mcpField
A
A2A to MCP bridge

A2A to MCP bridge

ローカル
github.com/AmirK-SAI・エージェント28 週間前に更新

A2A to MCP bridge について

A2A to MCP bridgeは、設定したA2A v1.0.1エージェントをMCPツールとして公開し、MCPクライアントから呼び出せるようにします。メッセージ、タスク状態、コンテンツを変換し、引き継げない情報も明示します。

主な機能

  1. 01A2Aエージェントを発見
  2. 02メッセージを送信して返信を取得
  3. 03タスクの取得とキャンセル
  4. 04コンテンツとタスク状態を変換
  5. 05変換で失われる情報を明示

活用シーン

  1. 01MCPクライアントからA2Aエージェントを呼び出す
  2. 02設定済みエージェントの機能を確認
  3. 03複数段階のタスクを追跡
  4. 04不要になったタスクをキャンセル

MCP 対応

1つ以上のA2Aエージェントを、発見、メッセージ送信、タスク取得、キャンセル用のMCPツールとして公開します。新旧のMCPルートに対応し、新しいルートではtasks拡張を提供します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"amirk-s-a2a-to": {
"command": "npx",
"args": [
"-y",
"a2a-to-mcp"
]
}
}
}
起動コマンドnpx -y a2a-to-mcp

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npma2a-to-mcp0.1.0

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

a2a-to-mcp

A2A v1.0.1 エージェントを、io.modelcontextprotocol/tasks 拡張を備えたステートレスな MCP 2026-07-28 サーバー上で MCP ツールとして公開します。

エージェントカードを使って、ブリッジの接続先となる A2A エージェントを 1 つ以上指定します。Claude Code や Cursor を含むあらゆる MCP クライアントから、エージェントの検出、メッセージの送信、タスクの読み取り、タスクのキャンセルという 4 つの通常のツールが見えるようになります。ブリッジは、パーツ、アーティファクト、タスクの状態、エラーを 2 つのプロトコル間で変換し、変換できないものについては明示します。

サーフェス提供バージョン固定された依存関係
MCP、モダンルートセッションなし、リクエストごとの _meta を使用する server/discover 経由の 2026-07-28@modelcontextprotocol/server 2.0.0
MCP、レガシールート同じエンドポイントで initialize 経由の 2025-11-25同上
MCP タスク拡張スキーマ 2026-07-28 の io.modelcontextprotocol/tasks。モダンルートのみなし。ブリッジが提供
A2AJSON-RPC バインディングの 1.0(A2A-Version: 1.0)@a2a-js/sdk 1.1.0

Node 20 以降。Apache-2.0。

クイックスタート

npm install -g a2a-to-mcp

または、リポジトリから実行します。

git clone https://github.com/AmirK-S/a2a-to-mcp.git && cd a2a-to-mcp && npm ci && npm run build

ベース URL またはカード URL を使って、エージェントごとに 1 つのエイリアスを記述した agents.json を作成します。

{
  "agents": {
    "hello": { "url": "http://localhost:9999" },
    "planner": { "cardUrl": "https://planner.example.org/.well-known/agent-card.json" }
  },
  "port": 8931
}

実行します。

node dist/cli.js --config agents.json

ブリッジは http://127.0.0.1:8931/mcp で待ち受けます。設定で allowedHosts を指定しない限り、Host ヘッダーと Origin ヘッダーで受け付けられるのはループバックホストのみです。このバージョンでは、どちら側にも認証はありません。

Claude Code

プロジェクトのルートにある .mcp.json に追加します。これはブリッジの起動時に表示されるブロックです。

{
  "mcpServers": {
    "a2a-to-mcp": {
      "type": "http",
      "url": "http://127.0.0.1:8931/mcp"
    }
  }
}

Claude Code は v2 ランタイム以降、server/discover を通じて 2026-07-28 をネゴシエートします。これは2.1.232 から文書化されており、ここでは 2.1.263 で測定しました。古いバージョンでは initialize にフォールバックし、レガシールートで同じ 4 つのツールを利用できます。ブリッジに対する Claude Code セッションの完全な注釈付きトレース(検出、アーティファクトを含むタスク、エリシテーションの往復)は、docs/DEMO-CLAUDE-CODE.md にあります。ヘッドレスモード(claude -p)ではエリシテーションに応答する人がいないため、Claude Code がエリシテーションをキャンセルし、ブリッジが A2A タスクをキャンセルします。対話モードではユーザーに尋ねます。

Cursor

.cursor/mcp.json に追加します。

{
  "mcpServers": {
    "a2a": { "url": "http://localhost:8931/mcp" }
  }
}

Cursor は 2025-11-25 を使用し、同じエンドポイントの initialize を通じてサービスされます。

4 つのツール

複数のエージェントを設定している場合、各ツールでは最初の引数としてエージェントのエイリアスを指定します。エージェントが 1 つだけの場合はエイリアスを省略でき、そのエージェントがデフォルトになります。

ツール引数戻り値
a2a_discoveragent構造チェック後の、エージェントが提供したままのエージェントカード。structuredContent 内に格納され、テキストの要約とカード URL は _meta に含まれます
a2a_send_messageagent、text、contextHandle?、taskHandle?エージェントの応答。下記の結果コントラクトを参照
a2a_get_taskagent、taskHandle、historyLength?履歴を含むタスクエンベロープ
a2a_cancel_taskagent、taskHandleキャンセル要求後のタスクエンベロープ
ワイヤー上でのツール呼び出し

メッセージを渡す引数は text です。MCP クライアントが送信する、2026-07-28 ルートでの完全な tools/call は次のとおりです。

curl -sS http://127.0.0.1:8931/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2026-07-28' \
  -H 'Mcp-Method: tools/call' \
  -H 'Mcp-Name: a2a_send_message' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{
        "_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28",
                 "io.modelcontextprotocol/clientCapabilities":{}},
        "name":"a2a_send_message",
        "arguments":{"agent":"hello","text":"task: hello world"}}}'

最初のユーザーが犯しがちなミスを含む、公開 A2A エージェントを使った実行例は、docs/USAGE-REEL.md にあります。

結果の契約

各応答は CallToolResult であり、content に翻訳された部分が格納され、structuredContent は次のエンベロープになります。

{
  "kind": "task",
  "contextHandle": "cx_...",
  "taskHandle": "tk_...",
  "a2aState": "TASK_STATE_COMPLETED",
  "status": "completed",
  "note": "present when the mapping lost information",
  "artifacts": [{ "artifactId": "...", "name": "result" }],
  "data": {}
}

data には成果物の単一の A2A データパートが格納され、データパートがない場合、または複数ある場合は存在しません。history は a2a_get_task によってのみ追加されます。

kind は、直接の A2A メッセージの場合は message、エージェントがタスクを開始した場合は task です。ハンドルはブリッジが発行する不透明な文字列で、A2A 識別子ではありません。ブリッジのテーブルは隠しますが、エージェントが自身のメッセージに書き込む内容は隠しません。デフォルトでは、最後に使用してから 15 分間メモリ内に保持されます(handleTtlMs)。期限切れまたは不明なハンドルを渡すと、明示的なエラーが返されます。同じ会話を続けるには contextHandle を返し、エージェントが入力待ちのままにしたタスクに応答するには taskHandle を返します。

エージェントの失敗(FAILED、REJECTED、AUTH_REQUIRED)およびエージェントが未指定の状態のままにしたタスクは、ツール実行エラーです。isError: true が設定され、エージェントのテキストが content に、A2A の状態と注記がエンベロープに含まれます。型付き A2A エラー(コード -32001 から -32009)もツール実行エラーであり、コードは structuredContent.a2aErrorCode に含まれます。ブリッジが A2A エラーコードを JSON-RPC コードとして再出力することはありません。JSON-RPC は -32000 から -32099 をサーバー定義エラー用に予約しており、MCP はすでにこの範囲の -32020、-32021、-32022 を使用しています。A2A コードをこの範囲で再現すると、実際には持たない MCP の意味を持つかのように扱われてしまいます。

長時間実行されるタスク

tasks 拡張機能を使用する場合

リクエストごとの clientCapabilities.extensions で io.modelcontextprotocol/tasks を宣言するクライアントには、エージェントがタスクを開始するとすぐに a2a_send_message から CreateTaskResult が返され、その後 tasks/get をポーリングします。また、tasks/update や tasks/cancel を呼び出すこともできます。カードがストリーミングを通知した場合、ブリッジはバックグラウンドで SendStreamingMessage を処理し、それ以外の場合は GetTask を処理します。

A2A TaskStatetasks/get の MCP TaskStatus失われる情報
SUBMITTEDworkingMCP には受理済みだが未開始の状態がありません。その旨は statusMessage で示されます
WORKINGworkingなし
INPUT_REQUIRED合成されたフォームによる 1 件のエリシテーションを含む input_requiredA2A は自由形式のテキストで要求しますが、フォームには文字列フィールドが 1 つだけあります
COMPLETEDresult に完全な CallToolResult を含む completedなし
FAILED、REJECTED、AUTH_REQUIREDresult.isError が true の completedエンベロープがなければ、拒否と認証要求を失敗と区別できません
CANCELEDcancelledなし。スペルに注意してください
指定なしresult.isError が true の completedA2A はライフサイクル状態をまったく送信していません。ブリッジが推測することはありません
ブリッジがタスクに到達できなくなった場合JSON-RPC の error を含む failed。A2A コードは error.data に格納されます

AUTH_REQUIRED は意図的に input_required にマッピングしていません。MCP では認証情報のフォームエリシテーションが禁止されており、A2A は帯域外の認証を要求するためです。通常、アクセス先の URL が記載されるエージェントのテキストは、結果として返されます。

この拡張機能は 2026-07-28 ルートでのみ提供されます。レガシールートでは、tasks/* は必要な機能を示す -32021 を返します。2026-09-06 時点で、このブリッジに対して測定した 2 つのクライアント、Claude Code と Cursor は、この拡張機能を宣言していません。このリポジトリのテストスイート、およびリクエストごとにオプトインするクライアントで動作が検証されています。

CreateTaskResult には、拡張機能で定義されているフィールドに加えて、空の content 配列も含まれます。これは、参照 SDK がすべての tools/call の結果を通常の結果スキーマに対して検証することへの回避策です(typescript-sdk issue 2637)。SDK がハンドラーを確認する前に tasks/get と tasks/cancel に -32601 を返すため(typescript-sdk issue 2598)、3 つの拡張機能メソッドはモダンルートで SDK の手前にある小規模なルーターによって提供されます。また、3 つを 2 つのレイヤーに分けると、実装にずれが生じる可能性があります。どちらの回避策も分離されており、SDK の移行後に削除される予定です。

拡張機能を使用しない場合

a2a_send_message は、エージェントが終端状態または中断状態に達するまで待機し、その場で応答します。INPUT_REQUIRED のままになったタスクは、次のように返されます。

  • elicitation を宣言するクライアントには、フォームエリシテーションを 1 件含む複数ラウンドトリップの input_required 結果として返され、その後、回答とともに呼び出しを再実行します。
  • それ以外のクライアントには、エンベロープに input_required が記載され、taskHandle が含まれる通常の結果として返され、その後、そのハンドルを使って回答を送信します。

ブリッジを通過するもの、しないもの

各部分:

A2A PartMCP コンテンツブロック
textTextContent
dataJSON を格納し、_meta でフラグ付けされた TextContent。タスクのアーティファクトにデータ部分が 1 つだけある場合は、structuredContent.data にも格納されます
urlfilename を名前、mediaType を mimeType とする ResourceLink
raw、画像または音声のメディアタイプbase64 の ImageContent または AudioContent
raw、その他のメディアタイプa2a://part/ URI の埋め込み Blob リソース

filename、アーティファクトの ID と名前、メッセージ ID、コンテキスト ID は、各ブロックの _meta["io.github.amirk-s/a2a"] を介して渡されます。

設計上、引き継がれないもの:プッシュ通知(MCP には Webhook がありません)、エージェントカードの署名、securitySchemes、ストリーミングイベントそのもの(タスクに集約されます)、ListTasks(ハンドルで代替されます)、および自由形式のテキストをスキルにルーティングする機能です。ブリッジは言語モデルを呼び出さず、ディスクにデータを保存することもありません。

適合性

スコアはその理由と合わせて確認してください。2026-07-28 の実行では、スコア対象の37シナリオのうち32シナリオで、少なくとも1つのチェックがグリーンではありません。29シナリオは失敗、3シナリオは警告のみです。19シナリオはテストスイートに記述されたツール名を呼び出し、13シナリオはプロンプト、リソース、または補完機能をテストしています。A2A エージェントへのブリッジでは、これらは宣言されません。logging はその中に含まれず、スコア対象となるのは 2025-11-25 のみです。テストスイートでは意図的に両方のシナリオ群を失敗として数え、回答として想定失敗のベースラインを示しています(modelcontextprotocol/conformance#248)。実行では、理由が記されたコミット済みベースラインにすべて含まれる67件の失敗チェックと5件の警告が記録されています。どちらのリビジョンでもテストスイートの終了コードは0で、ブリッジに適用されるプロトコルチェックはグリーンです。ワイヤースキーマ、server/discover、通知された機能とマウントされたハンドラーの一致、subscriptions/listen の確認応答、SEP-2243 ヘッダー、DNS リバインディング保護が該当します。数値は、以下のコマンドで再生成される conformance/REPORT.md に記載されています。

npm run conformance は、公式テストスイート @modelcontextprotocol/conformance の 0.2.0-alpha.11 を、2026-07-28 と 2025-11-25 向けに再実行します。すべての行に理由が記載された、想定失敗のベースラインが使用されます。レポートは conformance/REPORT.md にあります。

テストスイートで検証できること:ブリッジが送信するすべてのメッセージが、各リビジョンのスキーマに適合すること(両方のワイヤーで wire-schema-valid)、server/discover とステートレスワイヤーが正常に動作すること、SEP-2243 のヘッダー検証が適用されること、DNS リバインディング保護が有効であること。測定できないこと:テストスイート独自のフィクスチャーツールを名前で呼び出すシナリオと、tasks-* シナリオです。ブリッジがフィクスチャーのふりをしない限り、実際のエージェントを対象とするブリッジではこれらを満たせません。代わりに、タスク拡張機能はワイヤーを対象に記述された test/integration/tasks-extension.test.ts で、チェックごとに検証します。

開発

npm ci
npm test                 # unit and integration, in-process fixture agent, no network
npm run test:helloworld  # against the official A2A helloworld sample, see scripts/helloworld
npm run conformance      # official MCP suite, both revisions, baseline applied

fixtures/agent のフィクスチャーエージェントは、モデルを使用しない決定論的な A2A v1.0 エージェントです。そのコマンドでは、エージェントが意図的に報告できるすべてのタスク状態、2ターンの入力要求サイクル、キャンセル、4種類のパート、9種類の型付きエラーを操作できます。npx tsx fixtures/agent/cli.ts --port 41241 で単独実行できます。

メンテナンスと課題

課題とプルリクエストには7日以内に回答します。固定されたバージョンに関するバグ報告には対応します。新機能のリクエストには目を通して回答しますが、実装を約束するものではありません。今後追加される可能性のある拡張範囲として、A2A スキルごとに1つのツールを設けること、タスク通知を伴う subscriptions/listen、設定に基づく A2A 認証方式、逆方向の連携をここに記載しています。これらが暗黙に期待されることのないようにするためです。

サポート終了

いずれかのプロトコルの次のリビジョンで問題になる点は、docs/END-OF-LIFE.md に記載されています。バージョンは意図的に厳密に固定しています。docs/ETAT-FINAL.md には、初回リリース時点のプロジェクトの状態、つまり検証済みの内容、公開済みの内容、未解決で今後もそのままとなる内容が記録されています。

ライセンス

Apache-2.0。両プロトコルの仕様と A2A SDK も同じライセンスです。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。