CloudCodeTree LogoCloudCodeTree
AI NewsTutorialsAbout
CloudCodeTree Logo
CloudCodeTree
  • AI News
  • Tutorials
  • About
← Back to AI News
From stdio to the Internet: Deploy a Stateless MCP Server on Cloudflare Workers in 3 Commands

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

AI
Tutorial
MCP
Agents

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 /mcp HTTPS 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