Put a FastMCP Server Behind HTTPS with Caddy on macOS

Every deployment article so far bound the server to 127.0.0.1 over plain HTTP. That is correct for local use and unusable for anything else: a client on another machine cannot reach loopback, and sending bearer tokens or OAuth codes over plain HTTP leaks them. The fix is a TLS reverse proxy. This article puts Caddy in front of a FastMCP server so it is reachable over HTTPS, with certificates Caddy obtains and renews on its own. ...

12 min

Add Per-Plan Rate Limiting to a FastMCP Server on macOS

Gate a FastMCP Server to Paying Customers sold tiered access: Basic and Pro plans. Selling tiers only matters if the tiers actually differ, and the most common difference is how much a customer may call. This article adds per-plan rate limiting to a FastMCP server: a middleware reads each caller’s plan from their verified token and enforces that plan’s request quota, keyed on the caller’s identity. A Basic customer gets a small quota, a Pro customer a larger one, and over-limit calls are rejected cleanly. ...

13 min

Verify Signed JWTs with JWKS in a FastMCP Server on macOS

Two earlier articles secured a FastMCP server two ways: Gate a FastMCP Server to Paying Customers verified opaque license keys you minted and stored yourself, and Add GitHub OAuth delegated login to GitHub. This one takes a third path that sits between them: you run your own token authority that issues asymmetrically signed JWTs, and the server verifies each token’s signature against a JWKS (JSON Web Key Set) it publishes. No per-request database lookup, no third-party login. The signature and claims are self-contained, and only the holder of the private key can mint a valid token. ...

16 min

Add GitHub OAuth to a FastMCP Server on macOS

In Gate a FastMCP Server to Paying Customers you minted your own license keys and verified them yourself. That works, but it means you own the hard parts: issuing credentials, storing them, revoking them. This tutorial takes the other approach: delegate authentication to a real identity provider, GitHub, using FastMCP’s GitHubProvider. Your server never sees a password; users log in with GitHub, and the MCP client handles the whole OAuth 2.0 dance (Dynamic Client Registration, the browser login, PKCE, token exchange). ...

15 min

Build a Stateful FastMCP Server on macOS with SQLite

The FastMCP tutorials so far returned pure, stateless results. Real tools usually need state that persists — a record that is still there after the process restarts. In this tutorial you will build a FastMCP task-manager server whose tools read and write a SQLite database, so tasks survive restarts, redeploys, and reboots. You will separate the persistence layer (db.py) from the MCP tools (server.py), expose a live-stats resource, cover it with pytest (including a test that proves data survives a restart), and deploy it as a launchd service. The stack is Mac-native: uv, make, and Python’s built-in sqlite3 — no database server to install. ...

14 min

Serve Media from a FastMCP Server on macOS — Inline or as Expiring Links

MCP tools usually return text. But a tool can also return media (an image, a document), and sometimes the right answer isn’t the bytes at all but a link to them. This tutorial builds a FastMCP server that does both, and lets you choose per request: Inline delivery — the tool returns the media object directly (a PNG image, an SVG image, a Markdown document). Best for small results aimed at the model. Link delivery — the tool stores the bytes in a bucket and returns a URL. The URL is either permanent or expiring after N minutes. Best for large media (video), anything you want to share by link, and anything a person has to see with their own eyes. That last clause is doing real work. Inline media reaches every MCP client, but whether a client draws it is a UI decision the protocol does not require, and most do not: of three clients measured in Serve an Updating Image as an MCP Resource on macOS — and Where You Can Actually See It, only the MCP Inspector renders an image content block. Serve the model inline; serve a person a link. ...

23 min

Package and Distribute a FastMCP Server as a uvx Tool on macOS

The friendliest way to ship a Python command-line tool today is to make it runnable with uvx, uv’s equivalent of pipx run. A user types uvx macmcp and uv fetches the package, builds an ephemeral environment, and runs it, with no clone, no virtualenv, and nothing left installed. That is a perfect distribution model for a FastMCP server: you publish once, and anyone can run your MCP server (or wire it into an MCP client config) with a single command. ...

10 min

Build and Deploy a FastMCP Server on macOS Without Writing Code — Let Claude Code Do It

Most tutorials hand you code to type. This one does the opposite: you will stand up a FastMCP server on your Mac in which you never write a line of application code. You describe behavior in plain English and Cucumber/Gherkin scenarios, and Claude Code (driven by subagents and slash commands you configure once) writes and maintains server.py until every scenario passes. Your entire job is to run make (or let CI run it). ...

20 min

Gate a FastMCP Server to Paying Customers on macOS

Building an MCP server is easy; making sure only the people who paid for it can call it is the part that turns a demo into a product. In this tutorial you will build a FastMCP server that authenticates every request against a license store: paying customers hold a license key, the server verifies it, and unknown or expired keys are rejected with 401 Unauthorized. Premium tools are further gated so that only the Pro plan can call them. ...

17 min

Connect to a FastMCP Server from macOS

In the companion article Create and Deploy a FastMCP Server on macOS you built a FastMCP server and deployed it as a launchd service listening on http://127.0.0.1:8000/mcp/. This tutorial builds the other half: a command-line MCP client that connects to that running server over HTTP, lists what it offers, and calls its tools. Because you are on a Mac, the client does one extra thing that a generic client does not: with --copy it drops a tool’s result straight onto the macOS clipboard via pbcopy, so the output of slugify is ready to paste into your editor. Everything is managed with uv and make. ...

11 min