From cloudflare
Builds remote MCP (Model Context Protocol) servers on Cloudflare Workers with tools, OAuth authentication, and production deployment. Generates server code, configures auth providers, and deploys to Workers. Use when: user wants to "build MCP server", "create MCP tools", "remote MCP", "deploy MCP", add "OAuth to MCP", or mentions Model Context Protocol on Cloudflare. Also triggers on "MCP authentication" or "MCP deployment". Biases towards retrieval from Cloudflare docs over pre-trained knowledge.
How this skill is triggered — by the user, by Claude, or both
Slash command
/cloudflare:building-mcp-server-on-cloudflareThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Your knowledge of the MCP SDK and Cloudflare Workers integration may be outdated. **Prefer retrieval over pre-training** for any MCP server task.
Your knowledge of the MCP SDK and Cloudflare Workers integration may be outdated. Prefer retrieval over pre-training for any MCP server task.
| Source | How to retrieve | Use for |
|---|---|---|
| MCP docs | https://developers.cloudflare.com/agents/mcp/ | Server setup, auth, deployment |
| MCP spec | https://modelcontextprotocol.io/ | Protocol spec, tool/resource definitions |
| Workers docs | Search tool or https://developers.cloudflare.com/workers/ | Runtime APIs, bindings, config |
npm install -g wrangler)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
npm create cloudflare@latest -- my-mcp-server \
--template=cloudflare/ai/demos/remote-mcp-github-oauth
cd my-mcp-server
Requires OAuth app setup. See references/oauth-setup.md.
Tools are functions MCP clients can call. Define them using server.tool():
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() {
// Simple tool with parameters
this.server.tool(
"add",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }],
})
);
// Tool that calls external API
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: [{ type: "text", text: JSON.stringify(data) }],
};
}
);
}
}
Public server (src/index.ts):
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 };
Authenticated server — See references/oauth-setup.md.
# Start server
npm start
# In another terminal, test with MCP Inspector
npx @modelcontextprotocol/inspector@latest
# Open http://localhost:5173, enter http://localhost:8788/mcp
npx wrangler deploy
Server accessible at https://[worker-name].[account].workers.dev/mcp
Codex MCP client setup:
codex mcp add my-server -- npx mcp-remote https://my-mcp.workers.dev/mcp
Restart Codex after updating the MCP configuration.
// Text response
return { content: [{ type: "text", text: "result" }] };
// Multiple content items
return {
content: [
{ type: "text", text: "Here's the data:" },
{ type: "text", text: JSON.stringify(data, null, 2) },
],
};
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) => {
// params are fully typed and validated
}
);
export class MyMCP extends McpAgent<Env> {
async init() {
this.server.tool("query_db", { sql: z.string() }, async ({ sql }) => {
// Access D1 binding
const result = await this.env.DB.prepare(sql).all();
return { content: [{ type: "text", text: JSON.stringify(result) }] };
});
}
}
For OAuth-protected servers, see references/oauth-setup.md.
Supported providers:
Minimal wrangler.toml:
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"]
With bindings (D1, KV, etc.):
[[d1_databases]]
binding = "DB"
database_name = "my-db"
database_id = "xxx"
[[kv_namespaces]]
binding = "KV"
id = "xxx"
init() registers tools before connectionswrangler tail/mcpwrangler deployments listGITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET are sethttp://localhost:8788/callbacknpx claudepluginhub robinebers/converted-plugins --plugin cloudflareGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.