
From stdio to the Internet: Deploy a Stateless MCP Server on Cloudflare Workers in 3 Commands
Chris Harper
3 min read
Jul 26, 2026 · 04:03 UTC
TL;DR: Three commands move your MCP server from localhost to a public HTTPS endpoint on Cloudflare Workers using Streamable HTTP — the transport that replaces SSE as the July 28 spec locks in.
What you'll be able to do after this:
- Deploy an MCP server with a live public
/mcpHTTPS endpoint in under 5 minutes, no infrastructure provisioned - Understand why Streamable HTTP (not stdio, not SSE) is the transport for multi-client, production MCP
- Optionally add Cloudflare Access auth so only your team or specific services can connect
Why Cloudflare Workers?
stdio MCP servers run in the same process as the client — Claude Desktop, a local script. That works for personal tools but breaks the moment you want to share a server across teams, connect from CI, or expose a tool to multiple agents simultaneously. The July 28 MCP spec update finalizes Streamable HTTP as the only supported remote transport; SSE is sunset.
Cloudflare Workers is the fastest path to a compliant remote MCP endpoint: globally distributed edge runtime, serverless, free tier available, and Anthropic has published a first-class template for it.
The three commands
Step 1 — Scaffold from the official template:
npm create cloudflare@latest -- my-mcp-server \
--template=cloudflare/ai/demos/remote-mcp-authless
cd my-mcp-server
This creates a TypeScript Workers project with McpAgent pre-wired. The generated src/index.ts is small — about 30 lines:
import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
export class MyMCP extends McpAgent {
server = new McpServer({ name: "demo", version: "1.0.0" });
async init() {
this.server.tool(
"add",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }],
})
);
}
}
export default { fetch: MyMCP.serve("/mcp").fetch };
Step 2 — Add your tools. Every tool is a this.server.tool() call inside init(). The McpAgent class handles session state via Durable Objects, transport negotiation (SSE and Streamable HTTP), and the /mcp route.
Step 3 — Deploy:
npx wrangler login # one-time auth
npm run deploy
# Deployed to: my-mcp-server.your-account.workers.dev/mcp
Your MCP endpoint is live. The /mcp path accepts both POST (Streamable HTTP) and the legacy GET (SSE) requests — clients choose automatically.
Test it without a client
npx @modelcontextprotocol/inspector@latest \
https://my-mcp-server.your-account.workers.dev/mcp
The MCP inspector runs in your browser and lets you invoke tools interactively.
Connect it to Claude
In Claude Desktop's claude_desktop_config.json:
{
"mcpServers": {
"my-server": {
"url": "https://my-mcp-server.your-account.workers.dev/mcp"
}
}
}
Optional: lock it down with Cloudflare Access
Follow the Cloudflare One → Secure MCP servers guide to put a zero-trust auth layer in front. Users authenticate with your IdP; unauthenticated requests get a 403 before reaching the Worker. This is the pattern for team-shared or production MCP servers.
Sources: Cloudflare: Build a Remote MCP server · MCP transport docs · Secure MCP servers with Cloudflare One