jackspace/claudeskillz/cloudflare-mcp-server

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Builds and deploys remote Model Context Protocol (MCP) servers on Cloudflare Workers in TypeScript with @modelcontextprotocol/sdk: McpAgent class patterns for tools, resources, and prompts, all four authentication patterns (token validation, remote OAuth with DCR, OAuth proxy via workers-oauth-provider, and a full OAuth provider), GitHub/Google/Azure OAuth, Durable Objects for per-session state, WebSocket hibernation for cost savings, and dual SSE plus Streamable HTTP transports. Ships templates for basic servers, OAuth proxy, stateful Durable Object servers, and wrangler.jsonc configs, and prevents 15+ errors including McpAgent export mistakes, OAuth redirect URI mismatches, WebSocket state loss, Durable Objects binding errors, and CORS misconfiguration. Use when creating, authenticating, debugging, or deploying an MCP server on Cloudflare Workers.

Install

npx vskill@latest install jackspace/claudeskillz/cloudflare-mcp-server

SKILL.md

Cloudflare MCP Server Skill

Build and deploy Model Context Protocol (MCP) servers on Cloudflare Workers with TypeScript.


What is This Skill?

This skill teaches you to build remote MCP servers on Cloudflare - the ONLY platform with official remote MCP support as of 2025.

Use this skill when:

  • Building MCP servers with TypeScript (@modelcontextprotocol/sdk)
  • Deploying remote MCP servers to Cloudflare Workers
  • Implementing OAuth authentication (GitHub, Google, Azure, custom)
  • Creating stateful MCP servers with Durable Objects
  • Optimizing costs with WebSocket hibernation
  • Supporting both SSE and Streamable HTTP transports
  • Avoiding 15+ common MCP + Cloudflare errors

You'll learn:

  1. McpAgent class patterns and tool definitions
  2. OAuth integration (all 4 auth patterns)
  3. Durable Objects for per-session state
  4. WebSocket hibernation API
  5. Dual transport configuration (SSE + HTTP)
  6. Complete deployment workflow

Quick Start (5 Minutes)

Option 1: Deploy from Template
bash
# Create new MCP server from Cloudflare template
npm create cloudflare@latest -- my-mcp-server \
--template=cloudflare/ai/demos/remote-mcp-authless
cd my-mcp-server
npm install
npm run dev

Your MCP server is now running at http://localhost:8788/sse

Option 2: Copy Templates from This Skill
bash
# Copy basic MCP server template
cp ~/.claude/skills/cloudflare-mcp-server/templates/basic-mcp-server.ts src/index.ts
cp ~/.claude/skills/cloudflare-mcp-server/templates/wrangler-basic.jsonc wrangler.jsonc
cp ~/.claude/skills/cloudflare-mcp-server/templates/package.json package.json
# Install dependencies
npm install
# Start development server
npm run dev
Test with MCP Inspector
bash
# In a new terminal, start MCP Inspector
npx @modelcontextprotocol/inspector@latest
# Open http://localhost:5173
# Enter your MCP server URL: http://localhost:8788/sse
# Click "Connect" and test tools
Deploy to Cloudflare
bash
# Deploy to production
npx wrangler deploy
# Your MCP server is now live at:
# https://my-mcp-server.your-account.workers.dev/sse

Core Concepts

1. McpAgent Class

The McpAgent base class from Cloudflare's Agents SDK provides:

  • Automatic Durable Objects integration
  • Built-in state management with SQL database
  • Tool, resource, and prompt registration
  • Transport handling (SSE + HTTP)

Basic pattern:

typescript
import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
export class MyMCP extends McpAgent<Env> {
server = new McpServer({
name: "My MCP Server",
version: "1.0.0"
});
async init() {
// Register tools here
this.server.tool(
"tool_name",
"Tool description",
{ param: z.string() },
async ({ param }) => ({
content: [{ type: "text", text: "Result" }]
})
);
}
}
2. Tool Definitions

Tools are functions that MCP clients can invoke. Use Zod for parameter validation.

Pattern:

typescript
this.server.tool(
"tool_name", // Tool identifier
"Tool description", // What it does (for LLM)
{ // Parameters (Zod schema)
param1: z.string().describe("Parameter description"),
param2: z.number().optional()
},
async ({ param1, param2 }) => { // Handler
// Your logic here
return {
content: [{ type: "text", text: "Result" }]
};
}
);

Best practices:

  • Detailed descriptions: Help LLMs understand tool purpose
  • Parameter descriptions: Explain expected values and constraints
  • Error handling: Return { isError: true } for failures
  • Few, focused tools: Better than many granular ones
3. Transport Methods

MCP supports two transports:

SSE (Server-Sent Events) - Legacy, widely supported:

typescript
MyMCP.serveSSE("/sse").fetch(request, env, ctx)

Streamable HTTP - 2025 standard, more efficient:

typescript
MyMCP.serve("/mcp").fetch(request, env, ctx)

Support both for maximum compatibility:

typescript
export default {
fetch(request: Request, env: Env, ctx: ExecutionContext) {
const { pathname } = new URL(request.url);
if (pathname.startsWith("/sse")) {
return MyMCP.serveSSE("/sse").fetch(request, env, ctx);
}
if (pathname.startsWith("/mcp")) {
return MyMCP.serve("/mcp").fetch(request, env, ctx);
}
return new Response("Not Found", { status: 404 });
}
};

Authentication Patterns

Cloudflare MCP servers support 4 authentication patterns:

Pattern 1: No Authentication

Use case: Internal tools, development, public APIs

Template: templates/basic-mcp-server.ts

Setup: None required

Security: ⚠️ Anyone can access your MCP server


Pattern 2: Token Validation (JWTVerifier)

Use case: Pre-authenticated clients, custom auth systems

How it works: Client sends Bearer token, server validates

Template: Create custom JWTVerifier middleware

Setup:

typescript
import { JWTVerifier } from "agents/mcp";
const verifier = new JWTVerifier({
secret: env.JWT_SECRET,
issuer: "your-auth-server"
});
// Validate token before serving MCP requests

Security: ✅ Secure if tokens are properly managed


Pattern 3: OAuth Proxy (workers-oauth-provider)

Use case: GitHub, Google, Azure OAuth integration

How it works: Cloudflare Worker proxies OAuth to third-party provider

Template: templates/mcp-oauth-proxy.ts

Setup:

typescript
import { OAuthProvider, GitHubHandler } from "@cloudflare/workers-oauth-provider";
export default new OAuthProvider({
authorizeEndpoint: "/authorize",
tokenEndpoint: "/token",
clientRegistrationEndpoint: "/register",
defaultHandler: new GitHubHandler({
clientId: (env) => env.GITHUB_CLIENT_ID,
clientSecret: (env) => env.GITHUB_CLIENT_SECRET,
scopes: ["repo", "user:email"],
context: async (accessToken) => {
// Fetch user info from GitHub
const octokit = new Octokit({ auth: accessToken });
const { data: user } = await octokit.rest.users.getAuthenticated();
return {
login: user.login,
email: user.email,
accessToken
};
}
}),
kv: (env) => env.OAUTH_KV,
apiHandlers: {
"/sse": MyMCP.serveSSE("/sse"),
"/mcp": MyMCP.serve("/mcp")
},
allowConsentScreen: true,
allowDynamicClientRegistration: true
});

Required bindings:

jsonc
{
"kv_namespaces": [
{ "binding": "OAUTH_KV", "id": "YOUR_KV_ID" }
]
}

Security: ✅✅ Secure, production-ready


Pattern 4: Remote OAuth with DCR

Use case: Full OAuth provider, custom consent screens

How it works: Your Worker is the OAuth provider

Template: See Cloudflare's remote-mcp-authkit demo

Setup: Complex, requires full OAuth 2.1 implementation

Security: ✅✅✅ Most secure, full control


Stateful MCP Servers with Durable Objects

Use Durable Objects when your MCP server needs:

  • Per-session persistent state
  • Conversation history
  • Game state (chess, tic-tac-toe)
  • Cached API responses
  • User preferences
Storage API Pattern

Template: templates/mcp-stateful-do.ts

Store values:

typescript
await this.state.storage.put("key", "value");
await this.state.storage.put("user_prefs", { theme: "dark" });

Retrieve values:

typescript
const value = await this.state.storage.get<string>("key");
const prefs = await this.state.storage.get<object>("user_prefs");

List keys:

typescript
const allKeys = await this.state.storage.list();

Delete keys:

typescript
await this.state.storage.delete("key");
Configuration

wrangler.jsonc:

jsonc
{
"durable_objects": {
"bindings": [
{
"name": "MY_MCP",
"class_name": "MyMCP",
"script_name": "my-mcp-server"
}
]
},
"migrations": [
{ "tag": "v1", "new_classes": ["MyMCP"] }
]
}

IMPORTANT: Migrations are required on first deployment!


WebSocket Hibernation for Cost Optimization

Problem: Long-lived WebSocket connections cost CPU time

Solution: WebSocket Hibernation API suspends connections when idle

Pattern

Serialize metadata (preserves data during hibernation):

typescript
webSocket.serializeAttachment({
userId: "123",
sessionId: "abc",
connectedAt: Date.now()
});

Retrieve on wake:

typescript
const metadata = webSocket.deserializeAttachment();
console.log(metadata.userId); // "123"

Storage for persistent state:

typescript
// ❌ DON'T: In-memory state lost on hibernation
this.userId = "123";
// ✅ DO: Use storage API
await this.state.storage.put("userId", "123");
Cost Savings

Without hibernation:

  • 1000 concurrent WebSockets × 10ms CPU/sec = 10 CPU-sec/sec
  • Cost: ~$0.50/day

With hibernation:

  • CPU only on messages (99% idle time suspended)
  • Cost: ~$0.01/day (50x reduction!)

Worker & Durable Objects Basics

Self-contained section for standalone use

Worker Export Pattern

Workers must export a `fetch` handler:

typescript
export default {
fetch(request: Request, env: Env, ctx: ExecutionContext): Response | Promise<Response> {
// Handle request
return new Response("Hello");
}
};
Durable Objects Class Structure

DOs extend McpAgent (for MCP servers):

typescript
export class MyMCP extends McpAgent<Env> {
constructor(state: DurableObjectState, env: Env) {
super(state, env);
}
// Your methods here
}
Bindings Configuration

Environment bindings give Workers access to resources:

jsonc
{
"kv_namespaces": [{ "binding": "MY_KV", "id": "..." }],
"durable_objects": {
"bindings": [{ "name": "MY_DO", "class_name": "MyDO" }]
},
"r2_buckets": [{ "binding": "MY_BUCKET", "bucket_name": "..." }]
}

Access in code:

typescript
env.MY_KV.get("key");
env.MY_DO.idFromName("session-123").getStub(env);
env.MY_BUCKET.get("file.txt");

Deployment & Testing

Local Development
bash
# Start dev server (uses Miniflare for local DOs)
npm run dev
# Start dev server with remote Durable Objects (more accurate)
npx wrangler dev --remote

Access at: http://localhost:8788/sse

Test with MCP Inspector
bash
npx @modelcontextprotocol/inspector@latest
  1. Open http://localhost:5173
  2. Enter MCP server URL
  3. Click "Connect"
  4. Use "List Tools" to see available tools
  5. Test tool calls with parameters
Deploy to Cloudflare
bash
# First time: Login
npx wrangler login
# Deploy
npx wrangler deploy
# Check deployment
npx wrangler tail

Your server is live at:

https://my-mcp-server.YOUR_ACCOUNT.workers.dev/sse
Connect Claude Desktop

~/.config/claude/claude_desktop_config.json (Linux/Mac):

json
{
"mcpServers": {
"my-mcp": {
"url": "https://my-mcp-server.your-account.workers.dev/sse"
}
}
}

%APPDATA%/Claude/claude_desktop_config.json (Windows)

With OAuth:

json
{
"mcpServers": {
"my-mcp": {
"url": "https://my-mcp-oauth.your-account.workers.dev/sse",
"auth": {
"type": "oauth",
"authorizationUrl": "https://my-mcp-oauth.your-account.workers.dev/authorize",
"tokenUrl": "https://my-mcp-oauth.your-account.workers.dev/token"
}
}
}
}

Restart Claude Desktop after config changes.


Common Patterns

API Proxy MCP Server

Use case: Wrap external API with MCP tools

Pattern:

typescript
this.server.tool(
"search_wikipedia",
"Search Wikipedia for a topic",
{ query: z.string() },
async ({ query }) => {
const response = await fetch(
`https://en.wikipedia.org/api/rest_v1/page/summary/${encodeURIComponent(query)}`
);
const data = await response.json();

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
10
Repository forks
4
7-day trend score
12

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 24 Mar 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/jackspace/claudeskillz/cloudflare-mcp-server/badge)](https://verified-skill.com/skills/jackspace/claudeskillz/cloudflare-mcp-server)

Something wrong with this skill or its page? Tell us.