AI个人学习
和实操指南
豆包Marscode1

Cloudflare 拥抱远程 MCP:将 AI Agent 能力推向更广阔的互联网

Cloudflare 拥抱远程 MCP:将 AI Agent 能力推向更广阔的互联网-1

在构建 AI 应用和 Agent 的圈子里,模型上下文协议 (Model Context ProtocolMCP) 正成为一个热门话题。许多讨论围绕着在本地计算机上安装和运行 MCP 服务器展开。近期,Cloudflare 宣布支持在其平台上构建和部署远程 MCP 服务器,这标志着 MCP 应用的一个重要转折点。

Cloudflare 为简化远程 MCP 服务器的构建,引入了四项关键能力:

  1. workers-oauth-provider:一个 OAuth Provider 库,极大简化了远程服务必需的授权流程。
  2. McpAgent:集成在 Cloudflare Agents SDK 中的一个类,负责处理 MCP 的远程传输细节。
  3. mcp-remote:一个适配器工具,让仅支持本地连接的 MCP 客户端也能与远程 MCP 服务器交互。
  4. AI playground 作为远程 MCP 客户端:一个在线聊天界面,可以直接连接并测试远程 MCP 服务器,内置了认证检查功能。

开发者可以通过 Cloudflare 提供的示例代码和部署按钮,在短时间内将一个 MCP 服务器部署到生产环境。


https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/ai/tree/main/demos/remote-mcp-server

 

与之前普遍使用的本地 MCP 服务器不同,远程 MCP 服务器可以公开访问。用户只需通过熟悉的授权流程登录并授予权限,MCP 客户端(如 AI Agent)就能访问所需工具。这被认为是一个巨大的进步。过去几个月,将编码 Agent 连接到本地 MCP 服务器已让开发者初步体验到其潜力,而远程 MCP 则有望将类似的工作模式扩展到更广泛的用户群体,包括更多的日常消费级应用场景。这不仅仅是技术实现上的差异,更可能预示着 AI Agent 应用模式的根本性转变。

 

从本地到远程:MCP 走向大众的关键一步

MCP 正迅速成为一种通用协议,让大型语言模型 (LLM) 的能力超越简单的推理 (inference) 和检索增强生成 (RAG),能够执行需要访问外部资源的操作(例如发送邮件、部署代码、发布博客等)。它使得 AI Agent (MCP 客户端) 能够通过外部服务 (MCP 服务器) 提供的工具和资源进行交互。

然而,到目前为止,MCP 的应用大多局限在本地运行。如果想让 AI Agent 通过 MCP 访问网络上的某个工具,开发者通常需要在自己的机器上设置本地服务器。这意味着无法从网页界面或移动应用中使用 MCP,也缺少让普通用户进行身份验证和授权的机制。MCP 服务器实际上并未真正“上线”。

Cloudflare 拥抱远程 MCP:将 AI Agent 能力推向更广阔的互联网-3

对远程 MCP 连接的支持改变了这一局面。它为接触更广泛的互联网用户创造了机会,这些用户不太可能为了使用桌面应用而去本地安装和运行 MCP 服务器。远程 MCP 的支持,好比是从桌面软件向 Web 软件的过渡。用户期望跨设备连续工作,登录后一切就能正常使用。本地 MCP 对开发者来说很方便,但远程连接才是让 MCP 服务触达所有互联网用户的关键缺失环节。当然,远程连接也需要考虑网络延迟可能带来的影响,这与本地 stdio 通信是不同的。

Cloudflare 拥抱远程 MCP:将 AI Agent 能力推向更广阔的互联网-4

 

让认证和授权在 MCP 中“开箱即用”

将 MCP 从本地推向远程,不仅仅是改变传输层(从 stdio 到可流式 HTTP)。当构建一个需要访问用户账户信息的远程 MCP 服务器时,身份验证 (authentication) 和授权 (authorization) 变得至关重要。需要一种方式让用户登录并证明身份,还需要一种方式让用户控制 AI Agent 在使用服务时能够访问哪些内容。

MCP 规范采用了 OAuth 2.0 来解决这个问题。OAuth 是允许用户授权应用访问其信息或服务而无需共享密码的标准协议。在 MCP 场景下,MCP 服务器本身扮演 OAuth Provider 的角色。然而,自行完整实现符合 MCP 规范的 OAuth 流程相当复杂且容易出错。Cloudflare 提供的方案旨在解决这一痛点。

workers-oauth-provider:为 Cloudflare Workers 定制的 OAuth 2.1 Provider 库

当开发者在 Cloudflare 上部署 MCP 服务器时,其 Worker 可以利用 workers-oauth-provider 这个新的 TypeScript 库来充当 OAuth Provider。该库封装了 Worker 代码,为 API 端点(包括但不限于 MCP 服务器端点)添加了授权层。

MCP 服务器将直接收到已认证的用户信息作为参数,无需自行执行令牌验证或管理。同时,开发者仍然可以完全控制用户认证的方式:从登录界面 (UI) 到选择何种身份提供商(如 GoogleGitHub 或自建系统)。

完整的 MCP OAuth 流程如下:

Cloudflare 拥抱远程 MCP:将 AI Agent 能力推向更广阔的互联网-5

在这个流程中,MCP 服务器既是上游服务(如 GitHubGoogle)的 OAuth 客户端,又是面向 MCP 客户端(如 AI Agent)的 OAuth 服务器(Provider)。开发者可以使用任何上游认证流程,而 workers-oauth-provider 确保 MCP 服务器符合 MCP 规范的授权要求,能够与各种客户端应用和网站配合工作。这包括支持动态客户端注册 (RFC 7591) 和授权服务器元数据 (RFC 8414)。相比自行实现,使用此库能显著降低开发复杂性,并提高安全性与合规性。

简洁、可插拔的 OAuth 接口

使用 Cloudflare Workers 构建 MCP 服务器时,开发者只需提供 OAuth Provider 相关路径(授权、令牌、客户端注册端点)的实例,以及 MCP 服务器和认证逻辑的处理器 (handler):

import OAuthProvider from "@cloudflare/workers-oauth-provider";
import MyMCPServer from "./my-mcp-server";
import MyAuthHandler from "./auth-handler";
export default new OAuthProvider({
apiRoute: "/sse", // MCP 客户端连接服务器的路由
apiHandler: MyMCPServer.mount('/sse'), // MCP 服务器实现
defaultHandler: MyAuthHandler, // 认证实现
authorizeEndpoint: "/authorize",
tokenEndpoint: "/token",
clientRegistrationEndpoint: "/register",
});

这种抽象使得插入自定义认证逻辑变得容易。例如,一个使用 GitHub 作为身份提供商的 MCP 服务器,可以通过实现 /callback 和 /authorize 路由,在不到 100 行代码内完成集成。

为何 MCP 服务器要发行自己的 Token?

在上面的授权图中以及 MCP 规范的授权部分,值得注意的是 MCP 服务器会向 MCP 客户端发行自己的 Token,而不是直接传递从上游服务获取的 Token

具体来说,Worker 会将从上游获取的访问令牌 (access token) 加密存储(例如使用 Workers KV),然后生成并发行一个全新的、独立的 Token 给 MCP 客户端。workers-oauth-provider 库会自动处理这个过程,开发者的代码无需直接接触明文的上游令牌或自行管理存储,从而避免潜在的安全风险。

// 调用 completeAuthorization 时传入的 accessToken 会被加密存储,绝不会暴露给 MCP 客户端
// 一个新的、独立的 token 会在 /token 端点生成并提供给客户端
const { redirectTo } = await c.env.OAUTH_PROVIDER.completeAuthorization({
request: oauthReqInfo,
userId: login,
metadata: { label: name },
scope: oauthReqInfo.scope,
props: {
accessToken,  // 加密存储,不发送给 MCP 客户端
},
})
return Response.redirect(redirectTo)

表面上看,这种间接方式似乎更复杂。为何如此设计?

通过发行自己的 TokenMCP 服务器可以实施比上游提供商更细粒度的访问控制。即使发放给 MCP 客户端的 Token 泄露,攻击者获得的也仅仅是该 MCP 服务器明确授予的有限权限(通过其提供的 tools),而不是上游服务的完整访问权限。

例如,假设一个 MCP 服务器请求用户授权读取 Gmail 邮件的权限(使用 gmail.readonly scope)。但该服务器暴露的 tool 功能更窄,只允许读取特定发件人的旅行预订通知,以回答诸如“我明天酒店的退房时间是几点?”之类的问题。开发者可以在 MCP 服务器中强制执行此约束。如果发放给 MCP 客户端的 Token 被盗,由于该 Token 对应的是 MCP 服务器而非原始的上游提供商 (Google),攻击者无法用它读取任意邮件,只能调用 MCP 服务器提供的特定工具。OWASP 将“过度代理”(Excessive Agency) 列为构建 AI 应用的主要风险之一。通过发行自有 Token 并强制执行约束,MCP 服务器可以限制工具的访问权限,仅提供客户端所需的功能,遵循最小权限原则。

另一个例子,基于前述的 GitHub 认证,可以强制只有特定用户才能访问某个工具。下面的示例中,只有白名单内的用户 (geelen) 才能看到并调用 generateImage 工具,该工具使用 Workers AI 根据提示生成图像:

import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
const USER_ALLOWLIST = new Set(["geelen"]); // 使用 Set 提高查找效率
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',
'使用 flux-1-schnell 模型生成图像。',
{
prompt: z.string().describe('你想要生成的图像的文本描述。')
},
async ({ prompt }) => {
const response = await this.env.AI.run('@cf/black-forest-labs/flux-1-schnell', {
prompt,
steps: 8
});
// 检查 response.image 是否存在
if (!response.image) {
throw new Error("图像生成失败,未返回图像数据。");
}
return {
content: [{ type: 'image', data: response.image, mimeType: 'image/jpeg' }],
}
}
)
}
}
}

 

引入 McpAgent:兼容当前与未来的远程传输

将 MCP 带出本地机器的下一步是开放远程传输层。本地运行的 MCP 服务器通常通过标准输入输出 (stdio) 进行通信,但要让 MCP 服务器能通过互联网被调用,就必须实现远程传输协议,目前规范草案中是基于 HTTP 的 Server-Sent Events (SSE)

Cloudflare 在其 Agents SDK 中引入的 McpAgent 类处理了远程传输的复杂性。它在后台利用 Durable Objects 来维持持久连接,使得 MCP 客户端可以通过 SSE 向 MCP 服务器发送消息。开发者无需编写处理传输或序列化的底层代码。一个极简的 MCP 服务器可以仅用十几行代码实现:

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 规范中的远程传输正在修订,计划用可流式 HTTP (Streamable HTTP) 替代当前的 HTTP+SSE 方案。这将允许与 MCP 服务器建立无状态、纯粹的 HTTP 连接,并可选升级到 SSE,同时消除了客户端需要向不同端点发送消息的复杂性。Cloudflare 表示 McpAgent 类将随规范更新而演进,以支持新的 Streamable HTTP 标准,确保开发者不必重写代码来适应传输方式的变化。

这种对未来传输协议演进的考虑同样重要。目前,绝大多数 MCP 服务器主要暴露 tools,它们本质上是简单的远程过程调用 (RPC),可以通过无状态传输提供。但更复杂的“人在环路中” (human-in-the-loop) 和 Agent 间交互场景,将需要 prompts 和 sampling 等 MCP 概念的支持。这些需要双向、实时通信的场景,如果没有双向传输层很难高效实现。届时,Cloudflare 平台、Agents SDK 和 Durable Objects 都原生支持 WebSockets,能够提供全双工、双向的实时通信能力,为未来更高级的 MCP 应用奠定基础。

 

有状态、具备 Agent 特性的 MCP 服务器

在 Cloudflare 上构建 MCP 服务器时,每个 MCP 客户端会话都由一个 Durable Object 支持(通过 Agents SDK)。这意味着每个会话都可以管理和持久化自己的状态,甚至可以拥有自己的 SQL 数据库。

这为构建有状态的 MCP 服务器打开了大门。MCP 服务器不再仅仅是客户端应用和外部 API 之间的无状态转换层,它们本身可以是有状态的应用——例如游戏、带购物车的结账流程、持久化知识图谱等。在 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', '增加存储在 MCP 服务器中的计数器的值', { a: z.number() }, async ({ a }) => {
// 更新状态
this.setState({ ...this.state, counter: this.state.counter + a });
return {
content: [{ type: 'text', text: `增加了 ${a}, 当前总数是 ${this.state.counter}` }],
}
})
}
// 状态更新时的回调(可选)
onStateUpdate(state: State) {
console.log({ stateUpdate: state });
}
}

对于给定的会话,上述 MCP 服务器会在多次 tool 调用之间记住计数器的状态。

在 MCP 服务器内部,开发者可以利用 Cloudflare 完整的开发者平台能力,例如让 MCP 服务器启动浏览器进行网页浏览、触发 Workflow、调用 AI 模型等。这预示着 MCP 生态系统将向更高级、更智能化的用例演进。

 

连接现有 MCP 客户端到远程服务器

Cloudflare 较早地支持了远程 MCP,甚至在主流 MCP 客户端应用普遍支持远程、带认证的 MCP 之前。这为开发者提供了先行一步的机会。

但这也带来一个现实挑战:如果还没有支持远程 MCP 的客户端,开发者如何测试和让用户使用他们构建的远程 MCP 服务器?

Cloudflare 提供了两个新工具来应对:

  1. Workers AI Playground 更新:该在线聊天界面现在是一个功能完整的远程 MCP 客户端,支持连接到任何远程 MCP 服务器,并内置了认证流程。开发者只需输入远程服务器的 URL(例如 https://remote-server.example.com/sse)并点击连接,即可立即测试,无需本地安装任何软件。

    Cloudflare 拥抱远程 MCP:将 AI Agent 能力推向更广阔的互联网-6

    点击连接后,用户将经历认证流程(如果设置了),之后便能直接在聊天界面中与 MCP 服务器的工具交互。

  2. mcp-remote 适配器:对于那些已经支持 MCP 但尚未处理远程连接和认证的客户端(如 Claude Desktop 或 Cursor),可以使用 mcp-remote。这是一个 npm 包,充当本地客户端和远程服务器之间的桥梁。它让开发者和用户可以在他们熟悉的工具中预览与远程 MCP 服务器的交互体验,而无需等待客户端本身更新支持。

    Cloudflare 提供了关于如何将 mcp-remote 与 Claude DesktopCursorWindsurf 等流行 MCP 客户端配合使用的指南。例如,在 Claude Desktop 中,只需在配置文件中添加类似如下配置:

    {
    "mcpServers": {
    "remote-example": {
    "command": "npx",
    "args": [
    "mcp-remote",
    "https://remote-server.example.com/sse" // 替换为你的远程服务器 URL
    ]
    }
    }
    }
    

 

远程 MCP 的时代正在到来

远程模型上下文协议 (Remote MCP) 无疑是 AI Agent 领域的一个重要发展方向。当客户端应用广泛支持远程 MCP 服务器时,其用户群体将从开发者扩展到更广泛的人群——他们甚至可能从未听说过 MCP 这个术语。

对于服务提供商而言,构建远程 MCP 服务器是将自身服务集成到数百万用户使用的 AI 助手和工具中的关键途径。许多大型互联网公司据称已在积极构建 MCP 服务器,同时,也让人期待那些以 Agent-firstMCP-native 方式诞生的新兴业务。

基于 Cloudflare 提供的工具和平台,开发者现在就可以开始构建面向未来的远程 MCP 应用。这不仅是技术栈的一次升级,更是对 AI Agent 如何融入互联网服务的一次重要探索。随着生态系统的成熟,远程 MCP 有望催生出更加智能和个性化的用户体验。开发者可以查阅 Cloudflare 开发者文档 获取更多信息并开始实践。

未经允许不得转载:首席AI分享圈 » Cloudflare 拥抱远程 MCP:将 AI Agent 能力推向更广阔的互联网
zh_CN简体中文