1. 为什么你的 Agent 一接工具就变慢从 MCP 代码执行说起MCPModel Context Protocol是连接 AI Agent 与外部系统的开放标准它让开发者只需实现一次协议就能接入文件、数据库、搜索、CRM 等一整个工具生态。但很多人把十几个 MCP Server 接上之后会发现一个尴尬现象Agent 还没开始干活光是读工具定义就烧掉几万 token响应慢、成本高稍微大一点的中间结果还会直接把上下文窗口撑爆。这个问题的根源在于传统 MCP 客户端的交互方式把所有工具定义预先塞进上下文模型每调用一次工具请求参数和返回结果都要完整经过模型一次。一个两小时的会议记录可能在工具之间来回搬运两遍凭空多出几万 token。而 MCP 代码执行Code execution with MCP换了个思路——不再让模型直接调用工具而是让模型写代码把 MCP Server 当成代码 API 来用代码在沙箱里跑只有最终结果回到模型。这篇面向需要让 AI Agent 自主运行代码的开发者给出 MCP 服务端配置骨架、TaoToken 统一 Key 接入方式并完整演示一次 Agent 调用代码执行的验证流程。适合已经用过 MCP、但被上下文膨胀和成本问题卡住的同学也适合刚接触 Agent 工具编排、想搭一套可复现环境的新手。2. 前置准备TaoToken 统一 Key 与 MCP 运行环境在动手写代码执行服务端之前先把模型接入这一层理顺。MCP 代码执行对模型的代码生成能力要求较高建议用 Claude 系列或同级别的编码模型。TaoToken 提供统一的 API Key兼容 Anthropic 风格接口一个 Key 就能切换不同模型省去为每个模型单独配环境变量的麻烦。你需要准备三样东西一个可用的 API Key、Node.js 18 运行环境、以及一个支持 MCP 的客户端Claude Desktop、Cline、或自己写的 Agent 循环都行。先拿 Key。打开控制台创建密钥# 控制台创建 API Key https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_code_exec创建完成后把 Key 存到环境变量里不要硬编码进代码export TAOTOKEN_API_KEYsk-你的密钥 export TAOTOKEN_BASE_URLhttps://taotoken.net/api注意API 地址是https://taotoken.net/api不要在后面加多余路径SDK 会自动拼接/v1/messages之类的端点。如果你打算长期跑编码类 Agent可以顺手看一下 Coding Plan它针对高频代码生成场景做了额度优化# 长期编码 / Agent 场景 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_code_exec环境验证一步到位用 curl 确认 Key 能通curl https://taotoken.net/api/v1/messages \ -H x-api-key: $TAOTOKEN_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 64, messages: [{role: user, content: 回复 OK 两个字母}] }返回里能看到content字段带OK说明模型通道没问题。这一步别跳过后面 Agent 报错时你能快速判断是模型层还是 MCP 层的问题。3. MCP 代码执行服务端配置骨架核心思路是把每个 MCP 工具映射成一个可 import 的代码文件Agent 通过浏览文件系统按需发现工具而不是一次性加载全部定义。先建目录结构mkdir -p mcp-code-exec/servers/google-drive mkdir -p mcp-code-exec/servers/salesforce mkdir -p mcp-code-exec/workspace cd mcp-code-exec npm init -y npm install modelcontextprotocol/sdk写一个统一的 MCP 客户端桥接文件client.js所有工具文件都通过它调用真正的 MCP Server// client.js import { Client } from modelcontextprotocol/sdk/client/index.js; import { StdioClientTransport } from modelcontextprotocol/sdk/client/stdio.js; const clients new Map(); export async function getClient(serverName) { if (clients.has(serverName)) return clients.get(serverName); const transport new StdioClientTransport({ command: npx, args: [-y, modelcontextprotocol/server-${serverName}], }); const client new Client({ name: code-exec-bridge, version: 1.0.0 }); await client.connect(transport); clients.set(serverName, client); return client; } export async function callMCPTool(toolName, input) { const [server, tool] toolName.split(__); const client await getClient(server); const result await client.callTool({ name: tool, arguments: input }); return result.content; }接着为每个工具生成一个薄封装文件Agent 读这个文件就知道工具接口长什么样// servers/google-drive/getDocument.ts import { callMCPTool } from ../../client.js; interface GetDocumentInput { documentId: string; } interface GetDocumentResponse { content: string; } /* 从 Google Drive 读取文档内容 */ export async function getDocument( input: GetDocumentInput ): PromiseGetDocumentResponse { return callMCPToolGetDocumentResponse(google-drive__get_document, input); }再写一个index.ts做聚合导出方便 Agent 一行 import 拿到整个 server 的工具// servers/google-drive/index.ts export * from ./getDocument.js;到这里服务端骨架就成型了。关键点在于工具定义以文件形式存在磁盘上Agent 需要哪个就读哪个不需要的完全不进上下文。这跟传统 MCP 客户端把所有 schema 预加载进 system prompt 的做法token 消耗差了一个数量级。4. 让 Agent 写代码并执行完整验证流程现在演示一次真实调用。任务设定为从 Google Drive 读取会议记录过滤出待处理项写入本地 workspace。Agent 需要先探索文件系统发现工具再生成代码最后交给沙箱执行。第一步Agent 列出可用 server// Agent 生成的探索代码 import { readdir } from fs/promises; const servers await readdir(./servers); console.log(servers); // [google-drive, salesforce]第二步读取它需要的工具文件了解接口import { readFile } from fs/promises; const toolDef await readFile(./servers/google-drive/getDocument.ts, utf-8); console.log(toolDef);第三步生成业务代码并执行。注意这里做了数据过滤只有过滤后的结果才回到模型// Agent 生成的执行代码 import * as gdrive from ./servers/google-drive/index.js; import { writeFile } from fs/promises; const doc await gdrive.getDocument({ documentId: abc123 }); const lines doc.content.split(\n); const pending lines.filter((l) l.includes(TODO) || l.includes(待处理)); console.log(共 ${lines.length} 行待处理 ${pending.length} 项); console.log(pending.slice(0, 5)); await writeFile(./workspace/pending.txt, pending.join(\n));执行这段代码的沙箱入口可以这样写用 Node 的child_process起一个受限进程// sandbox.js import { spawn } from child_process; export function runInSandbox(code) { return new Promise((resolve, reject) { const child spawn(node, [--input-typemodule, -e, code], { cwd: ./workspace, timeout: 30000, env: { ...process.env, NODE_OPTIONS: --max-old-space-size256 }, }); let out ; let err ; child.stdout.on(data, (d) (out d)); child.stderr.on(data, (d) (err d)); child.on(close, (code) code 0 ? resolve(out) : reject(new Error(err)) ); }); }实测下来一个原本需要把上万行表格数据全部灌进上下文的场景用代码执行后模型只看到共 10000 行待处理 37 项加上前 5 行样本token 从十几万降到两千以内。这就是 MCP 代码执行最直接的收益数据在沙箱里流转模型只拿结论。5. 本篇常见报错与排查报错一Cannot find module ./servers/google-drive/index.js这是 ESM 路径问题。TypeScript 编译后.ts变.jsimport 时必须写.js后缀。检查你的tsconfig.json里module设为NodeNext并且所有相对导入都带扩展名。报错二MCP error -32000: Connection closed多半是 MCP Server 进程启动失败。先用命令行单独跑一次npx -y modelcontextprotocol/server-google-drive看是不是缺 API 凭证或包名写错。桥接层里getClient的command和args要和实际能跑通的命令完全一致。报错三沙箱执行超时但代码逻辑没问题检查spawn的timeout和NODE_OPTIONS内存限制。处理大文件时 256MB 可能不够调到 512MB 再试。另外确认cwd指向的 workspace 目录存在且有写权限。报错四模型返回的代码里 import 路径不对这是提示词问题。在 system prompt 里明确告诉模型工具文件位于./servers/server-name/导入时使用相对路径并带.js后缀。给一两个正确示例比反复纠错高效得多。报错五401 Unauthorized来自模型接口回到第 2 节用 curl 重新验证 Key。常见原因是环境变量没 export 成功或者 SDK 初始化时 base_url 写成了带尾斜杠的版本。接入文档里有各语言 SDK 的完整初始化示例# 接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_code_exec排查顺序建议固定为模型通道 → MCP Server 单跑 → 桥接层 → 沙箱 → 提示词。从下往上查能省掉大量来回试错的时间。6. 把 Key 和工具链固定下来让 Agent 真正跑起来代码执行这套模式跑通之后你会发现 Agent 的能力边界取决于两件事模型能不能写出正确的代码以及工具接口能不能被稳定发现。前者靠模型质量后者靠你的文件树组织。建议把常用的工具封装沉淀成skills/目录下的可复用函数Agent 第一次写对了之后直接 import 就行不用每次重新生成。模型侧的统一接入建议固定用一套 Key 管理避免多个供应商来回切换导致的环境混乱。需要新建或轮换密钥时走这里# API Keys 管理 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_code_exec想先在对话里验证模型对某段代码的理解和生成质量可以直接开模型对话试# 模型对话验证 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_code_exec如果你用的是 Claude Code 这类编码 Agent把 MCP 代码执行接进去之后它能在一次会话里自主完成「发现工具 → 写代码 → 沙箱执行 → 读结果 → 继续下一步」的闭环。配置方式参考# Claude Code 接入 https://taotoken.net/claude-code?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_code_exec最后留一个我踩过的坑沙箱里不要挂载生产数据库的直连凭证中间数据尽量在 workspace 内闭环敏感字段在进入模型上下文之前做标记化处理。代码执行带来效率的同时也放大了权限把执行环境和真实系统隔开是这套方案能长期跑下去的前提。
阅读完成 · 觉得有帮助?