返回博客2026年3月27日2 分钟阅读

用 Cloudflare Workers 部署 MCP 服务器

摘要

MCP 服务器不一定要跑在本地。这篇手把手教你用 Cloudflare Workers 部署一个远程 MCP 服务器,支持 SSE 传输,全球边缘节点加速。

MCP 服务器跑在本地有个问题——换台电脑就没了。部署到 Cloudflare Workers 上,随时随地都能用。

MCP(Model Context Protocol)是 Anthropic 推出的开放协议,让 AI 模型能连接外部工具和数据源。大多数教程教的都是本地 MCP 服务器(通过 stdio 通信),但在实际使用中,远程 MCP 服务器才是更实用的方案。

Cloudflare Workers 是部署远程 MCP 服务器的理想选择:免费额度大、全球边缘节点、冷启动快、原生支持 SSE。这篇从零开始,带你部署一个能用的 MCP 服务器。

一、为什么选 Cloudflare Workers

先说为什么不选其他方案:

方案问题
本地 stdio只能在本机用,不能共享
传统 VPS要自己管服务器,成本高
AWS Lambda冷启动慢,SSE 支持不好
Vercel Functions有执行时间限制,SSE 有坑

Cloudflare Workers 的优势:

  • 冷启动 < 5ms:边缘计算,不存在冷启动问题
  • 免费额度:每天 10 万次请求,小项目完全够用
  • 原生 SSE 支持:MCP 的 Streamable HTTP 传输需要 SSE,Workers 原生支持
  • 全球分布:200+ 数据中心,延迟低
  • Durable Objects:可以维护有状态的连接(MCP session)

二、项目初始化

Cloudflare 官方提供了 MCP 服务器的脚手架:

npm create cloudflare@latest -- my-mcp-server --template=cloudflare/ai/demos/remote-mcp-authless

这会创建一个包含基本结构的项目。进去看看:

cd my-mcp-server

核心文件结构:

my-mcp-server/
├── src/
│   ├── index.ts          # Workers 入口
│   └── tools.ts          # MCP 工具定义
├── wrangler.toml         # Cloudflare 配置
├── package.json
└── tsconfig.json

三、理解核心代码

先看 src/index.ts

import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

type Env = {
  MCP_OBJECT: DurableObjectNamespace<MyMCP>;
};

export class MyMCP extends McpAgent {
  server = new McpServer({
    name: "my-mcp-server",
    version: "1.0.0",
  });

  async init() {
    // 在这里注册工具
    this.server.tool(
      "get_weather",
      "获取指定城市的天气",
      { city: z.string().describe("城市名称") },
      async ({ city }) => {
        const weather = await fetchWeather(city);
        return {
          content: [{ type: "text", text: JSON.stringify(weather) }],
        };
      }
    );
  }
}

export default {
  fetch(request: Request, env: Env) {
    const url = new URL(request.url);

    if (url.pathname === "/sse" || url.pathname === "/mcp") {
      // MCP 连接走 Durable Object
      const id = env.MCP_OBJECT.idFromName("default");
      const stub = env.MCP_OBJECT.get(id);
      return stub.fetch(request);
    }

    return new Response("MCP Server is running", { status: 200 });
  },
};

几个关键点:

  1. McpAgent 是 Cloudflare 提供的基类,封装了 MCP 协议的传输层
  2. Durable Objects 用来维护 MCP session 状态——SSE 连接需要持久化
  3. 两个端点/sse 用于旧的 SSE 传输,/mcp 用于新的 Streamable HTTP 传输

四、添加自定义工具

MCP 的核心价值是提供工具给 AI 调用。来写几个实用的:

查询数据库

import { z } from "zod";

this.server.tool(
  "query_db",
  "查询 D1 数据库",
  {
    sql: z.string().describe("SQL 查询语句"),
  },
  async ({ sql }) => {
    // 只允许 SELECT 查询
    if (!sql.trim().toUpperCase().startsWith("SELECT")) {
      return {
        content: [{ type: "text", text: "只允许 SELECT 查询" }],
        isError: true,
      };
    }

    const result = await this.env.DB.prepare(sql).all();
    return {
      content: [{ type: "text", text: JSON.stringify(result.results, null, 2) }],
    };
  }
);

读取 KV 存储

this.server.tool(
  "get_config",
  "读取配置项",
  {
    key: z.string().describe("配置键名"),
  },
  async ({ key }) => {
    const value = await this.env.KV.get(key);
    if (!value) {
      return {
        content: [{ type: "text", text: `配置 ${key} 不存在` }],
        isError: true,
      };
    }
    return {
      content: [{ type: "text", text: value }],
    };
  }
);

调用外部 API

this.server.tool(
  "search_docs",
  "搜索项目文档",
  {
    query: z.string().describe("搜索关键词"),
  },
  async ({ query }) => {
    const response = await fetch(
      `https://api.example.com/search?q=${encodeURIComponent(query)}`,
      {
        headers: {
          Authorization: `Bearer ${this.env.API_TOKEN}`,
        },
      }
    );
    const data = await response.json();
    return {
      content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
    };
  }
);

五、配置 wrangler.toml

name = "my-mcp-server"
main = "src/index.ts"
compatibility_date = "2025-01-01"

[durable_objects]
bindings = [
  { name = "MCP_OBJECT", class_name = "MyMCP" }
]

[[migrations]]
tag = "v1"
new_classes = ["MyMCP"]

# 如果用 D1 数据库
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "xxx"

# 如果用 KV
[[kv_namespaces]]
binding = "KV"
id = "xxx"

六、本地开发和调试

npx wrangler dev

服务启动后,MCP 端点在 http://localhost:8787/sse

用 Claude Desktop 测试连接。在 claude_desktop_config.json 里添加:

{
  "mcpServers": {
    "my-remote-server": {
      "url": "http://localhost:8787/sse"
    }
  }
}

重启 Claude Desktop,就能看到你注册的工具了。

如果用 Claude Code,可以直接通过命令行配置:

claude mcp add my-remote-server --transport sse http://localhost:8787/sse

七、部署到生产

npx wrangler deploy

部署完成后会给你一个 URL,比如 https://my-mcp-server.your-account.workers.dev

重要:加上认证。 不加认证的 MCP 服务器等于把你的数据库、API 全暴露了。

最简单的方案——Bearer Token 认证:

export default {
  fetch(request: Request, env: Env) {
    // 验证 token
    const auth = request.headers.get("Authorization");
    if (auth !== `Bearer ${env.AUTH_TOKEN}`) {
      return new Response("Unauthorized", { status: 401 });
    }

    // ... 正常处理
  },
};

设置密钥:

npx wrangler secret put AUTH_TOKEN
# 输入你的 token

Cloudflare 也支持 OAuth 认证,适合多用户场景,但配置复杂一些。对个人使用来说,Bearer Token 足够了。

八、踩坑记录

实际部署过程中遇到的问题:

1. Durable Objects 必须用 migration

第一次部署 Durable Objects 时,必须在 wrangler.toml 里定义 migration。忘了的话部署会报错。

2. SSE 连接超时

Cloudflare Workers 的 CPU 时间限制是免费版 10ms、付费版默认 30 秒(最高可配置到 5 分钟)。注意这是 CPU 时间,不是挂钟时间 —— SSE 连接本身可以长时间保持,但每次处理请求的 CPU 时间不能超限。MCP SDK 已经处理了重连逻辑。

3. 环境变量类型

在 Workers 里,环境变量都是字符串。如果你需要 JSON 配置,记得 JSON.parse()

4. 免费版限制

免费版 Workers 有几个限制需要注意:

  • CPU 时间 10ms / 请求(大多数 MCP 工具调用够用)
  • Durable Objects 免费额度有限
  • 如果 MCP 工具需要做复杂计算,考虑升级到 $5/月的付费版

总结

Cloudflare Workers + MCP 是一个非常实用的组合。把 MCP 服务器部署到边缘,你在任何设备上都能连接同一套工具,不再受限于本地环境。

核心步骤回顾:

  1. 用官方模板创建项目
  2. 定义 MCP 工具(在 init() 方法里注册)
  3. 配置 Durable Objects(维护 session 状态)
  4. 加上认证(至少 Bearer Token)
  5. wrangler deploy 部署

下一步可以探索的方向:把你常用的内部 API、数据库查询、自动化脚本都封装成 MCP 工具,部署到 Workers 上,打造自己的 AI 工具集。

相关文章

2025年3月27日

Cloudflare MCP开发实战 - 创建支持OAuth的MCP服务器(简版)

在当今AI应用生态中,MCP(Model Context Protocol)服务器扮演着至关重要的角色,它允许AI客户端通过标准化的接口访问各种工具和服务。而添加用户认证机制,不仅可以保护您的服务资源,还能为不同用户提供个性化的体验。 赛博菩萨 Cloudflare 提供了一组开发工具,以及开发者手册,帮助 MCP 开发者更加轻松地开发并部署 MCP 服务器...

MCPCloudflareOAuth

合作伙伴

CompeteMap — 英国及爱尔兰学生竞赛一站式搜索

数学、编程、科学、写作等各类竞赛信息汇总,支持按年龄和科目筛选,再也不错过报名截止日。

准备开始了吗?

先简单说明目标,我会给出最合适的沟通方式。