Skip to content

Code Mode — 将 30+ 个 MCP 工具收拢为一个安全的 execute_code

状态: 已在 @wasmagent/mcp-server@0.3(S1/A1,2026-06)发布。 其设计参考了 2026 年多个项目独立汇聚的同一模式:Cloudflare 的 Code Mode MCP server(InfoQ, 2026-04)、Red Hat codemode-lite(next.redhat.com,2026-04),以及 Anthropic 的 "code execution with MCP" 指南。

为什么需要 code-mode

当 MCP 宿主(Claude Code、Cursor、Copilot……)连接到一个发布了 30+ 个工具的服务时,每个工具的名称、描述和 JSON schema 都会进入模型的 prompt——即使模型从来不会调用其中大部分工具。Codemode-lite 实测,仅凭将这些工具收拢到一个 run_python 入口、并让模型按需 JIT 获取文档,就能节省 53% 的 token

wasmagent-js 的 code-mode 把那个单一的 run_python(仅 Red Hat 在自己的 gVisor 容器内运行)替换为任意 wasmagent Kernel——QuickJSKernelPyodideKernelWasmtimeKernelRemoteSandboxKernel。同一套 CapabilityManifest(allowedHosts / allowedReadPaths / allowedWritePaths / env / cpuMs / memoryLimitBytes)在任何语言和隔离层级上的沙箱行为完全一致。

你要交付的代码

ts
import { JsKernel, ToolRegistry } from "@wasmagent/core";
import { QuickJSKernel } from "@wasmagent/kernel-quickjs";
import { createCodeModeServer, createFetchHandler } from "@wasmagent/mcp-server";

const tools = new ToolRegistry();
tools.register({ name: "search_docs", /* … */ });
tools.register({ name: "read_file", /* … */ });
// …还有 40 个工具…

const server = createCodeModeServer({
  serverInfo: { name: "my-code-mode", version: "1.0.0" },
  tools,
  // QuickJSKernel 适合 edge 安全执行;需要完整进程隔离时
  // 可换用 RemoteSandboxKernel(E2B / Cloudflare Sandbox)。
  kernel: new QuickJSKernel({ timeoutMs: 5_000 }),
  capabilities: {
    allowedHosts: ["api.example.com"],
    allowedReadPaths: ["/workspace"],
    cpuMs: 5_000,
    memoryLimitBytes: 64 * 1024 * 1024,
    env: { OPENAI_API_KEY: process.env.OPENAI_API_KEY ?? "" },
  },
});

// 挂载到 HTTP——兼容 Node、Bun、Workers。
export default { fetch: createFetchHandler(server, { path: "/mcp" }) };

宿主现在只看到两个工具,而不是四十个:

  • docs_search(query?, names?) — JIT 按需拉取下游工具的类型签名和描述。默认不包含 input schema;传入 includeSchemas: true 可将其内联。
  • execute_code({ code }) — 在 kernel 中运行一段 JS 代码片段。片段可以通过 callTool(name, args) 调用任意已注册工具;只有片段的最终返回值会通过网络传输。

Token 数学

以下数据来自 examples/benchmarks/code-mode-tokens.mjs(离线计量模型,2026-06):

工具数量 N直接 MCPCode-mode比率节省
10153047431.0%69.0%
30349047413.6%86.4%
100103504744.6%95.4%

具体数字取决于你的工具 docstring 长度和宿主的前缀缓存命中率。规律才是重点:直接 MCP 的启动开销是 O(N),code-mode 是 O(1)。

安全策略接口

每个 kernel 都遵循同一套 CapabilityManifest。矩阵 (core.executor.types.ts)记录了 各字段在每个 kernel 中是原生强制执行还是尽力而为:

字段JsKernelQuickJSKernelPyodideKernelWasmtimeKernelRemote
allowedHosts
allowedReadPaths✅ (fs†)✅ (fs†)✅ (fs†)
allowedWritePaths✅ (fs†)✅ (fs†)✅ (fs†)
env
cpuMs✅ (timeout)✅ (deadline)✅ (deadline)✅ (deadline)✅ (per-call)
memoryLimitBytes⚠️ best⚠️ best

† WASM kernel 中的 FS 访问通过显式 __fs__ 桥接落到宿主,每次调用都会重新对照同一份白名单进行校验。

什么时候不该用 code-mode

  • 工具数量 < ~10:启动阶段节省的 token 太少,不值得承担 JIT 文档的往返延迟。直接用 MCP 即可。
  • 工具返回值是富对象且你希望模型直接看到原始内容:在 code-mode 中,模型只能看到 execute_code 的最终返回值,因此"先看这个对象,再决定"的多步工作流可能比工具/结果链更难引导。有时 PTC(ProgrammaticOrchestrator)更合适——思路相同,但脚本本身就是 agent 的主循环,而不是众多工具之一。
  • 你已经在为工具/结果往返付费,因为你需要让模型看到历史记录:code-mode 会隐藏中间步骤。

参见

Released under the Apache-2.0 License.