跳转到内容
搜索文档

将 MCP tool 与 Code Mode 一起使用

最后更新 查看 MarkdownAgent 设置

使用 McpConnector 在 Code Mode 沙箱内暴露现有 Model Context Protocol (MCP) 客户端连接中的工具。连接器与持久运行时配合,含发现、审批与执行历史。

本页涵盖 Agent 消费 MCP 服务器。要将 Code Mode 发布为 MCP 服务器,请参阅 Code Mode MCP 服务器模式

前提条件

需要:

  • 已配置 持久 Code Mode 运行时 的项目。该设置提供 Worker Loader 绑定与 CodemodeRuntime 导出。
  • 现有 Agents SDK MCP 连接。创建与授权连接请参阅 McpClient API
  1. 安装 Code Mode

    若项目尚未包含 Code Mode,安装 @cloudflare/codemode

    npm i @cloudflare/codemode
  2. 创建 MCP connector

    在独立文件中创建 connector。它是 plain class,无特殊文件名或 import 语法。

    src/github-connector.jsjs
    import { McpConnector } from "@cloudflare/codemode";
    
    export class GithubConnector extends McpConnector {
    	connection;
    
    	constructor(ctx, env, connection) {
    		super(ctx, env);
    		this.connection = connection;
    	}
    
    	name() {
    		return "github";
    	}
    
    	instructions() {
    		return "Use for GitHub repositories, issues, and pull requests.";
    	}
    
    	createConnection() {
    		return this.connection;
    	}
    
    	tool(name, tool) {
    		if (name === "create_issue") {
    			return { ...tool, requiresApproval: true };
    		}
    
    		return tool;
    	}
    }
    src/github-connector.tsts
    import {
    	McpConnector,
    	type ConnectorTool,
    	type McpConnectionLike,
    } from "@cloudflare/codemode";
    
    export class GithubConnector extends McpConnector<Env> {
    	private connection: McpConnectionLike;
    
    	constructor(
    		ctx: DurableObjectState | ExecutionContext,
    		env: Env,
    		connection: McpConnectionLike,
    	) {
    		super(ctx, env);
    		this.connection = connection;
    	}
    
    	override name() {
    		return "github";
    	}
    
    	protected override instructions() {
    		return "Use for GitHub repositories, issues, and pull requests.";
    	}
    
    	protected override createConnection() {
    		return this.connection;
    	}
    
    	protected override tool(
    		name: string,
    		tool: ConnectorTool,
    	): ConnectorTool {
    		if (name === "create_issue") {
    			return { ...tool, requiresApproval: true };
    		}
    
    		return tool;
    	}
    }

    createConnection() 返回现有 Agents SDK 连接。name() 定义沙箱全局,因此此连接器在 github 下暴露方法。每个运行时内连接器名称须唯一。

    McpConnector 为每个发现的 MCP 工具创建一个带类型的沙箱方法。从 MCP schema 推导方法类型。每个方法通过 connection.client.callTool() 调用原始工具。

    连接器将 MCP 工具名称清理为有效 JavaScript 标识符。例如 list-pull.requests 变为 list_pull_requests3d-render 变为 _3d_renderdelete 变为 delete_。若两个源名产生相同标识符,连接器抛出错误。重写 toolName() 以消歧。

    tool() 装饰钩子按清理后的名称接收每个生成方法。此例中钩子将 create_issue 标记为需审批。持久运行时在执行该方法前暂停,审批后恢复运行。

  3. 将 connector 加入 runtime

    在 Agent 中找到现有 MCP 连接并传给 connector。创建 Code Mode runtime 时包含 connector:

    src/server.jsjs
    import { Agent } from "agents";
    import {
    	createCodemodeRuntime,
    	DynamicWorkerExecutor,
    } from "@cloudflare/codemode";
    import { GithubConnector } from "./github-connector";
    
    export class Chat extends Agent {
    	async codemodeRuntime() {
    		await this.mcp.waitForConnections();
    
    		const server = this.mcp
    			.listServers()
    			.find((server) => server.name === "github");
    
    		if (!server) {
    			throw new Error("GitHub MCP server is not registered.");
    		}
    
    		const connection = this.mcp.mcpConnections[server.id];
    		if (!connection) {
    			throw new Error("GitHub MCP connection is not available.");
    		}
    
    		return createCodemodeRuntime({
    			ctx: this.ctx,
    			executor: new DynamicWorkerExecutor({ loader: this.env.LOADER }),
    			connectors: [new GithubConnector(this.ctx, this.env, connection)],
    		});
    	}
    }
    src/server.tsts
    import { Agent } from "agents";
    import {
    	createCodemodeRuntime,
    	DynamicWorkerExecutor,
    } from "@cloudflare/codemode";
    import { GithubConnector } from "./github-connector";
    
    export class Chat extends Agent<Env> {
    	private async codemodeRuntime() {
    		await this.mcp.waitForConnections();
    
    		const server = this.mcp
    			.listServers()
    			.find((server) => server.name === "github");
    
    		if (!server) {
    			throw new Error("GitHub MCP server is not registered.");
    		}
    
    		const connection = this.mcp.mcpConnections[server.id];
    		if (!connection) {
    			throw new Error("GitHub MCP connection is not available.");
    		}
    
    		return createCodemodeRuntime({
    			ctx: this.ctx,
    			executor: new DynamicWorkerExecutor({ loader: this.env.LOADER }),
    			connectors: [
    				new GithubConnector(this.ctx, this.env, connection),
    			],
    		});
    	}
    }

    先 await codemodeRuntime(),然后将 runtime.tool() 作为 codemode 工具传给模型。调用审批、拒绝、回滚或代码片段方法前再次 await 该辅助方法。这确保 MCP 连接在休眠后完成恢复。

    若运行时属于 Think agent,将 MCP 工具排除在直接模型工具集外:

    import { Think } from "@cloudflare/think";
    
    export class Chat extends Think {
    	includeMcpTools = false;
    	waitForMcpConnections = true;
    }
    import { Think } from "@cloudflare/think";
    
    export class Chat extends Think<Env> {
        includeMcpTools = false;
        waitForMcpConnections = true;
    }

    includeMcpTools = false 跳过 Think 的自动 getAITools() 调用。MCP 连接仍对 McpConnector 可用。

  4. 让模型发现并调用 tool

    告诉模型在调用不熟悉的方法前使用 codemode.search()codemode.describe()。模型生成的沙箱代码可发现并调用生成的方法:

    async () => {
    	const matches = await codemode.search("open pull requests");
    	const docs = await codemode.describe(matches.results[0].path);
    
    	const pullRequests = await github.list_pull_requests({
    		owner: "cloudflare",
    		repo: "agents",
    		state: "open",
    	});
    
    	return { docs, pullRequests };
    };

    codemode.search() 返回 ranked connector 方法。codemode.describe() 返回 connector 或方法的 TypeScript 文档。这使模型仅在需要时加载 tool 详情。

当模型调用 github.create_issue() 时,运行时返回已暂停的执行。通过运行时审批该执行以执行 MCP 工具并继续同一沙箱程序。

使用 AI SDK tool 集合

对无需持久审批或 codemode.search()/codemode.describe() 的较小集成,将 Agents SDK 工具集合直接传给 createCodeTool()

import { DynamicWorkerExecutor } from "@cloudflare/codemode";
import { createCodeTool } from "@cloudflare/codemode/ai";

await this.mcp.waitForConnections();

const executor = new DynamicWorkerExecutor({ loader: this.env.LOADER });
const codemode = createCodeTool({
	tools: this.mcp.getAITools(),
	executor,
});
import { DynamicWorkerExecutor } from "@cloudflare/codemode";
import { createCodeTool } from "@cloudflare/codemode/ai";

await this.mcp.waitForConnections();

const executor = new DynamicWorkerExecutor({ loader: this.env.LOADER });
const codemode = createCodeTool({
	tools: this.mcp.getAITools(),
	executor,
});

此方式在默认 codemode 命名空间下暴露 MCP 工具。不使用连接器运行时的持久暂停、审批与恢复流程。当工具可产生副作用或模型需要按需发现时使用 McpConnector

getAITools() 转换 MCP 输入输出 schema 供 AI SDK 使用。Agents SDK 复用这些转换 schema,每个实时连接保持相同当前目录。仅需检查原始 MCP 目录时使用 this.mcp.listTools()

这篇文档对您有帮助吗?