原文地址 blog.cloudflare.com2025-03-25-9 min read
你现在可以将远程 MCP 服务器构建并部署到 Cloudflare,我们负责构建过程中的复杂部分……
似乎几乎每个人都在构建 AI 应用程序和代理时都在谈论 模型上下文协议(MCP),以及在自己的计算机上安装并运行本地 MCP 服务器。
现在,您可以在 Cloudflare 上 构建和部署远程 MCP 服务器 。我们已经在 Cloudflare 上添加了四项功能,这些功能会为您处理构建远程 MCP 服务器的复杂部分:
-
workers-oauth-provider — 一个 OAuth 提供商,使授权变得容易
-
McpAgent — 一个内置在 Cloudflare Agents SDK 中的类,处理远程传输
-
mcp-远程 — 一个适配器,让原本只支持本地连接的 MCP 客户端能够与远程 MCP 服务器协同工作
-
AI 游乐场作为远程 MCP 客户端 — 一个聊天界面,允许您连接到远程 MCP 服务器,并包含身份验证检查
按下面的按钮,或访问开发文档 ,您将在不到两分钟内准备好使用这个示例 MCP 服务器进行生产部署:
与您之前可能使用的本地 MCP 服务器不同,远程 MCP 服务器可以通过互联网访问。人们只需登录并使用熟悉的授权流程授予 MCP 客户端权限。我们认为这将是一个巨大的突破 —— 连接编码代理与 MCP 服务器在过去几个月中已经让开发者们大开眼界,而远程 MCP 服务器也有潜力以更广泛的方式,包括更多的日常消费者使用案例,让编码代理与 MCP 服务器协同工作。
从本地到远程——将 MCP 带给大众
MCP 正迅速成为一种通用协议,使@1011#能够超越推理和检索-生成 ,并执行需要访问超出 AI 应用程序本身的资源的操作(如发送电子邮件、部署代码更改、发布博客文章等)。它使 AI 代理(MCP 客户端)能够访问外部服务中的工具和资源(MCP 服务器)。
截至目前,MCP 仅限于在您的本地机器上运行——如果您想使用 MCP 访问网络上的工具,您需要在本地设置服务器。您无法从基于 Web 的界面或移动应用程序中使用 MCP,也没有一种方法可以让人们进行身份验证并授予 MCP 客户端权限。换句话说,MCP 服务器尚未上线。
使 MCP 的身份验证和授权能够自动完成
不仅仅是改变传输层——从标准输入输出到可流式传输的 HTTP——当你构建一个使用用户账户信息的远程 MCP 服务器时,你需要身份验证和授权 。你需要一种让用户登录并证明他们身份的方法(身份验证),以及一种让用户控制 AI 代理在使用服务时能够访问的内容的方法(授权)。
MCP 通过 OAuth 实现这一点,OAuth 是一种标准协议,允许用户授予应用程序访问其信息或服务的权限,而无需共享密码。在这里,MCP 服务器本身充当 OAuth 提供商。然而,使用 MCP 实现 OAuth 比较困难,因此在您在 Cloudflare 上构建 MCP 服务器时,我们会为您提供。
workers-oauth-provider — 一个适用于 Cloudflare Workers 的 OAuth 2.1 提供商库
当你将 部署一个 MCP 服务器 到 Cloudflare 时,你的 Worker 充当 OAuth 提供者,使用 workers-oauth-provider,这是一个新的 TypeScript 库,它包装了 Worker 的代码,并为 API 端点(包括但不限于 MCP 服务器 API 端点)添加了授权。
你的 MCP 服务器将接收到已经认证的用户详细信息作为参数。你不需要自行进行任何检查,或直接管理令牌。你仍然可以完全控制如何进行用户认证:从他们登录时看到的 UI,到他们使用的登录提供商。你可以选择使用自己的第三方认证和授权提供商,如 Google 或 GitHub,或者与你自己的系统集成。
完整的 MCP OAuth 流程 如下所示:
在这里,您的 MCP 服务器既充当与上游服务的 OAuth 客户端,又充当 MCP 客户端的 OAuth 服务器(也称为 OAuth “提供商”)。您可以使用任何上游身份验证流程,但 workers-oauth-provider 确保您的 MCP 服务器是 标准符合型 的,并且能够与各种客户端应用程序和网站协同工作。这包括对动态客户端注册(RFC 7591)和授权服务器元数据(RFC 8414)的支持。
一个简单的插件式接口用于 OAuth
当你使用 Cloudflare Workers 构建一个 MCP 服务器时,你需要提供 OAuth 提供者的实例,并指向你的授权、令牌和客户端注册端点,以及你的 MCP 服务器和认证的处理程序 :
import OAuthProvider from "@cloudflare/workers-oauth-provider";
import MyMCPServer from "./my-mcp-server";
import MyAuthHandler from "./auth-handler";
export default new OAuthProvider({
apiRoute: "/sse",
apiHandler: MyMCPServer.mount('/sse'),
defaultHandler: MyAuthHandler,
authorizeEndpoint: "/authorize",
tokenEndpoint: "/token",
clientRegistrationEndpoint: "/register",
});
这个抽象让你可以轻松地插入自己的认证。查看一下使用 GitHub 作为身份提供商的 MCP 服务器的这个示例 ,通过实现/callback 和/authorize 路由,在不到 100 行代码中完成。
为什么 MCP 服务器会自己颁发令牌?
您可能已经在上面的授权图中注意到,以及在 MCP 规范的授权部分中,MCP 服务器会向 MCP 客户端发放自己的令牌。
而不是直接将从上游提供商接收到的令牌传递给 MCP 客户端,您的 Worker 会在 Workers KV 中存储加密的访问令牌。然后向客户端发放自己的令牌。如上图中的 GitHub 示例所示,这由 workers-oauth-provider 为您处理——您的代码从未直接处理过写入令牌的操作,防止了错误的发生。您可以在上图中的 GitHub 示例中的以下代码片段中看到这一点:
const { redirectTo } = await c.env.OAUTH_PROVIDER.completeAuthorization({
request: oauthReqInfo,
userId: login,
metadata: { label: name },
scope: oauthReqInfo.scope,
props: {
accessToken,
},
})
return Response.redirect(redirectTo)
这种间接性在表面上可能听起来更复杂。为什么它会这样工作?
通过向 MCP 客户端发放自己的令牌,MCP 服务器可以限制访问并实施更细粒度的控制,而不是上游提供商。如果您发放给 MCP 客户端的令牌被泄露,攻击者只能获得您通过 MCP 工具明确授予的有限权限,而不是原始令牌的全部访问权限。
让我们假设你的 MCP 服务器请求用户授权读取其 Gmail 账户中的邮件,使用的是 gmail.readonly 范围 。MCP 服务器公开的工具更为具体,仅允许从有限的发件人读取旅行预订通知,以回答类似“我明天酒店房间的退房时间是什么时候?”的问题。你可以在 MCP 服务器上实施这种限制,如果 MCP 客户端发出的令牌被泄露,因为该令牌是发给 MCP 服务器的——而不是直接发给上游提供商(Google)的原始令牌——攻击者无法利用它来读取任意邮件。他们只能调用 MCP 服务器提供的工具。OWASP 指出,“过度代理”是构建 AI 应用程序的顶级风险因素之一,通过向客户端发放自己的令牌并实施限制,你的 MCP 服务器可以将工具的访问权限限制在客户端所需的内容范围内。
或者在此前的 GitHub 示例基础上进行构建,可以强制只有特定用户才能访问某个特定工具。在下面的示例中,只有被列入允许列表的用户才能看到或调用 generateImage 工具,该工具使用 Workers AI 根据提示生成图片:
import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
const USER_ALLOWLIST = ["geelen"];
export class MyMCP extends McpAgent<Props, Env> {
server = new McpServer({
name: "Github OAuth Proxy Demo",
version: "1.0.0",
});
async init() {
if (USER_ALLOWLIST.has(this.props.login)) {
this.server.tool(
'generateImage',
'Generate an image using the flux-1-schnell model.',
{
prompt: z.string().describe('A text description of the image you want to generate.')
},
async ({ prompt }) => {
const response = await this.env.AI.run('@cf/black-forest-labs/flux-1-schnell', {
prompt,
steps: 8
})
return {
content: [{ type: 'image', data: response.image!, mimeType: 'image/jpeg' }],
}
}
)
}
}
}
介绍 McpAgent:一种当前可用的远程传输支持,未来也将与 MCP 规范的修订兼容
打开 MCP 远程通信的下一步是打开一个远程传输层。您本地机器上运行的 MCP 服务器只是通过标准输入输出进行通信,但为了使 MCP 服务器可以通过互联网调用,它必须实现远程传输 。
我们今天作为 McpAgent 类的一部分引入,作为我们 Agents SDK 的一部分,它为您处理了这一点,使用持久对象在后台保持一个持久连接打开,这样 MCP 客户端可以向您的 MCP 服务器发送服务器发送事件(SSE)。您不需要自己编写处理传输或序列化的代码。一个最小的 MCP 服务器可以在 15 行代码中看起来像这样:
import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
export class MyMCP extends McpAgent {
server = new McpServer({
name: "Demo",
version: "1.0.0",
});
async init() {
this.server.tool("add", { a: z.number(), b: z.number() }, async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }],
}));
}
}
经过大量的讨论 ,MCP 规范中的远程传输正在改变,Streamable HTTP 将取代 HTTP+SSE。这使得 MCP 服务器可以使用无状态的纯 HTTP 连接,同时可以选择升级到 SSE,从而消除了 MCP 客户端需要向不同于其首次连接的端点发送消息的需要。McpAgent 类也将随之改变,只需与 Streamable HTTP 一起工作,因此无需从头开始支持传输方式的修订。
这同样适用于未来传输的迭代。目前,绝大多数 MCP 服务器仅暴露工具,这些工具是可以通过无状态传输提供的简单远程过程调用(RPC) 方法。但更复杂的人在环和代理间交互将需要提示和采样 。我们预计这些类型的聊天式、双向交互需要实时进行,这将很难在没有双向传输层的情况下做好。当这种情况到来时,Cloudflare、 代理 SDK 和持久对象都将原生支持 WebSocket,这使得全双工、双向实时通信成为可能。
具有状态的代理 MCP 服务器
当你在 Cloudflare 上构建 MCP 服务器时,每个 MCP 客户端会话都通过 Agents SDK 由一个持久对象支持。这意味着每个会话可以管理并持久化自己的状态, 并通过其自己的 SQL 数据库支持 。
这为构建具有状态的 MCP 服务器打开了大门。与仅仅作为客户端应用程序和外部 API 之间的无状态层不同,部署在 Cloudflare 上的 MCP 服务器可以成为具有状态的应用程序——游戏、购物车加结账流程、一个持久的知识图谱,或者你可以想象的任何东西。当你在 Cloudflare 上构建时,MCP 服务器可以远远不只是你 REST API 前面的一层。
为了理解这种工作的基本原理,让我们来看一个最小的示例,该示例会递增计数器:
import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
type State = { counter: number }
export class MyMCP extends McpAgent<Env, State, {}> {
server = new McpServer({
name: "Demo",
version: "1.0.0",
});
initialState: State = {
counter: 1,
}
async init() {
this.server.resource(`counter`, `mcp://resource/counter`, (uri) => {
return {
contents: [{ uri: uri.href, text: String(this.state.counter) }],
}
})
this.server.tool('add', 'Add to the counter, stored in the MCP', { a: z.number() }, async ({ a }) => {
this.setState({ ...this.state, counter: this.state.counter + a })
return {
content: [{ type: 'text', text: String(`Added ${a}, total is now ${this.state.counter}`) }],
}
})
}
onStateUpdate(state: State) {
console.log({ stateUpdate: state })
}
}
对于给定的会话,上述 MCP 服务器将在工具调用之间记住计数器的状态。
在 MCP 服务器内部,你可以使用 Cloudflare 的整个开发者平台,并让 MCP 服务器启动自己的网络浏览器、触发工作流、调用 AI 模型等。我们期待看到 MCP 生态系统发展出更高级的应用场景。
从今天仅支持本地 MCP 的 MCP 客户端连接到远程 MCP 服务器
Cloudflare 已经支持远程 MCP — 在最突出的 MCP 客户端应用程序支持远程、身份验证的 MCP 之前,以及其他平台支持远程 MCP 之前。我们这样做是为了让你提前为 MCP 的发展方向做好准备。
但是如果你今天构建了一个远程 MCP 服务器,这就会带来一个挑战——如果没有任何支持远程 MCP 的 MCP 客户端,人们如何开始使用你的 MCP 服务器呢?
我们有两个新的工具,可以让你测试远程 MCP 服务器,并模拟未来用户如何与其交互:
我们更新了 Workers AI Playground,使其成为一个完全支持远程 MCP 的客户端,允许你连接到任何远程 MCP 服务器,并内置了身份验证支持。这个在线聊天界面让你无需在设备上安装任何东西即可立即测试远程 MCP 服务器。只需输入远程 MCP 服务器的 URL(例如:remote-server.example.com/sse),然后点击连接…
一旦你点击连接,你将通过身份验证流程(如果你设置了的话),之后你就可以直接从聊天界面与 MCP 服务器工具进行交互。
如果您更喜欢使用像 Claude Desktop 或 Cursor 这样的客户端,这些客户端已经支持 MCP,但尚未处理带有身份验证的远程连接,您可以使用 mcp-remote。mcp-remote 是一个适配器,可以让原本只支持本地连接的 MCP 客户端能够与远程 MCP 服务器进行交互。这使得您和您的用户能够在今天使用的工具中预览与远程 MCP 服务器交互的情况,而无需等待客户端原生支持远程 MCP。
我们已经发布了一篇指南 ,介绍了如何使用 mcp-remote 与 Claude Desktop、Cursor 和 Windsurf 等流行的 MCP 客户端。在 Claude Desktop 中,您需要在配置文件中添加以下内容:
{
"mcpServers": {
"remote-example": {
"command": "npx",
"args": [
"mcp-remote",
"https://remote-server.example.com/sse"
]
}
}
}
Remote Model Context Protocol (MCP) 即将到来!当客户端应用程序支持远程 MCP 服务器时,能够使用它们的人群将从我们这些开发者扩展到普通大众——这些人甚至可能根本不知道 MCP 是什么或代表什么。
在远程构建 MCP 服务器是将您的服务引入数以亿计人使用的 AI 助手和工具的方式。我们很高兴看到互联网上许多最大的公司都在忙于构建 MCP 服务器,我们对以代理优先、MCP 原生方式出现的新兴企业感到好奇。
在 Cloudflare, 您今天就可以开始构建 。我们已经为您做好了准备,并且随时准备帮助您。请通过 1800-mcp@cloudflare.com 联系我们,我们将帮助您开始。MCP 还有很多更多的功能,我们期待看到您构建的内容。
Cloudflare 的连接云保护整个企业网络 ,帮助客户高效地构建互联网规模的应用程序 ,加速任何网站或互联网应用程序 , 抵御 DDoS 攻击 ,防止黑客入侵 ,并可以帮助您踏上零信任之旅 。
从任何设备访问 1.1.1.1,开始使用我们的免费应用程序,使您的互联网更快更安全。