Deploy MCP Server to Cloudflare Workers: MCP at the Edge
Deploy MCP Server to Cloudflare Workers: stdio to Streamable HTTP conversion, Edge Runtime limits, KV persistence, wrangler config, and a production checklist.
How to
Evaluate stdio vs Streamable HTTP
Local-only → keep stdio; cross-network → switch to Streamable HTTP; deploying to Workers mandates Streamable HTTP.
Adapt the MCP Server entry point
Use @modelcontextprotocol/sdk's StreamableHTTPServerTransport instead of StdioServerTransport; entry point goes from process.stdin to a fetch handler.
Adapt to Edge Runtime
Code uses only fetch / crypto / streams / KV bindings; drop fs / child_process usage; long tasks via ctx.waitUntil.
Configure wrangler.jsonc
Set name / main / compatibility_date / compatibility_flags; configure kv_namespaces (D1 / R2 bindings); secrets via wrangler secret (separate).
Local wrangler dev
wrangler dev; MCP Host points to http://localhost:8787/sse; test tool list and invocations; hot-reload on code changes.
Deploy + monitor
wrangler deploy; Cloudflare dashboard for request logs + CPU usage; set alerts.
Cloudflare Workers is the ideal edge platform to deploy MCP Server on - low latency, pay-per-request, fast cold start. This article walks the full path.
1. Why Workers
Common options for deploying MCP Server:
| Platform | Latency | Cold start | Fit |
|---|---|---|---|
| Cloudflare Workers | Very low (200+ PoP) | < 50ms | Edge MCP, IO-bound |
| Vercel Functions | Medium (CDN) | Medium | Next.js stack |
| AWS Lambda | Medium | Medium | Complex backend |
| Self-hosted VPS | Depends | Depends | Full control |
Workers' edge: global latency + pay-per-request + KV/D1/R2 adjacent.
2. stdio vs Streamable HTTP
MCP has two transports:
- stdio: local process (Host spawns the server binary, communicates via stdin/stdout)
- Streamable HTTP: HTTP + SSE (Server exposes HTTP endpoint, Host calls via POST + GET-SSE)
Workers can only run Streamable HTTP - Workers is edge runtime, no stdin/stdout processes.
To convert, use @modelcontextprotocol/sdk's StreamableHTTPServerTransport instead of StdioServerTransport:
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined, // stateless
});
server.connect(transport);
// Workers fetch handler
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
return transport.handleRequest(request);
}
};
3. Edge Runtime limits
Workers Edge Runtime is not Node.js - the following are unavailable:
fs(filesystem)child_process(subprocess)setImmediate/process.nextTick- any Node.js built-in modules (except Web standards: fetch / crypto / streams / URL)
Code must:
- use only Web standard APIs (
fetch,crypto.subtle,TransformStream) - use Workers KV / D1 / R2 instead of local storage
- long-running tasks via
ctx.waitUntil(async) - cannot require Node packages; use esbuild-compatible packages (most modern SDKs work)
4. CPU time limits
| Plan | CPU time / request |
|---|---|
| Free | 5ms (wall time 10s) |
| Bundled | 5-50ms (per plan) |
| Unbound | 30s |
MCP tool calls are usually low CPU intensity (IO-bound) - 5ms suffices in most cases; complex compute (scraping + parsing) goes to Unbound.
5. KV persistence
Workers KV (edge key-value store) fits MCP scenarios:
// Read
const counter = await env.MCP_KV.get("rate_limit:user_123", { type: "json" });
// Write
await env.MCP_KV.put("rate_limit:user_123", JSON.stringify({ count: counter + 1 }));
KV properties:
- Eventual consistency (global convergence < 60s)
- Per-key value ≤ 25MB
- Suits rate limits / caches / prefs
Not for strong consistency (use D1 SQLite for that).
6. wrangler.jsonc config
{
"name": "my-mcp-server",
"main": "src/index.ts",
"compatibility_date": "2026-08-01",
"compatibility_flags": ["nodejs_compat"], // compatibility for some Node.js APIs
"vars": {
"LOG_LEVEL": "info"
},
"kv_namespaces": [
{ "binding": "MCP_KV", "id": "xxx" }
],
"secrets": [
"GITHUB_CLIENT_SECRET", // set via wrangler secret put
"API_KEY"
]
}
secrets don't go into git - use wrangler secret put GITHUB_CLIENT_SECRET to configure.
7. Deploy + monitor
# Local dev
wrangler dev
# Deploy
wrangler deploy
# Tail logs
wrangler tail
# Set secrets
wrangler secret put GITHUB_CLIENT_SECRET
Cloudflare dashboard provides:
- Request / error rate real-time monitoring
- CPU time usage (spot performance issues)
- KV read/write volume
Set alerts: 5xx rate > 5% sustained 5 minutes → trigger.
8. Practical gotchas
nodejs_compatflag: some Node.js packages (especially zod / pnpm packages) need this flag to run- Cold start: first request 50-100ms warm-up; the user's first MCP call is a bit slower
- Worker size limit: 1MB compressed; with SDK it's typically 200-400KB
- CORS: MCP Host (ChatGPT web) calls your Worker from a different origin; configure CORS to allow
*or ChatGPT's domain
9. What's Next
- Build Your Own MCP Server: From Zero to Published - full stdio MCP path
- Model Context Protocol: How MCP Works and How to Build on It - protocol deep dive
- OpenAI API Error Handling and Retry - production stability
Update log
- 2026-08-08: Initial publish
Key points
- Workers is the ideal edge platform for MCP - but only runs Streamable HTTP MCP, stdio needs a local process
- Edge Runtime has no Node.js APIs (fs / child_process unavailable) - use only fetch / crypto / streams
- CPU time is 5ms (free plan) / 30s (unbound plan) - long tasks must stream or offload
- KV for persistence (rate-limit state, user prefs) - eventual consistency but sufficient
- wrangler.jsonc configures secrets (OAuth client secret, API keys) + bindings (KV, D1, R2)
- Local dev with wrangler dev simulates Edge Runtime; deploy with wrangler deploy; CI with wrangler deploy --dry-run
Frequently asked questions
Official references
Related articles
Codex CLI MCP Servers: The Full mcp_servers Config Field Guide
Codex CLI wires MCP servers via [mcp_servers] in config.toml: command/args/env for stdio, url/bearer_token/http_headers for remote, plus timeouts, tool filters and OAuth.
Read articleMCP Apps Explained: Interactive UIs Rendered Inside Chat, Standardized as SEP-1865
MCP Apps (SEP-1865, Final): a server declares a ui:// resource, and hosts like Claude or VS Code Copilot render the interactive HTML inside the conversation. Mechanism, security model, SDK code, and host support.
Read articleThe Model Hardware Standard, explained: how MHS lets AI agents safely operate physical devices
A close reading of Anthropic's August 27 research preview of the Model Hardware Standard: standardized drivers, three control mechanisms including MCP, results from six research partners, and eight vendors building support.
Read articleSubscribe to GPTMap Weekly
One email every Monday: curated OpenAI updates, deep dives, and best practices. No ads, unsubscribe anytime.
Submitting opens Buttondown in a new tab to confirm your subscription.