リモートMCPがやってくる、そしてA2Aについて
先日 Streamable HTTP Transportに対応したMCP TypeScript SDK 1.10.0がリリースされました。これは、以前のSSE Transport(2024-11-05)を置き換えるものです。Python SDK(最新バージョン1.6.0)にはまだこの更新が含まれていないようです。
Streamable HTTP Transport
従来のMCPでは、クライアントがサーバーに継続的に接続(標準入出力やSSE)してセッションを維持する必要がありました[1]。新しいStreamable HTTP Transportでは、クライアントがサーバーに1回のHTTP POSTリクエストを送るだけでセッションを開始できます。
また、サーバーからクライアントへリアルタイムでデータを送信(プッシュ)したい場合、Server-Sent Events(SSE)をオプションとして利用できます。これはサーバーからクライアントへの要求が発生する、Sampling仕様を実装したい時には必要です。
サンプルコードや実装例については、azukiazusaさんによる記事「MCP サーバーの Streamable HTTP transport を試してみる」が参考になります。ここではNode.jsとExpressでStreamable HTTP Transportを使う例があります。

ステートレスモードとCloudflareのAgents SDK
Streamable HTTP Transportではステートレスモードが追加され、セッションを確立せずにリクエストごとに独立した関数としてエンドポイントを動作させることができます。これは、サーバーレスプラットフォーム(例:AWS Lambda、Vercel)でのリモートMCPサーバーをデプロイする時などに使えます。
従来のリファレンス実装では、セッションごとにTransportオブジェクトをインスタンス化し、サーバープロセス内で保持していました。このオブジェクトはリクエスト間で再利用され、セッション状態を管理します。しかし、マルチプロセス環境やサーバーレス環境では、プロセス間でTransportオブジェクトを共有できないため、セッションの紐付けが困難でした。これを解決するには、外部ストレージ(例:データベース)や永続化メカニズムでTransportオブジェクトを保存する必要がありました
ところでCloudflare Workersでは別のアプローチが取られていました。CloudflareのAgents SDKのMCPサーバーサポートでは、Durable Objectsを活用してセッションごとのTransportオブジェクトを永続化します。Durable Objectsは、セッションごとの状態を一意のオブジェクトに割り当て、プロセス間で一貫性を保ちます。
またStreamable HTTP TransportはNode.jsサーバーを想定しているのですが、Request/ResponseオブジェクトなどCloudflare Workersの環境との差異があります。これを吸収して変換するレイヤーもAgent SDKに含まれています。

しかも最近Cloudflare Workersの無料プランからDurable Objectsが利用できるようになりました(気前がいい)。これでリモートMCPサーバーの構築がより手軽になります。
Agents SDKはMCP TypeScript SDKのラッパーを提供しており、McpAgentを通じて構築します。筆者は普段使っているスクレイピングツールを試しにリモートMCPサーバー化してVS Codeから試しました(これは試作版でありセッション対応をしていないので複数ユーザーで使えるコードではないです)。

一方、VercelやAWS Lambdaのように、Durable Objectsのようなネイティブの永続化メカニズムを持たないプラットフォームでは、開発者が自前で状態管理を実装する必要があります(例:Redis、DynamoDB)。しかし、ステートレスモードではこの永続化が不要なため、こうしたプラットフォームでのデプロイが簡素化されます。
moritalousさんによるAWS Lambdaのサンプルが以下にあります。ここで活用されているのもステートレスモードです。
ステートレスモードは、セッション管理を省略するため、認証を必要としないMCPサーバーに適しています。ただし、クライアントを実装する前提なら認証を必要とする場合でもステートレスモードは利用可能です。たとえば、サーバーで発行したJWTのアクセストークンをリクエストごとに含めることで、セッションを保持せずに認証を実現できます。
以上の更新は、将来的に想定されるリモートMCPサーバーのユースケースやスケーリング問題に対応した形です。なのでこれからリモートMCPの活用を考えてゆくフェーズになるかと思います。
A2Aはどうですか?
標準化プロトコルといえば、先日GoogleがA2AプロトコルというAIエージェント向けのAPI仕様を発表しました。これはHTTP経由でリモートのエージェントを呼び出せるので、リモートMCPを置き換えるものでしょうか? 比較してみます。

A2Aサーバーは、/.well-known/agent.jsonという公開されたホストのパスで「Agent Card」と呼ばれるJSONファイルを公開します。これにはA2Aサーバーのメタ情報が含まれます。例えばGoogleがサンプルアプリで用意した「両替エージェント」には以下のようなAgent Cardが定義されています。

注目するべきは「skills」の部分で、一見これはMCPサーバーのToolのように見えます。しかしMCPサーバーのToolは呼び出す時に引数の型情報を要求します。A2Aの場合はそれが見当たりません。以下はGitHub Issueを探すMCPサーバーのTool定義の例です。

ユーザーの対話メッセージからこの「inputSchema」を埋めてTool 呼び出すをするために、LLMに前段で推論させます。Toolではdescriptionと引数のスキーマはセットです。
しかしA2Aサーバーはスキーマではなくプレーンなテキストを送受信します。このテキストをサーバー側のLLMが解析したり、もしくはルールベースな処理を実行するのかはサーバー側の実装に委ねられます。
このようにメッセージングの手続き方法が異なります。A2Aの方がより抽象的なサーバー間呼び出し仕様になっています。なのでレイヤーが異なり、置き換えられるものではないですね。もちろん、A2Aのサーバーの中は任意の実装なので、そこでローカル/リモートのMCPサーバーを呼び出すというシナリオはあり得ます。
この大まかな「サーバーのAgent Cardを取集して、クライアントはHTTPで呼び出す」という原則だけ理解するのが良いと思います。それがエンドユーザーが操作するアプリを含めて多対多に配置できることをマルチエージェントと説明しています。
付け加えるならA2Aプロトコルには、処理中のリソースを管理する「Task」や「Push Notification」の仕様があります。これはMCPのスコープにはなかったものですが、Google CloudのBatch Prediction APIやOpenAIのAssistant APIなど、エージェント向け環境で一般的な非同期タスク管理のパターンです。LLMのAPI呼び出しを含むマルチエージェントシステムは実行に時間がかかるため、A2Aは進捗管理やリアルタイム通知をサポートする仕組みを入れたのでしょう。
ただ、世間ではA2AプロトコルがMCPブームのような狂乱を生み出すような技術を期待されている向きがありまが、これは時期尚早です。A2Aは上記のように分散システムの部品として利用される渋めのバックエンド技術なので、どのように現実のAIプロダクトに適用されるのか、エンドユーザーに直接影響を及ぼすのかは不明です。筆者としてはECのカートの裏側の決済ネットワークのように消費者レベルでは意識されない可能性もあると思います。