Skip to content

Deploy to Cloudflare Workers

Host an MCP server on Cloudflare Workers. Generate a Worker from OpenAPI, set secrets with wrangler and deploy to your own account.

By Updated

The cloudflare-worker transport generates a complete Workers project that serves your MCP server over Streamable HTTP at /mcp. You deploy it to your own Cloudflare account with Wrangler.

1. Generate#

bash
npx openapi-mcp-generator@5 --input ./openapi.json --output ./my-mcp --transport=cloudflare-worker --inbound-auth bearer
cd my-mcp
npm install

--inbound-auth bearer makes the Worker require Authorization: Bearer <token> on /mcp. Leave it out only if every tool is safe to expose to anyone.

If your spec's servers URL is relative (for example /api/v3), pass an absolute one. The Workers runtime needs an absolute upstream URL:

bash
npx openapi-mcp-generator@5 --input ./openapi.json --output ./my-mcp --transport=cloudflare-worker --inbound-auth bearer --base-url https://api.example.com/v3

2. Run locally#

bash
cp .dev.vars.example .dev.vars   # fill in local secrets
npm run dev                      # serves http://localhost:8787/mcp

Open http://localhost:8787/ for the browser playground, or test with the MCP Inspector or, from Claude Desktop, mcp-remote.

3. Set secrets#

bash
npx wrangler secret put <SCHEME>_API_KEY   # names are listed in .dev.vars.example

Secrets are read from the Worker's env binding and are never committed. Non-secret settings such as API_BASE_URL go under vars in wrangler.jsonc. If a tool needs a secret that is not set, it returns an error naming it instead of calling your API. See Authentication.

4. Set the inbound token#

With --inbound-auth bearer, generate a random token and store it as a secret:

bash
openssl rand -hex 32
npx wrangler secret put MCP_AUTH_TOKEN
  • Every request to /mcp must send Authorization: Bearer <token>; others get 401 before any tool runs.
  • With no token configured the Worker fails closed with 503.
  • To rotate without downtime, set MCP_AUTH_TOKENS to new-token,old-token, then remove the old one.

Clients that accept custom headers (Claude Code, Cursor, VS Code, MCP Inspector, mcp-remote) send the token directly. Claude.ai and ChatGPT connectors use OAuth or no auth; put the Worker behind an OAuth-capable gateway such as Cloudflare Access for SaaS or @cloudflare/workers-oauth-provider for those.

5. Deploy#

bash
npx wrangler deploy

Wrangler signs in to your Cloudflare account and prints the Worker URL. Your MCP endpoint is that URL plus /mcp, for example https://my-mcp.<your-subdomain>.workers.dev/mcp.

Test it in the browser: open https://mcp.pidata.tech/playground/?url=https://<your-worker>.workers.dev/mcp and paste your MCP_AUTH_TOKEN. The token stays in your browser tab and is only sent to your server.

Good to know#

  • The Worker is stateless and runs on the free Workers tier with no Durable Objects or KV. GET and DELETE on /mcp answer 405.
  • /mcp answers CORS (Access-Control-Allow-Origin: *), so browser-based MCP clients can reach it. Access is still controlled by the Authorization header.
  • The Worker serves the browser playground at /. Set the MCP_PLAYGROUND var to "off" in wrangler.jsonc to stop serving it.
  • --header-passthrough forwards the listed headers to the upstream API, overriding stored secrets for the same header.
  • --custom-auth, --port, --insecure, --generate-lib and --oauth-creds-in-body are ignored for this target.
  • The generated .gitignore excludes .dev.vars, node_modules/, .wrangler/ and dist/.

Prefer not to run it yourself? MCP Cloud is planned to host generated servers in isolated Workers. It is in private beta and not live yet.