- All YoU Need Is D*
- Posts
- 新しいMCP仕様(2025-03-26)での変更点:認証・SSEサポート任意化
新しいMCP仕様(2025-03-26)での変更点:認証・SSEサポート任意化
2024-11-05からのアップデート

ModelContextProtocol(MCP)の仕様が2024-11-05版から2025-03-26版へと更新された。本記事では、最新版で導入された変更点について、関連するPull Requestでの議論も踏まえながらまとめる。2025-03-26のMCP仕様まとめではなく、主に今回の変更点に焦点を当てたものとなっている。
主要な変更点の概要
2025-03-26
のModelContextProtocolでは、以下の主要な変更が入った:
OAuth 2.1に基づく認証仕様の追加
より柔軟な「Streamable HTTP」トランスポートの導入
JSON-RPCバッチングのサポート
ツールの動作をより詳細に記述するためのTool annotationsの追加
その他のスキーマ変更と機能強化
認証仕様の追加
2025-03-26
のMCPでは、OAuth 2.1に基づく包括的な認証仕様が新たに追加された。これによって、MCPクライアントがリソース所有者に代わって制限付きMCPサーバーにリクエストを行う際の仕様が追加された。
認証はMCP実装において任意(OPTIONAL)となっている。
サポートする場合:
HTTP-basedトランスポートを使用する実装は、この仕様に準拠すべき(SHOULD)
STDIOトランスポートを使用する実装は、この仕様に従うべきではなく(SHOULD NOT)、代わりに環境変数から認証情報を取得すべき
代替トランスポートを使用する実装は、そのプロトコルに応じた確立されたセキュリティのベストプラクティスに従わなければならない(MUST)
認証仕様追加の背景と設計思想
この認証仕様の追加は、#133で提案され、約1ヶ月の議論を経て策定された。この提案の背景には、MCPのセキュリティを強化しながらも、プロトコルの基本原則である「シンプルさと標準ベースの設計」を維持するという目標があった。
認証仕様の設計における主要な考え方は以下の通り:
既存の標準の活用: 新しい認証スキームを発明するのではなく、広く採用されている OAuth 2.0/2.1 標準を基盤として採用
関心事の分離: 認証の懸念事項をコアプロトコルメッセージングから分離し、プロトコルの中核部分をクリーンで焦点を絞ったものに保つ
トランスポートレベルでの認証: 認証はHTTPトランスポートレベルで行われ、コアプロトコルメッセージングには影響しない
オプショナルだが標準化: 認証はオプショナルでありながらも、実装する場合は標準化された方法で行うべき
明確なガイダンス: トークン処理、セキュリティ要件、エラーケースに関する明確なガイダンスを提供
Streamable HTTPトランスポートの導入
2025-03-26
では、以前のHTTP+SSEトランスポートがより柔軟な「Streamable HTTP」トランスポートに置き換えられた。この新しいトランスポートは、基本的なMCPサーバーと、ストリーミングやサーバー・クライアント間の通知をサポートする機能豊富なサーバーの両方に対応している。この仕様は#206で議論され追加された。
旧仕様ではSSEエンドポイントとHTTP POSTエンドポイントを用意する必要があったが、新仕様では単一のエンドポイント(例: /mcp
)に統合されたのが大きい。 また、SSEの実装は必須(MUST)では無くなった。
セッション識別のための Mcp-Session-Id
ヘッダーについても仕様が追加されている。
Streamable HTTPトランスポートの主な特徴
単一のHTTPエンドポイント: サーバーは単一のHTTPエンドポイントを提供し、POSTとGETの両方をサポート
Server-Sent Events(SSE)のオプション化: サーバーはオプションでSSEを使用して複数のサーバーメッセージをストリーミング可能
柔軟な設計: 基本的なMCPサーバーから機能豊富なサーバーまで、さまざまな実装に対応
下位互換性: 2024-11-05版のHTTP+SSEトランスポートとの下位互換性を考慮した設計
ステートレスサーバーの実現: 高可用性の長期接続を必要としないステートレスサーバーの実装が可能
Streamable HTTPトランスポートの設計に関する#206の議論では、以下の点が強調された:
完全にステートレスなサーバー実装: この新しいトランスポートでは、高可用性の長期接続を必要としない完全にステートレスなサーバーの実装が可能に
"just HTTP"としての実装: 新しいトランスポートはただのHTTPとして実装できるため、既存のHTTPのインフラをそのまま活用できる。
ステートレスサーバーでもストリーミングが可能: 完全にステートレスなサーバーでも、必要に応じてSSEを使用してストリーミングレスポンスを提供可能 4.WebSocketではなくSSEを選択した理由: 開発チームはWebSocketではなくSSEを選択した理由として、以下の点を挙げている: (PRの
Why not WebSocket?
のセクション)単純なRPC的な使用では、WebSocketは不必要な運用・ネットワークオーバーヘッドを引き起こす
ブラウザからは、WebSocketに
Authorization
などのヘッダーを付加できないWebSocketへのアップグレードはGETリクエストでのみ可能で、POSTからのアップグレードには複雑な2段階プロセスが必要
後方互換性の維持
2024-11-05
で導入された古いHTTP+SSEトランスポートとの後方互換性は、以下のように維持できる:
サーバー側の後方互換性
古いクライアントをサポートしたいサーバーは:
新しい「MCPエンドポイント」と並行して、古いトランスポートのSSEエンドポイントとPOSTエンドポイントの両方を引き続きホストする
古いPOSTエンドポイントと新しいMCPエンドポイントを統合することも可能だが、不要な複雑さを招く可能性がある
クライアント側の後方互換性
古いサーバーをサポートしたいクライアントは:
ユーザーからMCPサーバーURLを受け取る(古いトランスポートまたは新しいトランスポートを使用するサーバーのいずれかを指す可能性がある)
上記で定義された
Accept
ヘッダーを付けて、サーバーURLにInitializeRequest
をPOSTする:成功した場合、新しいStreamable HTTPトランスポートをサポートするサーバーと判断できる
HTTP 4xx(例:405 Method Not AllowedまたはNot Found)で失敗した場合:
サーバーURLにGETリクエストを発行し、最初のイベントとしてエンドポイントイベントを返すSSEストリームが開かれることを期待する
エンドポイントイベントが到着したら、古いHTTP+SSEトランスポートを実行しているサーバーと判断し、以降のすべての通信にそのトランスポートを使用する
JSON-RPCバッチングのサポート
2025-03-26
では、JSON-RPCバッチングのサポートが追加された。これにより、複数のリクエストや通知を一度に送信することが可能になり、メッセージ交換の効率が向上した。
JSON-RPCバッチングの背景と設計思想
JSON-RPCバッチングのサポートは、PR #228で提案され、実装された。この提案の背景には、MCPの効率性を向上させるという目標があった。
議論によると、それまでのMCP仕様ではJSON-RPCバッチングについて明示的に言及されておらず、多くのSDKが一般的にバッチングをサポートしていなかった。これは技術的にはJSON-RPC仕様への準拠違反となる可能性があった。
この変更により、MCPの実装は 必須(MUST) でJSON-RPCバッチングをサポートすることになった。
この仕様追加により、特に多数の小さなメッセージを交換する必要があるシナリオでのパフォーマンスが向上することになる。
Tool annotationsの追加
2025-03-26
では、ツールの動作をより詳細に記述するためのTool annotationsが追加された。これにより、ツールが読み取り専用か破壊的かなどの特性を示すことが可能になった。
Tool annotationsの主な特徴
詳細な動作記述: ツールの動作特性を詳細に記述するためのannotation
安全性の明示: ツールが読み取り専用か破壊的かなどの特性を明示的に示すことが可能
セキュリティ強化: クライアントがツールの安全性を評価する際に役立つ情報を提供
Tool annotationsの具体的な値
具体的に取り得る値はschema.tsで定義されている。
Tool annotationsでは、以下の値を指定可能:
title: ツールの人間が読みやすいタイトル
readOnlyHint: ツールが環境を変更しないことを示す(デフォルト: false)
destructiveHint: ツールが破壊的な更新を行う可能性があることを示す。falseの場合、追加的な更新のみを行う。readOnlyHintがfalseの場合のみ意味を持つ(デフォルト: true)
idempotentHint: 同じ引数で繰り返し呼び出しても環境に追加の影響がないことを示す。readOnlyHintがfalseの場合のみ意味を持つ(デフォルト: false)
openWorldHint: ツールが「オープンな世界」の外部エンティティと相互作用する可能性があることを示す。falseの場合、ツールの相互作用領域は閉じている。例えば、ウェブ検索ツールの世界はオープンだが、メモリツールの世界は閉じている(デフォルト: true)
注意点として、これらのannotationはすべてヒントであり、ツールの動作を忠実に記述することは保証されていない(title
のような説明的なプロパティも含む)。クライアントは、信頼できないサーバーから受け取ったTool annotationsに基づいてツールの使用を判断すべきではないとも記載されている。
その他の変更と機能強化
2025-03-26
では、上記の主要な変更に加えて、いくつかの小さな改善も行われた:
進捗通知の強化
ProgressNotification
にmessage
フィールドが追加され、進捗状況の説明が可能になった。これにより、長時間実行される操作の状態をユーザーに対してより明確に伝えることができるようになった。
オーディオデータのサポート
テキストと画像に加えて、オーディオデータのサポートが追加された。これにより、MCPはマルチモーダルなコンテンツタイプをより幅広くサポートできるようになった。
引数自動補完のサポート明示
引数の自動補完候補のサポートを明示的に示すcompletions
機能が追加された。これにより、サーバーは自動補完機能をサポートしていることをクライアントに明示的に伝えることができる。
タイムアウト処理の改善
リクエストのタイムアウト処理に関するガイダンスが強化され、以下のように明確化された。
MCP実装は、接続のハングやリソース枯渇を防ぐため、すべての送信リクエストにタイムアウトを設定すべき(SHOULD)とされている。タイムアウト期間内に成功またはエラーのレスポンスを受信しない場合、送信者はそのリクエストのキャンセル通知を発行し、レスポンスの待機を停止すべき(SHOULD)だ。
SDKやその他のミドルウェアは、これらのタイムアウトをリクエストごとに設定できるようにすべき(SHOULD)とされている。
また、リクエストに対応する進捗通知を受信した場合、これは実際に作業が行われていることを示すため、タイムアウトクロックをリセットしてもよい(MAY)。ただし、クライアントやサーバーの誤動作の影響を制限するため、進捗通知の有無に関わらず、常に最大タイムアウト時間を適用すべき(SHOULD)だ。
まとめ
ModelContextProtocolの 2025-03-26
では、認証仕様の追加、Streamable HTTPトランスポートの導入、JSON-RPCバッチングのサポート、Tool annotationsの追加など、多くの重要な機能強化が行われた。これらの変更により、MCPはより安全で柔軟、そして効率的になった。
特に認証仕様の追加は、MCPの実用性がより上がりそう。また、Streamable HTTPトランスポートの導入により、完全にステートレスなサーバーの実装が可能になったのはありがたい。
参考リンク
この記事の作成にあたり、以下の情報源を参考にした: