|
Add this skill
npx mdskills install cloudflare/building-mcp-server-on-cloudflareComprehensive guide to building and deploying production MCP servers on Cloudflare Workers with OAuth
1---2name: building-mcp-server-on-cloudflare3description: |4 Builds remote MCP (Model Context Protocol) servers on Cloudflare Workers5 with tools, OAuth authentication, and production deployment. Generates6 server code, configures auth providers, and deploys to Workers.78 Use when: user wants to "build MCP server", "create MCP tools", "remote9 MCP", "deploy MCP", add "OAuth to MCP", or mentions Model Context Protocol10 on Cloudflare. Also triggers on "MCP authentication" or "MCP deployment".11---1213# Building MCP Servers on Cloudflare1415Creates production-ready Model Context Protocol servers on Cloudflare Workers with tools, authentication, and deployment.1617## When to Use1819- User wants to build a remote MCP server20- User needs to expose tools via MCP21- User asks about MCP authentication or OAuth22- User wants to deploy MCP to Cloudflare Workers2324## Prerequisites2526- Cloudflare account with Workers enabled27- Node.js 18+ and npm/pnpm/yarn28- Wrangler CLI (`npm install -g wrangler`)2930## Quick Start3132### Option 1: Public Server (No Auth)3334```bash35npm create cloudflare@latest -- my-mcp-server \36 --template=cloudflare/ai/demos/remote-mcp-authless37cd my-mcp-server38npm start39```4041Server runs at `http://localhost:8788/mcp`4243### Option 2: Authenticated Server (OAuth)4445```bash46npm create cloudflare@latest -- my-mcp-server \47 --template=cloudflare/ai/demos/remote-mcp-github-oauth48cd my-mcp-server49```5051Requires OAuth app setup. See [references/oauth-setup.md](references/oauth-setup.md).5253## Core Workflow5455### Step 1: Define Tools5657Tools are functions MCP clients can call. Define them using `server.tool()`:5859```typescript60import { McpAgent } from "agents/mcp";61import { z } from "zod";6263export class MyMCP extends McpAgent {64 server = new Server({ name: "my-mcp", version: "1.0.0" });6566 async init() {67 // Simple tool with parameters68 this.server.tool(69 "add",70 { a: z.number(), b: z.number() },71 async ({ a, b }) => ({72 content: [{ type: "text", text: String(a + b) }],73 })74 );7576 // Tool that calls external API77 this.server.tool(78 "get_weather",79 { city: z.string() },80 async ({ city }) => {81 const response = await fetch(`https://api.weather.com/${city}`);82 const data = await response.json();83 return {84 content: [{ type: "text", text: JSON.stringify(data) }],85 };86 }87 );88 }89}90```9192### Step 2: Configure Entry Point9394**Public server** (`src/index.ts`):9596```typescript97import { MyMCP } from "./mcp";9899export default {100 fetch(request: Request, env: Env, ctx: ExecutionContext) {101 const url = new URL(request.url);102 if (url.pathname === "/mcp") {103 return MyMCP.serveSSE("/mcp").fetch(request, env, ctx);104 }105 return new Response("MCP Server", { status: 200 });106 },107};108109export { MyMCP };110```111112**Authenticated server** — See [references/oauth-setup.md](references/oauth-setup.md).113114### Step 3: Test Locally115116```bash117# Start server118npm start119120# In another terminal, test with MCP Inspector121npx @modelcontextprotocol/inspector@latest122# Open http://localhost:5173, enter http://localhost:8788/mcp123```124125### Step 4: Deploy126127```bash128npx wrangler deploy129```130131Server accessible at `https://[worker-name].[account].workers.dev/mcp`132133### Step 5: Connect Clients134135**Claude Desktop** (`claude_desktop_config.json`):136137```json138{139 "mcpServers": {140 "my-server": {141 "command": "npx",142 "args": ["mcp-remote", "https://my-mcp.workers.dev/mcp"]143 }144 }145}146```147148Restart Claude Desktop after updating config.149150## Tool Patterns151152### Return Types153154```typescript155// Text response156return { content: [{ type: "text", text: "result" }] };157158// Multiple content items159return {160 content: [161 { type: "text", text: "Here's the data:" },162 { type: "text", text: JSON.stringify(data, null, 2) },163 ],164};165```166167### Input Validation with Zod168169```typescript170this.server.tool(171 "create_user",172 {173 email: z.string().email(),174 name: z.string().min(1).max(100),175 role: z.enum(["admin", "user", "guest"]),176 age: z.number().int().min(0).optional(),177 },178 async (params) => {179 // params are fully typed and validated180 }181);182```183184### Accessing Environment/Bindings185186```typescript187export class MyMCP extends McpAgent<Env> {188 async init() {189 this.server.tool("query_db", { sql: z.string() }, async ({ sql }) => {190 // Access D1 binding191 const result = await this.env.DB.prepare(sql).all();192 return { content: [{ type: "text", text: JSON.stringify(result) }] };193 });194 }195}196```197198## Authentication199200For OAuth-protected servers, see [references/oauth-setup.md](references/oauth-setup.md).201202Supported providers:203- GitHub204- Google205- Auth0206- Stytch207- WorkOS208- Any OAuth 2.0 compliant provider209210## Wrangler Configuration211212Minimal `wrangler.toml`:213214```toml215name = "my-mcp-server"216main = "src/index.ts"217compatibility_date = "2024-12-01"218219[durable_objects]220bindings = [{ name = "MCP", class_name = "MyMCP" }]221222[[migrations]]223tag = "v1"224new_classes = ["MyMCP"]225```226227With bindings (D1, KV, etc.):228229```toml230[[d1_databases]]231binding = "DB"232database_name = "my-db"233database_id = "xxx"234235[[kv_namespaces]]236binding = "KV"237id = "xxx"238```239240## Common Issues241242### "Tool not found" in Client2432441. Verify tool name matches exactly (case-sensitive)2452. Ensure `init()` registers tools before connections2463. Check server logs: `wrangler tail`247248### Connection Fails2492501. Confirm endpoint path is `/mcp`2512. Check CORS if browser-based client2523. Verify Worker is deployed: `wrangler deployments list`253254### OAuth Redirect Errors2552561. Callback URL must match OAuth app config exactly2572. Check `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET` are set2583. For local dev, use `http://localhost:8788/callback`259260## References261262- [references/examples.md](references/examples.md) — Official templates and production examples263- [references/oauth-setup.md](references/oauth-setup.md) — OAuth provider configuration264- [references/tool-patterns.md](references/tool-patterns.md) — Advanced tool examples265- [references/troubleshooting.md](references/troubleshooting.md) — Error codes and fixes266
Full transparency — inspect the skill content before installing.