← Создание агентов на Cloudflare / agents / tools / codemode
Используйте инструменты MCP с Code Mode
Используйте McpConnector чтобы предоставить инструменты из существующего подключения клиента Model Context Protocol (MCP) внутри песочницы режима Code Mode. Коннектор работает с устойчивым runtime, включая обнаружение, подтверждения и историю выполнения.
Эта страница описывает, как Agent использует MCP-сервер. Чтобы опубликовать Code Mode как MCP-сервер, см. Паттерны MCP-серверов Code Mode.
Предварительные требования
Вам понадобится:
- Проект с устойчивый runtime Code Mode настроено. Эта настройка предоставляет привязку Worker Loader и
CodemodeRuntimeэкспорт. - Существующее MCP-подключение Agents SDK. Чтобы создать и авторизовать подключение, обратитесь к McpClient API.
-
Установка Code Mode
Если в вашем проекте ещё нет Code Mode, установите
@cloudflare/codemode:npm i @cloudflare/codemode -
Создайте MCP-коннектор
Создайте коннектор в отдельном файле. Это обычный класс без специального имени файла или синтаксиса импорта.
src/github-connector.jsimport { 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.tsimport { 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. Каждый метод вызывает исходный инструмент черезconnection.client.callTool().Коннектор преобразует названия инструментов MCP в допустимые идентификаторы JavaScript. Например,
list-pull.requestsстановитсяlist_pull_requests,3d-renderстановится_3d_render, а такжеdeleteстановитсяdelete_. Если два исходных имени дают один и тот же идентификатор, коннектор выбрасывает ошибку. ПереопределитеtoolName()чтобы устранить неоднозначность между этими инструментами.tool()hook декорирования получает каждый сгенерированный метод по его очищенному имени. В этом примере hook помечаетcreate_issueдля подтверждения. Durable-среда выполнения приостанавливается перед вызовом этого метода и возобновляет выполнение после подтверждения. -
Добавьте коннектор в среду выполнения
В своём Agent найдите существующее MCP-подключение и передайте его коннектору. Затем включите коннектор при создании рантайма Code Mode:
src/server.jsimport { 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.tsimport { 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), ], }); } }Дождитесь
codemodeRuntime(), затем передайтеruntime.tool()вашей модели какcodemodeинструмент. Снова дождитесь завершения работы хелпера, прежде чем вызывать методы подтверждения, отклонения, отката или сниппета. Это гарантирует, что восстановление MCP-соединений после гибернации завершилось.Если рантайм принадлежит
Thinkагента, не включайте инструменты 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пропускает автоматическую функцию ThinkgetAITools()вызов. Соединение MCP остаётся доступным дляMcpConnector. -
Позвольте модели самостоятельно находить и вызывать инструменты
Укажите модели использовать
codemode.search()иcodemode.describe()перед вызовом незнакомых методов. Сгенерированный моделью код в sandbox может затем обнаружить и вызвать сгенерированные методы: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()возвращает ранжированные методы коннектора.codemode.describe()возвращает документацию TypeScript для коннектора или метода. Это позволяет модели загружать детали инструмента только тогда, когда это нужно.
Когда модель вызывает github.create_issue(), среда выполнения возвращает приостановленное выполнение. Подтвердите это выполнение через среду выполнения, чтобы выполнить MCP-инструмент и продолжить ту же программу песочницы.
Используйте набор инструментов AI SDK
Для более простой интеграции без устойчивых подтверждений или 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,
});Этот подход предоставляет доступ к MCP-инструментам под стандартным codemode пространство имён. Оно не использует устойчивый механизм паузы, подтверждения и возобновления рантайма коннектора. Используйте McpConnector когда инструменты могут вызывать побочные эффекты или когда модели требуется обнаружение по запросу.
getAITools() преобразует входные и выходные схемы MCP для использования в AI SDK. Agents SDK повторно использует эти преобразованные схемы, при этом каждое активное подключение сохраняет один и тот же актуальный каталог. Используйте this.mcp.listTools() вместо этого, если вам нужно только просмотреть необработанный каталог MCP.