How to host a remote MCP server with OAuth (2026)
Local STDIO servers are easy. A remote MCP server that Claude, Cursor and ChatGPT can install over the internet — without leaving it open to the world — is where the real work is. Here's the whole picture.
Updated May 2026
Local vs remote: why this is harder than it looks
A local MCP server talks to one client over STDIO on your machine — no network, no auth. The moment you want a server that lives at a URL and any MCP client can connect to, you inherit a full web-service problem: a public transport, TLS, identity, authorization, and isolation between callers. The MCP spec settled on Streamable HTTP as the remote transport (it replaced the older HTTP+SSE pairing), and on OAuth 2.1 as the auth model. Both are non-negotiable if you want the server installable from Claude Desktop or ChatGPT.
The OAuth 2.1 pieces you can't skip
MCP authorization is OAuth 2.1, and for remote servers it leans on a few RFCs that older OAuth tutorials don't cover:
- PKCE (RFC 7636) on every authorization-code exchange — mandatory in OAuth 2.1, no exceptions for "confidential" clients.
- Dynamic Client Registration (RFC 7591) — clients like Claude Desktop register themselves at runtime; you can't pre-provision a client_id for every user.
- Resource Indicators (RFC 8707) — the token has to be bound to the specific MCP server (the
resource), so a token minted for one server can't be replayed against another. - Protected-resource metadata — your server returns a
WWW-Authenticateheader pointing at the authorization server so clients can discover where to get a token.
Get any of these wrong and the symptom is the same: the client either can't complete the handshake, or it silently fails to discover your auth server. This is the single most common reason a "working" MCP server won't install from Claude.
Option A — roll your own on generic infra
You can deploy a remote MCP server to Cloudflare Workers (the most common production choice, edge-global), or to Render, Fly, or Cloud Run as a normal container. Cloudflare even ships an OAuth provider library for Workers-based MCP servers. This path gives you full control and is the right call if you have engineers and want to own the runtime.
The cost is everything around the code: standing up the authorization server (or wiring a third-party IdP correctly for the RFCs above), per-tenant secret storage, TLS, rate limiting, and keeping the transport spec-current as MCP evolves. Budget days, not hours, for the auth layer alone.
Option B — a platform that wraps it for you
If you already have a server, tools like MintMCP take a local STDIO server and expose it as a remote one with OAuth wrapping. If you don't have a server yet, that's where BuildMyMCPServer fits: you describe the tool in plain language, it generates the TypeScript MCP server, runs static checks, builds a container, and deploys it behind a full OAuth 2.1 authorization server — PKCE, DCR and Resource Indicators included — with copy-paste install snippets for each client.
A practical checklist before you ship
- Transport is Streamable HTTP, served over TLS at a stable public URL.
- Unauthenticated request returns 401 + a
WWW-Authenticatepointing at your AS. - Authorization code flow enforces PKCE (S256), exact redirect-URI match, single-use codes.
- Issued access tokens are audience-bound to the specific server (RFC 8707).
- Per-caller secrets are encrypted at rest and injected only at runtime, never logged.
- You've actually installed it from Claude Desktop end-to-end — not just curl'd it.
Whichever route you take, test the real install path in a real client early. See the platform comparison for which option fits your situation.
Skip the boilerplate — describe your tool, get a hosted MCP server.
BuildMyMCPServer generates the TypeScript server, wraps it in OAuth 2.1 and deploys it to a public Streamable HTTP URL for Claude, Cursor and ChatGPT. Free tier, source export, no lock-in.
Start building →