はじめに
AIエージェントをつなぐ2つのオープン標準、MCP(Model Context Protocol) と A2A(Agent2Agent)プロトコル について、これまで9本の記事を書いてきました。外部ライブラリを使わない生実装と通信ログの実測で仕組みを調べる記事が8本、公式MCPサーバをクラウドに配置する検証記事が1本です。本記事では、MCP深掘りシリーズを「前作」、A2A深掘りシリーズを「本シリーズ」と呼びます。
MCP深掘りシリーズ(3本)と関連記事(1本):
- MCPサーバは「SDKなし100行」で作れる — Claude Codeとの通信を盗聴して中身を全部見てみた
- SDKなしでMCPのStreamable HTTPサーバを作って、仕組みを理解する
- 認可サーバごと自作して、MCPのOAuth 2.1フローを理解する
- GitHub公式MCPサーバを「無改変のまま」AWS Bedrock AgentCoreに載せてみた
A2A深掘りシリーズ(5本):
- A2AでAIエージェント同士はどう会話するのか?
- A2Aエージェントは時間のかかる依頼をどう処理するのか?
- A2Aエージェント同士をつなぐと何が起きるのか?
- A2Aのプッシュ通知はどう動くのか? — webhookで結果を受け取る
- 自作のA2Aエージェントは公式SDK製と会話できるのか? — 挙動差分と0.3系/1.0系の非互換
A2A深掘りシリーズでは毎回「MCPとの対比」の節を置き、前作のMCP深掘りシリーズの実測と突き合わせてきました。本記事はその締めくくりとして、「結局、どう使い分けるのか」を1本にまとめます。公式ドキュメントの説明をなぞるのではなく、実測で見えた違いを根拠にします。
本記事のゴール
次の3点を、根拠を添えて言えるようになることです。
- MCPとA2Aは競合ではなく、つなぐ相手が違う。MCPはエージェントとツール・データ、A2Aはエージェントとエージェントをつなぐことを主目的とする
- 両者の主要な違いは「状態をどこで管理するか」にある。MCP(2025-06-18版)は接続(セッション)で、A2AはTaskで管理する
- 使い分けは「相手に決まった入出力があるか」「1回の応答で終わるか」「呼ぶ側は何か」の3つの問いで決まる。実運用では両方を組み合わせて使う
注意: 本記事の比較は、MCPは旧版(2025-06-18版)を基準にしています
MCPは2025-06-18版の仕様、A2Aはv1.0の仕様を基準に比較します。どちらも、前作と本シリーズで実装と実測の基準にしたバージョンです。ただし、MCPの現行の仕様は2026-07-28版で、2025-06-18版から設計が大きく変わっています。本記事の表や説明をそのまま現行版に当てはめると食い違う箇所があります。何が変わったかは「MCPの現行版(2026-07-28)では前提が変わる」の節でまとめて扱います。
一言で言うと何が違うのか
A2Aの公式ドキュメントにあるMCPとの関係を説明するページは、こう整理しています。MCPはエージェントがツールやデータを使うためのプロトコルで、相手は「決まった入出力を持ち、多くの場合は状態を持たない機能」です。一方、A2Aはエージェントが別のエージェントに仕事を依頼するためのプロトコルで、相手は「中身が見えず(opaque)、自分で判断して仕事を進める相手」です。同じページでは、MCPを1つのエージェントの能力を深める縦方向の接続、A2Aをエージェント同士を横につなぐ横方向の接続と表現しています。
もう少し具体的に言うと、違いは「相手に何を渡し、何が返ってくるか」に現れます。MCPでは、ツールごとに入力の型がJSON Schema(inputSchema)で決まっていて、呼べば1回の応答で結果が返ります。A2Aでは、依頼はMessage(自然文でも構造化データでも渡せます)で、返ってくるのはMessageによる即答か、Taskです。Taskの場合は「受け付けました」という状態から始まり、完了するまでに時間がかかったり、途中で聞き返されたり、断られたりすることがあります。A2Aの公式ドキュメントは、この性質を次のように言い表しています(原文)。
Still, A2A's main strength is its support for flexible, stateful, collaborative interactions that go beyond a typical tool call.
(それでも、A2Aの主な強みは、典型的なツール呼び出しの範囲を超えた、柔軟で、状態を持ち、協調的なやり取りを支えることにある)
この一文に、A2Aが何のためのプロトコルかが端的に表れています。
何が同じなのか
違いに入る前に、共通点を押さえておきます。2つのプロトコルの土台はほとんど同じです。
| 観点 | MCP | A2A |
|---|---|---|
| メッセージの形式 | JSON-RPC 2.0 | JSON-RPC 2.0(gRPC、HTTP+JSONも選べる) |
| HTTPでの運び方 | HTTP POST。応答をSSEに格上げできる | HTTP POST。応答をSSEに格上げできる |
| サーバからクライアントへの送信 | セッション内のSSEストリームに流す | SSEまたはwebhook(プッシュ通知)で送る |
| 多段の連携 | MCPサーバが別のMCPサーバのクライアントになる | A2Aエージェントが別のエージェントのクライアントになる |
| 認証 | OAuth 2.1(HTTPの場合) | Agent Cardで宣言(OAuth2、OpenID Connect、APIキー、mTLSなど) |
JSON-RPC 2.0でメソッドを呼び、HTTP POSTで運び、必要ならSSEで流す、という考え方は共通しています。
運営も、今では同じ傘の下にあります。成り立ちは別で、MCPは2024年11月にAnthropicが、A2Aは2025年4月にGoogleが発表しました。A2Aは2025年6月にLinux Foundationへ移管され、2026年8月にはその傘下のAgentic AI Foundation(AAIF)に加わりました(公式ブログ)。AAIFにはMCPも所属しており、同じ組織が2つのプロトコルを、役割を分けたまま運営しています。
何が違うのか
共通の土台の上で、何が違うのか。両方を実測して確かめた違いを1つの表にまとめます。
| 観点 | MCP(2025-06-18版) | A2A(v1.0) | どの記事で実測したか |
|---|---|---|---|
| 接続先(クライアントが呼び出す相手) | ツール・リソース・プロンプト(決まった入出力を持つ機能) | エージェント(中身が見えない自律的な相手) | 両シリーズ全体 |
| 接続先の情報を得る手順 | 接続してから initialize で能力を交渉し、tools/list で一覧を取る |
接続する前に /.well-known/agent-card.json を読む。往復の交渉は無く、クライアントがAgent Cardの内容から選ぶ |
MCP第1回、A2A第1回・第5回 |
| 接続先が提供する機能の記述方法 | ツールごとに inputSchema(JSON Schema)で入力の型を定義 |
Agent Cardの skills に説明文・キーワード(tags)・入力例(examples)・扱えるメディア種別(inputModes / outputModes)。JSON Schemaのように入力の構造を定めるフィールドは無い |
MCP第1回、A2A第1回 |
| 作業の単位 |
tools/call の1往復。呼べば結果が返る |
Task。受付、作業中、中断、完了などの状態を持ち、完了まで時間がかかる依頼にも対応できる(すぐ終わる依頼はMessageで即答もできる) | A2A第2回 |
| 処理の進捗状況の伝え方 |
progressToken による進捗通知(進み具合の数値とメッセージ)。呼び出した接続の上を流れ、切断時の再送はサーバの任意機能。呼び出しの状態を後から問い合わせる手段は無い |
Taskの状態更新(statusUpdate)と成果物の更新(artifactUpdate)。切断後もGetTaskで取り直せる |
A2A第2回 |
| 追加入力(聞き返し。処理の途中でサーバが利用者に情報を求めること) |
elicitation。サーバがクライアントへid付きのリクエスト elicitation/create を送り、求める入力の型をJSON Schemaで指定する。クライアントは利用者に入力してもらい、accept / decline / cancel のいずれかと入力内容を応答として返す |
Taskを INPUT_REQUIRED 状態にする。クライアントが新しいMessageで再開する。入力の型は指定できない |
A2A第2回・第4回 |
| 成果物 | ツール結果の content に本文と同居 |
Artifactとして、連絡(Message)と型で分離 | A2A第2回 |
| 結果の受け取り方 | 同期の1応答(進捗はセッション内の通知) | ブロッキング、即時応答してポーリング、SSE、webhookから選択 | A2A第2回・第4回 |
| 状態の置き場所 | セッション(Mcp-Session-Id で識別される接続) |
Task(taskIdで識別され、接続とは独立) | MCP第2回、A2A第2回 |
| プロトコルバージョンの合わせ方 |
initialize で往復して交渉する |
Agent Cardに書かれたバージョンからクライアントが選び、A2A-Version ヘッダで申告する。合わなければエラー |
MCP第2回、A2A第5回 |
| 多段連携での状態の中継 | 標準の作業状態が無いので、上流は下流の進捗数値しか使えない | 作業状態の値(TASK_STATE_*)が標準なので、上流は下流の状態を見て自分の状態を決められる |
A2A第3回 |
表の右端の列に書いたとおり、これらは仕様書を読んだだけの比較ではなく、実際に動かして通信ログで確かめた差です。
主要な違いは「状態をどこで管理するか」
表の中で、設計としていちばん大きな違いは「状態をどこで管理するか」です。
MCPは状態を接続(セッション)で管理します。クライアントは接続してから initialize で能力を交渉し、そのセッションの中でツールを呼び、進捗通知もelicitation(追加入力の要求)もそのセッションの上を流れます。前作の第2回で実測したとおり、セッションは Mcp-Session-Id ヘッダで識別され、サーバがそのIDを忘れれば(404を返せば)クライアントは initialize からやり直します。接続の中に会話の文脈がある、という設計です。
A2Aは状態をTaskで管理し、接続には文脈を持たせません。Taskはサーバが採番したIDを持ち、接続とは独立に存在します。したがって、途中経過をSSEで受けても、webhookで受けても、ポーリングで取っても、それらは同じTaskの状態を別の経路で見ているだけです。接続が切れても、taskIdを指定して GetTask を送れば、そのTaskの現在の状態を取り直せます。A2Aシリーズの第2回で「状態の正はTaskにある」と書き、第4回で「通知は見に行くきっかけとして使い、正式な状態はGetTaskで取り直す」と書いたのは、この設計があるからです。
どう使い分けるのか
A2Aの公式ドキュメントは、2つのプロトコルの違いを次の一文で言い表しています(原文)。
A2A is about agents partnering on tasks; MCP is more about agents using capabilities.
(A2Aはエージェントが仕事で協力し合うためのもの、MCPはエージェントが能力を利用するためのもの)
「協力し合う相手」か「利用する能力」か。使い分けの出発点はこの1文で足りますが、実際の設計では境目が曖昧な場面が出てきます。そこで、ここまでの違いを、設計の場面で使える判断基準に落とします。相手をMCPサーバとして作るか、A2Aエージェントとして作るか(あるいは既存の相手をどちらで呼ぶか)を決めるとき、次の3つの問いで判断できます。
問い1: 入力と出力の形が決まっているか。 「都市名を渡すと天気が返る」「SQLを渡すと結果が返る」のように、渡すものと返ってくるものをあらかじめ項目として決められるなら、それはツールです。MCPではその形を inputSchema(JSON Schema)として書き、呼ぶ側のLLMが引数を組み立てられます。逆に「この資料を要約して、足りない情報があれば聞いてほしい」のように、依頼が自然文になり、相手が何をどう進めるかを相手の判断に任せるなら、それはエージェントへの依頼であり、A2Aの方が適しています。A2AのAgent CardにはJSON Schemaのように入力の構造を定めるフィールドが無く、説明文・キーワード・入力例・扱えるメディア種別を書くだけなのは、この前提に立っているからです。
問い2: 呼び出しは1回の応答で終わるか。 数秒で結果が返るならMCPの tools/call で十分です。数分かかる、途中で人の確認が要る、断られることがある、成果物が複数できる、という仕事なら、Taskという単位で状態を追えるA2Aのほうが素直に書けます。MCPでも progressToken で進捗は流せますが、それは接続内の通知で、切断後の再送は任意機能です。「今どの状態か」を後から問い合わせる標準の手段は、2025-06-18版にはありません。
問い3: 呼ぶ側は何か。 これは実務上いちばん効く問いです。Claude Code、GitHub Copilot(VS Code)、ChatGPT、Cursor、Gemini CLI といったLLMホストは、公式ドキュメントのとおりMCPサーバに接続する機能を持っています。一方、これらがA2Aクライアントとして直接A2Aエージェントに依頼を送る機能は、上記の公式ドキュメントには見当たりません(2026年9月時点で筆者が確認した範囲です)。つまり、LLMホストから直接呼びたい相手は、時間がかかる仕事であってもMCPサーバとして用意する必要があります。A2Aエージェントとして作ったものをLLMホストから使うには、間にA2Aクライアントを内蔵したMCPサーバをブリッジとして配置することになります。逆に、呼ぶ側(クライアント側)を自分で開発するなら、A2Aクライアントを組み込めるので、相手をA2Aエージェントにできます。
実際には組み合わせて使う
使い分けと言っても、どちらか一方を選ぶ話ではありません。A2Aの公式ドキュメントにある自動車修理工場の例がそのまま典型で、1つのエージェントが両方を同時に話します。
顧客は店長エージェントにA2Aで依頼し、店長は整備士エージェントにA2Aで作業を頼みます。整備士はその仕事を進めるために診断機やマニュアルDBをMCPで使い、部品が要れば部品サプライヤーのエージェントにA2Aで注文します。A2Aはエージェントを横につなぎ、MCPは各エージェントを自分の道具につなぐ。 整備士エージェント1体が、店長に対してはA2Aサーバ、道具に対してはMCPクライアント、サプライヤーに対してはA2Aクライアント、という3つの役割を同時に持ちます。
なお、A2Aの公式ドキュメントには「A2AエージェントをMCPのリソースとして表現する」という項目もあります。A2Aエージェントが持つskillsのうち、ツールのように状態を持たず1回の呼び出しで済むものを、MCP互換のリソースとして公開できる、という使い方です。MCPしか話せないLLMホストからA2Aエージェントの能力の一部を使う手段になりますが、本記事では試していません。機会があれば実際に動かして、別の記事にします。
MCPの現行版(2026-07-28)では前提が変わる
本記事の比較は、前作で実測したMCPの2025-06-18版を基準にしています。MCPの現行の仕様である2026-07-28版では、この基準にした設計が大きく変わりました(変更履歴)。本記事の表や説明を現行版に当てはめて読むと食い違う箇所があるので、主な変更点を挙げておきます。
- プロトコルレベルのセッションと
Mcp-Session-Idヘッダが無くなりました。initializeの握手も無くなり、プロトコルバージョンとクライアントの能力は毎リクエストの_metaに載せて申告します。事前に相手を知るためのserver/discoverというメソッドが追加されました - サーバからクライアントへリクエストを送る形(elicitationなど)が無くなり、代わりにサーバが
resultType: "input_required"の結果を返して、クライアントが情報を足して同じリクエストを送り直す形(Multi Round-Trip Requests)になりました - 2025-11-25版で実験的に入ったTasksは、公式拡張(
io.modelcontextprotocol/tasks)に移り、結果を待ち受ける方式からtasks/getでポーリングする方式に変わりました - SSEの再開と再送(
Last-Event-ID)は削除され、切れたら新しいリクエストとして送り直すことになりました
本記事の表で言えば、「接続先の情報を得る手順」「追加入力」「処理の進捗状況の伝え方」「状態の置き場所」「プロトコルバージョンの合わせ方」のMCP側のセルが、現行版では当てはまりません。並べてみると、接続に状態を持たせない、事前に相手を知る、聞き返しはリクエストではなく結果の状態で表す、進捗は取りに行く、という方向で、本記事でA2Aの設計として説明した内容にMCP自身が寄っています。長時間の仕事や切断への強さという要求が、MCPの側にも来た結果だと読めます。ただし「接続先がツールかエージェントか」という出発点の違いは変わっていません。
どちらもプロトコルバージョンの確認が必要
「MCP対応」「A2A対応」と書かれていても、バージョンが合わなければつながりません。A2Aシリーズの第5回で実測したとおり、A2Aプロトコル仕様の0.3系と1.0系はメソッド名の定義自体が異なり、片方の形式で送った依頼はもう片方に断られます。例えばAWSのStrands Agentsは、2026年9月時点の最新版でもA2A機能の依存を a2a-sdk<0.4.0(0.3系)に固定しています。一方、公式SDKには0.3系のリクエストも受け付ける互換モードを持つものがあります(@a2a-js/sdk の legacyCompat。第5回で確認)。
MCPも同じです。2025-03-26版でHTTPのトランスポートが変わり(HTTP+SSEからStreamable HTTPへ)、2026-07-28版ではセッションと initialize そのものが無くなりました。製品やサービスにどちらかの「対応」を求めるなら、プロトコルバージョンまで明示する必要があります。
まとめ
- MCPはエージェントとツール・データをつなぐ。A2Aはエージェントとエージェントをつなぐ。競合ではなく、つなぐ相手が違う
- 土台(JSON-RPC 2.0、HTTP、SSE、OAuth系の認証)はほぼ同じ。違いは上に載る約束事にある
- 主要な違いは「状態をどこで管理するか」。MCP(2025-06-18版)は接続(セッション)で、A2AはTaskで管理する
- 使い分けは3つの問いで決まる。入力と出力の形が決まっているか、1回の応答で終わるか、呼ぶ側はLLMホストかエージェントか
- 実運用では、用途に応じて、両者を使い分ける
- MCPもA2Aも、標準仕様の更新が速い。MCPは2026-07-28版でセッションと
initializeを無くすなど設計が大きく変わり、A2Aは0.3系と1.0系に非互換がある。「MCP対応」「A2A対応」とあっても、どのバージョンかまで確かめる必要がある