mcpField
M
mcp-code-execution

mcp-code-execution

github.com/laurigatesAgent 工作流5936 次安装2 天前更新
代码仓库

关于 mcp-code-execution

mcp-code-execution 是一项指导如何通过生成代码与 MCP 服务交互的技能,适用于需要处理大量工具或大型结果的 Agent。内容涵盖按需发现工具、沙盒执行、结果筛选、敏感数据处理和状态复用。

主要功能

  1. 01渐进式工具发现
  2. 02TypeScript/Python 类型化封装
  3. 03沙盒代码执行
  4. 04在结果进入上下文前筛选
  5. 05PII 标记化与状态持久化
  6. 06跨运行复用技能

适用场景

  1. 01协调多个 MCP 服务及大量工具
  2. 02处理大型中间结果,避免载入上下文
  3. 03在工具调用间运行循环、重试和条件逻辑
  4. 04在系统间传递 PII,同时避免其进入模型上下文

MCP 相关

介绍一种通过类型化封装和客户端发现并调用 MCP 服务工具的 Agent 架构。代码在沙盒中运行,筛选后的结果再返回给 Agent。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/laurigates/claude-plugins --skill mcp-code-execution

安装后在 Claude Code 中输入/mcp-code-execution确认已加载。

详细介绍

MCP 代码执行模式

用于设计 Agent 系统的专业知识:这类系统生成并执行代码来与 MCP 服务交互,而不是直接调用工具。

何时使用此技能

在以下情况下使用此技能……在以下情况下改用 mcp-management……
设计需要跨 10+ 个 MCP 服务或 50+ 个工具进行扇出的 Agent在 .mcp.json 中安装或配置单个 MCP 服务
中间工具结果很大(>10K 个令牌),会撑爆上下文操作一两个服务,且每个结果都足够小,可以内联
工作流需要在工具调用之间使用循环、重试或条件判断执行一次性连接检查或线性的 2–3 次调用
必须确保 PII 不进入模型上下文工具响应不包含敏感数据

何时使用此模式

在以下情况下使用代码执行……在以下情况下直接调用工具……
连接到 10+ 个 MCP 服务或 50+ 个工具服务很少,工具也只有几个
中间结果很大(>10K 个令牌)结果很小,且模型需要所有结果
工作流需要循环、重试或条件判断线性的 2-3 次工具调用
必须确保 PII 不进入模型上下文工具响应中没有敏感数据
任务受益于跨运行的状态持久化无状态的一次性操作
希望 Agent 积累可复用技能固定的预定义工作流

核心架构

工作原理

Agent 不会预先将所有 MCP 工具定义加载到模型上下文中,而是会:

  1. 发现:通过浏览类型化文件树来发现可用工具
  2. 生成:生成导入并调用类型化封装函数的 TypeScript/Python 代码
  3. 执行:在沙盒环境中执行代码
  4. 返回:仅向模型返回经过筛选/汇总的结果

这样可将令牌用量从 O(所有工具定义) 降低到 O(仅相关导入项)。

文件树结构
project/
├── servers/
│   ├── google-drive/
│   │   ├── getDocument.ts
│   │   ├── getSheet.ts
│   │   ├── listFiles.ts
│   │   └── index.ts          # Re-exports all tools
│   ├── salesforce/
│   │   ├── query.ts
│   │   ├── updateRecord.ts
│   │   └── index.ts
│   └── slack/
│       ├── sendMessage.ts
│       ├── getChannelHistory.ts
│       └── index.ts
├── skills/                    # Agent-accumulated reusable functions
│   └── save-sheet-as-csv.ts
├── workspace/                 # Persistent state between executions
├── client.ts                  # MCP client that routes calls to servers
└── sandbox.config.ts          # Execution environment configuration
类型化封装模式

每个 MCP 工具都有一个类型化封装函数,供 Agent 导入:

// servers/google-drive/getDocument.ts
import { callMCPTool } from "../../client.js";

interface GetDocumentInput {
  documentId: string;
}

interface GetDocumentResponse {
  content: string;
}

/** Read a document from Google Drive */
export async function getDocument(
  input: GetDocumentInput
): Promise<GetDocumentResponse> {
  return callMCPTool<GetDocumentResponse>("google_drive__get_document", input);
}

然后,Agent 会编写代码,自然地使用这些封装函数:

import * as gdrive from "./servers/google-drive";
import * as salesforce from "./servers/salesforce";

const transcript = (
  await gdrive.getDocument({ documentId: "abc123" })
).content;

await salesforce.updateRecord({
  objectType: "SalesMeeting",
  recordId: "00Q5f000001abcXYZ",
  data: { Notes: transcript },
});

关键模式

1. 渐进式工具发现

Agent 按需浏览文件系统以查找相关工具,而不是预先加载所有定义。

Agent: "I need to read from Google Drive"
  → ls servers/
  → ls servers/google-drive/
  → cat servers/google-drive/getDocument.ts  (reads signature + JSDoc)
  → generates code importing only getDocument

令牌影响:令牌数从 150,000(所有定义)降至约 2,000(单个定义),减少 98.7%。

2. 高效利用上下文的数据筛选

在执行环境中筛选大型数据集,再将结果交给模型:

// Filter in the sandbox — only summary reaches the model
const allRows = await gdrive.getSheet({ sheetId: "abc123" });
const pending = allRows.filter((row) => row["Status"] === "pending");
console.log(`Found ${pending.length} pending orders`);
console.log(pending.slice(0, 5)); // Only first 5 for model review
3. 原生控制流

使用代码原生循环和条件判断取代串联的工具调用:

// Polling loop — runs entirely in sandbox
let found = false;
while (!found) {
  const messages = await slack.getChannelHistory({ channel: "C123456" });
  found = messages.some((m) => m.text.includes("deployment complete"));
  if (!found) await new Promise((r) => setTimeout(r, 5000));
}
console.log("Deployment notification received");
4. PII 令牌化

MCP 客户端会拦截响应,并在敏感数据到达模型之前将其令牌化:

// Agent writes this code
for (const row of sheet.rows) {
  await salesforce.updateRecord({
    objectType: "Lead",
    recordId: row.salesforceId,
    data: { Email: row.email, Phone: row.phone, Name: row.name },
  });
}
console.log(`Updated ${sheet.rows.length} leads`);

模型在执行输出中看到的内容:

[
  { salesforceId: "00Q...", email: "[EMAIL_1]", phone: "[PHONE_1]", name: "[NAME_1]" },
  { salesforceId: "00Q...", email: "[EMAIL_2]", phone: "[PHONE_2]", name: "[NAME_2]" }
]
Updated 247 leads

实际的 PII 会在外部系统之间流转,而不会进入模型上下文。

5. 状态持久化

将中间结果保存到工作区,以便在不同执行之间保持连续性:

// Execution 1: fetch and save
const leads = await salesforce.query({
  query: "SELECT Id, Email FROM Lead LIMIT 1000",
});
await fs.writeFile("./workspace/leads.csv", leads.map((l) => `${l.Id},${l.Email}`).join("\n"));

// Execution 2: resume from saved state
const saved = await fs.readFile("./workspace/leads.csv", "utf-8");
6. 技能积累

Agent 会将可复用函数持久化为技能,供后续执行使用:

// skills/save-sheet-as-csv.ts
import * as gdrive from "../servers/google-drive";
import * as fs from "fs/promises";

export async function saveSheetAsCsv(sheetId: string): Promise<string> {
  const data = await gdrive.getSheet({ sheetId });
  const csv = data.map((row) => row.join(",")).join("\n");
  const path = `./workspace/sheet-${sheetId}.csv`;
  await fs.writeFile(path, csv);
  return path;
}

后续执行可直接导入该技能:

import { saveSheetAsCsv } from "./skills/save-sheet-as-csv";
const csvPath = await saveSheetAsCsv("abc123");

搭建新项目

步骤 1:确定 MCP 服务

列出 Agent 需要交互的 MCP 服务。检查 .mcp.json 或项目的 MCP 配置:

cat .mcp.json 2>/dev/null || echo "No MCP config found"
步骤 2:生成服务目录

为每个 MCP 服务创建一个包含类型化封装函数的目录。每个工具都使用自己的文件,并包含:

  • 输入接口
  • 输出接口
  • 描述工具的 JSDoc 注释
  • 封装 callMCPTool 的异步函数
步骤 3:创建 MCP 客户端

客户端会将 callMCPTool 调用路由到相应的 MCP 服务:

// client.ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";

const clients = new Map<string, Client>();

export async function callMCPTool<T>(
  toolName: string,
  input: Record<string, unknown>
): Promise<T> {
  const serverName = toolName.split("__")[0];
  const client = clients.get(serverName);
  if (!client) throw new Error(`No MCP client for server: ${serverName}`);

  const result = await client.callTool({ name: toolName, arguments: input });
  return result.content as T;
}
第 4 步:配置沙箱

执行环境需要满足以下要求:

关注事项要求
隔离进程级或容器级沙箱
资源限制CPU 时间、内存上限、磁盘配额
网络仅允许连接 MCP 服务
超时每次运行均设定硬性执行时间限制
文件系统限定在 workspace/ 和 servers/ 目录内
监控记录所有执行和 MCP 调用
第 5 步:接入 Agent 循环

Agent 循环变为:

1. Receive user request
2. Agent explores servers/ tree to find relevant tools
3. Agent generates TypeScript code using typed wrappers
4. Code executes in sandbox
5. Filtered output returns to agent
6. Agent decides: done, or generate more code?

安全检查清单

项目状态
沙箱执行环境必需
资源限制(CPU、内存、磁盘)必需
网络隔离(仅允许 MCP 服务)必需
执行超时必需
在 MCP 客户端中对 PII 进行令牌化建议用于敏感数据
记录所有执行的审计日志建议
对 servers/ 进行只读访问建议
仅对 workspace/ 开放受限写入权限建议

Agentic 优化

场景方法
工具较多(50+)通过文件树逐步发现
中间数据较大在沙箱中筛选并返回摘要
多步骤工作流生成包含控制流的单个代码块
敏感数据管道在 MCP 客户端中启用 PII 令牌化
长时间运行的任务使用 workspace/ 持久化状态
重复操作提取到 skills/ 中以供复用

快速参考

令牌影响
方法工具定义中间数据总体
直接调用工具全部预先加载经过上下文高
代码执行按需发现保留在沙箱中低
不适用此模式的情况
  • 仅与 1-3 个 MCP 服务进行简单集成
  • 所有工具响应都很小,且模型都需要这些响应
  • 工具响应中不包含敏感数据
  • 基础设施复杂度不合理(沙箱设置、监控)
  • 原型或概念验证阶段
参考资料

评论

支持 Markdown