当您在 Cloudflare 上构建 MCP 服务器时,您需要扩展来自 Agents SDK 的 McpAgent
类 ↗,如下所示:
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) }], }), ); }}
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 服务器的每个实例都有自己的持久状态,由 Durable Object 支持,拥有自己的 SQL 数据库。
您的 MCP 服务器不一定必须是一个 Agent。您可以构建无状态的 MCP 服务器,只需使用 @modelcontextprotocol/typescript-sdk
包为您的 MCP 服务器添加工具。
但是,如果您希望您的 MCP 服务器能够:
- 记住以前的工具调用和它提供的响应
- 向 MCP 客户端提供游戏,记住游戏板状态、以前的移动和分数
- 缓存以前外部 API 调用的状态,以便后续工具调用可以重复使用它
- 执行 Agent 可以做的任何事情,但允许 MCP 客户端与其通信
您可以使用下面的 API 来实现这些功能。
McpAgent
实例自动支持 WebSockets 休眠,允许有状态的 MCP 服务器在非活动期间休眠,同时保留其状态。这意味着您的 agents 只在主动处理请求时消耗计算资源,在保持完整上下文和对话历史的同时优化成本。
休眠功能默认启用,无需额外配置。
McpAgent 类提供与 OAuth Provider Library ↗ 的无缝集成,用于身份验证和授权。
当用户向您的 MCP 服务器进行身份验证时,他们的身份信息和令牌通过 props
参数提供,允许您:
- 访问特定用户的数据
- 在执行操作前检查用户权限
- 根据用户属性自定义响应
- 使用身份验证令牌代表用户向外部服务发出请求
McpAgent
类提供了来自 Agents SDK 的以下方法子集:
例如,以下代码实现了一个记住计数器值的 MCP 服务器,并在调用 add
工具时更新计数器:
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", });
initialState = { 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) { console.log({ stateUpdate: state }); }}
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 }); }}
以下来自 Agents SDK 的 API 在 McpAgent
上尚不可用:
- WebSocket API(
onMessage
、onError
、onClose
、onConnect
) - 调度 API
this.schedule
- @2025 Cloudflare Ubitools
- Cf Repo