mcp-code-execution について
mcp-code-executionは、生成コードを使ってMCPサーバーと連携するエージェント設計のスキルです。多数のツールや大きな結果を扱うための段階的な発見、サンドボックス実行、データ処理、状態の再利用を説明します。
主な機能
- 01段階的なツール発見
- 02型付きTypeScript/Pythonラッパー
- 03サンドボックスでのコード実行
- 04コンテキスト投入前の結果フィルタリング
- 05PIIのトークン化と状態の永続化
- 06実行をまたいだスキルの再利用
活用シーン
- 01多数のMCPサーバーとツールを使うワークフローの調整
- 02大きな中間結果をコンテキストに読み込まず処理
- 03ツール呼び出し間でループ、再試行、条件分岐を実行
- 04システム間でPIIを渡しながらモデルのコンテキストから除外
MCP 対応
型付きラッパーとクライアントを介して、エージェントがMCPサーバーのツールを発見し呼び出す構成を説明します。コードはサンドボックスで実行され、フィルタリング済みの結果がエージェントに返されます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ laurigates/ claude-plugins --skill mcp-code-executionインストール後、Claude Code で/mcp-code-executionを入力して読み込まれたか確認します。
詳細
MCP コード実行パターン
MCP サーバーと直接ツールを呼び出すのではなく、コードを生成して実行し、MCP サーバーとやり取りするエージェントシステムを設計するための専門知識です。
このスキルを使用するタイミング
| 次の場合にこのスキルを使用してください… | 次の場合は mcp-management を使用してください… |
|---|---|
| 10 個以上の MCP サーバーまたは 50 個以上のツールにまたがって処理を振り分けるエージェントを設計する | .mcp.json で単一の MCP サーバーをインストールまたは設定する |
| 中間ツールの結果が大きく(10K トークン超)、コンテキストを圧迫する | すべての結果をインライン化できるほど小さい 1〜2 個のサーバーを操作する |
| ツール呼び出しをまたいで、ループ、再試行、条件分岐が必要なワークフローを扱う | 1 回限りの接続確認、または直線的な 2〜3 回の呼び出しを行う |
| PII をモデルのコンテキストに含めてはならない | ツールの応答に機密データが含まれない |
このパターンを使用するタイミング
| 次の場合はコード実行を使用してください… | 次の場合はツールを直接呼び出してください… |
|---|---|
| 10 個以上の MCP サーバーまたは 50 個以上のツールに接続する | サーバーが少なく、ツールもわずかである |
| 中間結果が大きい(10K トークン超) | 結果が小さく、必要なものがすべてモデルに渡される |
| ループ、再試行、条件分岐が必要なワークフローを扱う | 2〜3 回のツール呼び出しによる直線的な処理である |
| PII をモデルのコンテキストに含めてはならない | ツールの応答に機密データが含まれない |
| タスクの実行間で状態を保持すると有益である | ステートレスな 1 回限りの操作である |
| エージェントに再利用可能なスキルを蓄積させたい | 固定された事前定義済みのワークフローである |
コアアーキテクチャ
仕組み
すべての MCP ツール定義をあらかじめモデルのコンテキストに読み込むのではなく、エージェントは次の処理を行います。
- 型付きファイルツリーをたどって、利用可能なツールを検出します
- 型付きラッパー関数をインポートして呼び出す TypeScript/Python コードを生成します
- サンドボックス環境でコードを実行します
- フィルタリングまたは要約した結果のみをモデルに返します
これにより、トークン使用量は 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 ツールには、エージェントがインポートする型付きラッパー関数があります。
// 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);
}
次にエージェントは、これらのラッパーを自然に使うコードを記述します。
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: "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 トークン(1 つの定義)に削減されます。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. スキルの蓄積
エージェントは、今後の実行で使えるよう、再利用可能な関数をスキルとして保持します。
// 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 サーバーを特定する
エージェントがやり取りする必要のある 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:エージェントのループを組み立てる
エージェントのループは次のようになります。
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/ のみに限定した書き込みアクセス | 推奨 |
エージェント型の最適化
| コンテキスト | アプローチ |
|---|---|
| ツールが多数(50 以上) | ファイルツリーを使った段階的な検出 |
| 中間データが大きい | サンドボックス内でフィルタリングし、要約を返す |
| 複数ステップのワークフロー | 制御フローを含む単一のコードブロックを生成 |
| 機密データのパイプライン | MCP クライアントで PII トークン化を有効化 |
| 長時間実行されるタスク | 状態の永続化に workspace/ を使用 |
| 繰り返し実行する操作 | 再利用できるよう skills/ に抽出 |
クイックリファレンス
トークンへの影響
| アプローチ | ツール定義 | 中間データ | 合計 |
|---|---|---|---|
| ツールを直接呼び出す | すべてを最初に読み込む | コンテキストを経由する | 高 |
| コード実行 | 必要に応じて検出 | サンドボックス内に留まる | 低 |
このパターンを使用しない場合
- MCP サーバーが 1~3 個の単純な統合
- すべてのツールの応答が小さく、モデルが必要とする
- ツールの応答に機密データが含まれていない
- インフラストラクチャの複雑さが妥当でない(サンドボックスのセットアップ、監視)
- プロトタイプまたは概念実証の段階
参考資料
- Anthropic Engineering:MCP を使ったコード実行
- Cloudflare「Code Mode」 — 同じパターンを独立して検証