Co-Pilot
Updated a month ago

building-mcp-server-on-cloudflare

Ccloudflare
0.1k
cloudflare/skills/building-mcp-server-on-cloudflare
82
Agent Score

💡 Summary

This skill builds and deploys Model Context Protocol servers on Cloudflare Workers with OAuth support.

🎯 Target Audience

Cloudflare developersBackend engineersAI tool developersDevOps professionalsTechnical project managers

🤖 AI Roast:Powerful, but the setup might scare off the impatient.

Security AnalysisMedium Risk

Risk: Medium. Review: shell/CLI command execution; outbound network access (SSRF, data egress); API keys/tokens handling and storage; filesystem read/write scope and path traversal; dependency pinning and supply-chain risk. Run with least privilege and audit before enabling in production.


name: building-mcp-server-on-cloudflare description: | 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".

Building MCP Servers on Cloudflare

Creates production-ready Model Context Protocol servers on Cloudflare Workers with tools, authentication, and deployment.

When to Use

  • User wants to build a remote MCP server
  • User needs to expose tools via MCP
  • User asks about MCP authentication or OAuth
  • User wants to deploy MCP to Cloudflare Workers

Prerequisites

  • Cloudflare account with Workers enabled
  • Node.js 18+ and npm/pnpm/yarn
  • Wrangler CLI (npm install -g wrangler)

Quick Start

Option 1: 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

Option 2: Authenticated Server (OAuth)

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.

Core Workflow

Step 1: Define Tools

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) }], }; } ); } }

Step 2: Configure Entry Point

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.

Step 3: Test Locally

# Start server npm start # In another terminal, test with MCP Inspector npx @modelcontextprotocol/inspector@latest # Open http://localhost:5173, enter http://localhost:8788/mcp

Step 4: Deploy

npx wrangler deploy

Server accessible at https://[worker-name].[account].workers.dev/mcp

Step 5: 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

// 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) }, ], };

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) => { // params are fully typed and validated } );

Accessing Environment/Bindings

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) }] }; }); } }

Authentication

For OAuth-protected servers, see references/oauth-setup.md.

Supported providers:

  • GitHub
  • Google
  • Auth0
  • Stytch
  • WorkOS
  • Any OAuth 2.0 compliant provider

Wrangler Configuration

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"

Common Issues

"Tool not found" in Client

  1. Verify tool name matches exactly (case-sensitive)
  2. Ensure init() registers tools before connections
  3. Check server logs: wrangler tail

Connection Fails

  1. Confirm endpoint path is /mcp
  2. Check CORS if browser-based client
  3. Verify Worker is deployed: wrangler deployments list

OAuth Redirect Errors

  1. Callback URL must match OAuth app config exactly
  2. Check GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET are set
  3. For local dev, use http://localhost:8788/callback

References

5-Dim Analysis
Clarity8/10
Novelty7/10
Utility9/10
Completeness9/10
Maintainability8/10
Pros & Cons

Pros

  • Supports OAuth authentication
  • Easy deployment on Cloudflare Workers
  • Flexible tool definition
  • Production-ready setup

Cons

  • Requires Cloudflare account
  • Dependency on external APIs
  • OAuth setup can be complex
  • Limited to Cloudflare ecosystem

Related Skills

durable-objects

A
toolCo-Pilot
82/ 100

“Powerful, but the setup might scare off the impatient.”

cloudflare-skill

B
toolCo-Pilot
76/ 100

“The installation script could pose risks if the source is compromised, potentially leading to unauthorized access or code execution. Ensure to verify the script's integrity before ”

cloudflare-docs

C
toolCo-Pilot
68/ 100

“Powerful, but the setup might scare off the impatient.”

Disclaimer: This content is sourced from GitHub open source projects for display and rating purposes only.

Copyright belongs to the original author cloudflare.