• #Claude
  • #Anthropic
  • #MCP
  • #AI
  • #エージェント
  • #コード実行

MCPでのコード実行:より効率的なエージェントの構築

公開日: 2025年11月4日

著者: Adam Jones、Conor Kelly

原文: Code Execution with MCP: Building More Efficient Agents

私の環境(Claude Code)で使えるか?

アプローチ適用可否備考
コード実行によるツールオーケストレーションClaude APIのベータ機能(code_execution)が必要
MCPサーバーのファイルシステム構成Claude Codeでは直接サポートされていない
PII自動トークン化カスタムMCPクライアント実装が必要
カスタムMCPサーバー作成自作MCPサーバーをClaude Codeに接続可能

結論

この記事で紹介されているコード実行アプローチの大部分は、Claude Codeでは直接利用できません

理由:

  1. Programmatic Tool Callingcode_executionツール)はClaude APIのベータ機能
  2. Claude Codeは従来の直接ツール呼び出し方式のみサポート
  3. MCPサーバーをファイルシステムとして公開する機能はない

唯一できること

カスタムMCPサーバーの作成は可能です。例えば:

  • 複数のツールをまとめた高レベルMCPサーバーを自作
  • データフィルタリングをサーバー側で行い、結果のみ返す
  • これにより間接的にトークン削減は実現可能

ただし、記事で説明されている「エージェントがコードを書いてツールをオーケストレーション」というパターンは使えません。


概要

この記事では、エージェントが直接ツール呼び出しではなくコード実行を通じてMCPサーバーとより効率的に連携する方法を探ります。

課題

エージェントが多数のMCPサーバーに接続する際に2つの主要な課題が生じます:

1. ツール定義のオーバーロード

すべてのツール定義を事前に読み込むと、コンテキストウィンドウの大部分を消費します。

「ツールの説明がコンテキストウィンドウをより多く占有し、応答時間とコストが増加する」

2. 中間結果の重複

エージェントがツールを順次呼び出すと、結果はモデルを複数回通過する必要があります。

たとえばGoogle Driveから会議の議事録を取得してSalesforceに添付する場合、議事録全体がコンテキストを2回通過し、長いドキュメントでは50,000トークン以上が追加される可能性があります。

解決策:コード実行アプローチ

ツールを直接関数呼び出しとして公開する代わりに、MCPサーバーをコードAPIとして提示します。エージェントはコードを書いてツールと対話し、オンデマンドのツール読み込みと環境内でのデータ処理によって両方の課題に対処します。

ファイルシステムアーキテクチャ

MCPツールをファイルシステムとして構成:

servers
├── google-drive
│   ├── getDocument.ts
│   ├── ... (他のツール)
│   └── index.ts
├── salesforce
│   ├── updateRecord.ts
│   ├── ... (他のツール)
│   └── index.ts
└── ... (他のサーバー)

実装例:ツールラッパー

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

interface GetDocumentInput {
  documentId: string;
}

interface GetDocumentResponse {
  content: string;
}

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 }
});

効率性の向上

「これにより、トークン使用量が150,000トークンから2,000トークンに削減され、98.7%の時間とコストの削減となる」

主要な利点

1. 段階的開示(Progressive Disclosure)

モデルはファイルシステムを自然にナビゲートし、すべてを事前に読み込むのではなく、オンデマンドでツール定義を読み取ります。

代替アプローチとして、エージェントが詳細レベル(最小限 vs 完全なスキーマ)を指定できるsearch_tools関数を実装することもできます。

2. コンテキスト効率的な結果

エージェントは実行環境内で大規模なデータセットをフィルタリングしてから、モデルに結果を返すことができます。

const allRows = await gdrive.getSheet
  ({ sheetId: 'abc123' });
const pendingOrders = allRows.filter(row =>
  row["Status"] === 'pending'
);
console.log(pendingOrders.slice(0, 5));

10,000行のスプレッドシートを処理する場合、モデルに返すのはフィルタリングされた5行だけになります。

3. 制御フロー

ループ、条件分岐、エラー処理がモデルの繰り返し呼び出しを必要とせず、コード内で実行されます。

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));
}

条件ロジックは反復的なモデル呼び出しを必要とせず、環境内で実行されます。

4. プライバシー保護

中間結果はデフォルトで実行環境内に留まります。システムは個人識別情報(PII)を自動的にトークン化し、データをモデルに公開することなくサービス間で流すことができます。

const sheet = await gdrive.getSheet
  ({ sheetId: 'abc123' });
for (const row of sheet.rows) {
  await salesforce.updateRecord({
    objectType: 'Lead',
    recordId: row.salesforceId,
    data: {
      Email: row.email,
      Phone: row.phone,
      Name: row.name
    }
  });
}

MCPクライアントはPIIをインターセプトし、モデルが見る前に[EMAIL_1][PHONE_1]のようなトークンに変換します。実際の値はモデルに公開されることなく、サービス間で直接流れます。

5. 状態の永続化

エージェントは中間結果をファイルに書き込むことができ、進捗追跡と再開可能なワークフローを可能にします。

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

// 後で読み込み
const saved = await fs.readFile
  ('./workspace/leads.csv', 'utf-8');

6. スキル開発

エージェントは動作するコード実装を再利用可能な関数として保存し、より高レベルな機能のツールボックスを徐々に構築できます。

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

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

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

実装上の考慮事項

このアプローチには、適切なサンドボックス化、リソース制限、監視を備えた安全なコード実行インフラストラクチャが必要です。

「エージェントが生成したコードを実行するには、適切なサンドボックス化、リソース制限、監視を備えた安全な実行環境が必要です」

これらの運用要件は、効率性の向上と比較検討する必要があります。

関連情報

記事ではCloudflareの並行した取り組みに言及し、LLMコード生成の利点に関する類似の洞察を指摘しています。MCPコミュニティとの実装共有も推奨しています。

結論

コード実行は複雑さを導入しますが、確立されたソフトウェアエンジニアリングパターンをエージェント開発に適用し、馴染みのあるプログラミング構造を通じてより効率的なMCPサーバー連携を実現します。