| name | mcp-cloudflare-builder |
| description | Builds production-ready remote MCP servers on Cloudflare Workers with typed tools, OAuth authentication, and Wrangler deployment. Use when: "build MCP server on Cloudflare", "remote MCP", "deploy MCP to Workers", "MCP OAuth authentication", "expose tools via MCP". |
MCP Cloudflare Builder
Scaffolds and deploys production-ready Model Context Protocol servers on Cloudflare Workers.
Philosophy
Most MCP servers start as stdio processes tied to a single machine. Remote MCP — hosted on Cloudflare Workers — changes the unit of deployment: a tool server becomes a durable, network-accessible endpoint that any authorized client can reach over HTTPS. This matters because it decouples tooling from the machines running agents, enables OAuth-protected sharing across teams, and makes the server's uptime and auth someone else's operational concern (Cloudflare's).
This skill exists because the gap between "I have a tool idea" and "the tool is deployed and connected" is all infrastructure. The scaffold here eliminates that gap.
Description
Creates remote MCP servers using the McpAgent Durable Object pattern on Cloudflare Workers. Covers tool definition with Zod validation, public vs. OAuth-protected modes, local testing with MCP Inspector, Wrangler deployment, and client connection. Distinct from mcp-builder (which covers general MCP server concepts) and mcp-server-builder (which scaffolds from OpenAPI specs) — this skill is Cloudflare-specific and deployment-complete.
When to Use
- User wants a remote (not stdio) MCP server
- User needs to expose tools to Claude Desktop or other MCP clients over HTTPS
- User wants MCP authentication via OAuth (GitHub, Google, Auth0, etc.)
- User is deploying on Cloudflare Workers specifically
Workflow
Step 1: Scaffold the Project
Public server (no auth):
npm create cloudflare@latest -- my-mcp-server \
--template=cloudflare/ai/demos/remote-mcp-authless
cd my-mcp-server && npm start
Server runs at http://localhost:8788/mcp.
OAuth-protected server:
npm create cloudflare@latest -- my-mcp-server \
--template=cloudflare/ai/demos/remote-mcp-github-oauth
cd my-mcp-server
Step 2: Define Tools
Tools are functions MCP clients can call. Define them in McpAgent.init():
import { McpAgent } from "agents/mcp";
import { z } from "zod";
export class MyMCP extends McpAgent {
server = new Server({ name: "my-mcp", 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) }],
})
);
this.server.tool(
"get_weather",
{ city: z.string() },
async ({ city }) => {
const response = await fetch(`https://api.weather.com/${city}`);
const data = await response.json();
return { content: [{ : , : .(data) }] };
}
);
}
}
Step 3: Configure Entry Point
import { MyMCP } from "./mcp";
export default {
fetch(request: Request, env: Env, ctx: ExecutionContext) {
const url = new URL(request.url);
if (url.pathname === "/mcp") {
return MyMCP.serveSSE("/mcp").fetch(request, env, ctx);
}
return new Response("MCP Server", { status: 200 });
},
};
export { MyMCP };
Step 4: Test Locally
npm start
npx @modelcontextprotocol/inspector@latest
Step 5: Deploy
npx wrangler deploy
Step 6: Connect Clients
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"my-server": {
"command": "npx",
"args": ["mcp-remote", "https://my-mcp.workers.dev/mcp"]
}
}
}
Restart Claude Desktop after updating config.
Tool Patterns
Return Types
return { content: [{ type: "text", text: "result" }] };
return {
content: [
{ type: "text", text: "Here's the data:" },
{ type: "text", text: JSON.stringify(data, null, 2) },
],
};
Input Validation with Zod
this.server.tool(
"create_user",
{
email: z.string().email(),
name: z.string().min(1).max(100),
role: z.enum(["admin", "user", "guest"]),
age: z.number().int().min(0).optional(),
},
async (params) => { }
);
Accessing Cloudflare Bindings
export class MyMCP extends McpAgent<Env> {
async init() {
this.server.tool("query_db", { sql: z.string() }, async ({ sql }) => {
const result = await this.env.DB.prepare(sql).all();
return { content: [{ type: "text", text: JSON.stringify(result) }] };
});
}
}
Wrangler Configuration
name = "my-mcp-server"
main = "src/index.ts"
compatibility_date = "2024-12-01"
[durable_objects]
bindings = [{ name = "MCP", class_name = "MyMCP" }]
[[migrations]]
tag = "v1"
new_classes = ["MyMCP"]
[[d1_databases]]
binding = "DB"
database_name = "my-db"
database_id = "xxx"
OAuth Setup
Supported providers: GitHub, Google, Auth0, Stytch, WorkOS, any OAuth 2.0 provider.
Set secrets via Wrangler:
wrangler secret put GITHUB_CLIENT_ID
wrangler secret put GITHUB_CLIENT_SECRET
Callback URL must match OAuth app config exactly. For local dev: http://localhost:8788/callback.
Common Issues
| Issue | Cause | Fix |
|---|
| "Tool not found" | Name mismatch | Verify exact case; ensure init() registers before connections |
| Connection fails | Wrong path | Confirm endpoint is /mcp; check CORS for browser clients |
| OAuth redirect error | Callback URL mismatch | Match OAuth app config; check secrets are set |
Best Practices
- Zod-validate every input. Never trust raw tool parameters — use
.email(), .min(), .enum() constraints to catch malformed input before it reaches your business logic or external APIs.
- One tool, one intent. A tool that does two different things based on a flag is two tools. Split them — agents choose tools by reading descriptions, not by inspecting parameter combinations.
- Access Cloudflare bindings via
this.env, not global scope. D1, KV, and R2 are injected per-request; referencing them outside McpAgent loses the request context.
- Set secrets with
wrangler secret put, never in wrangler.toml. Committed secrets in toml are a deployment risk even in private repos.
- Match the OAuth callback URL exactly. A trailing slash difference between the OAuth app config and the Worker route causes silent redirect failures that are hard to diagnose.
- Test with MCP Inspector before deploying. Local iteration via
npm start + Inspector catches tool-registration errors before they reach production clients.
Quality Checklist
Before calling the deployment complete:
Related Skills
mcp-server-builder — spec-driven MCP scaffold from an OpenAPI contract (language-agnostic, not Cloudflare-specific)
skill-creation — for wrapping a built MCP server into a reusable agent skill
process-extraction — for capturing the deployment workflow as a repeatable runbook
Output
A Cloudflare Workers project directory containing:
src/index.ts — entry point with SSE routing
src/mcp.ts — McpAgent class with tool definitions
wrangler.toml — deployment configuration
package.json — dependencies including agents, zod, @modelcontextprotocol/sdk