Transports
Documentation Index
完全なドキュメント索引は modelcontextprotocol.io/llms.txt で取得してください。 さらに調べる前に、このファイルを使って利用可能なすべてのページを見つけてください。
MCP はメッセージの符号化に JSON-RPC を使用します。JSON-RPC メッセージは UTF-8 でエンコードされていなければなりません (MUST)。
このプロトコルは現在、クライアントとサーバー間の通信のために、次の 2 つの標準的なトランスポート機構を定義しています。
- stdio: 標準入力と標準出力を介した通信
- Streamable HTTP
クライアントは、可能であれば stdio をサポートするべきです (SHOULD)。
また、クライアントとサーバーは、プラグイン可能な形で custom transports を実装することもできます。
stdio
stdio トランスポートでは、次のように動作します。
- クライアントは MCP サーバーをサブプロセスとして起動します。
- サーバーは標準入力 (
stdin) から JSON-RPC メッセージを読み取り、標準出力 (stdout) にメッセージを送信します。 - メッセージは、それぞれ個別の JSON-RPC request、notification、または response です。
- メッセージは改行で区切られ、埋め込み改行を含んではなりません (MUST NOT)。
- サーバーは、情報、デバッグ、エラーの各メッセージを含むあらゆるログ用途のために、UTF-8 文字列を標準エラー出力 (
stderr) に書き込んでもかまいません。 - クライアントは、サーバーの
stderr出力を取得しても、転送しても、無視してもかまいません (MAY)。また、stderr出力がエラー状態を示すと想定するべきではありません (SHOULD NOT)。 - サーバーは、有効な MCP メッセージではないものを
stdoutに書き込んではなりません (MUST NOT)。 - クライアントは、有効な MCP メッセージではないものをサーバーの
stdinに書き込んではなりません (MUST NOT)。
Streamable HTTP
この方式は、プロトコルバージョン 2024-11-05 における HTTP+SSE transport を置き換えるものです。詳細は後述の後方互換性ガイドを参照してください。
Streamable HTTP トランスポートでは、サーバーは複数のクライアント接続を処理できる独立したプロセスとして動作します。このトランスポートは HTTP POST リクエストと GET リクエストを使用します。サーバーは必要に応じて Server-Sent Events (SSE) を利用し、複数のサーバーメッセージをストリーミングできます。これにより、基本的な MCP サーバーだけでなく、ストリーミングやサーバーからクライアントへの notification や request をサポートする、より機能豊富なサーバーも実現できます。
サーバーは、POST メソッドと GET メソッドの両方をサポートする単一の HTTP エンドポイントパス(以下、MCP endpoint と呼びます)を提供しなければなりません (MUST)。たとえば、https://example.com/mcp のような URL がこれに当たります。
Security Warning
Streamable HTTP トランスポートを実装する際は、次の点に注意しなければなりません。
- サーバーは、DNS リバインディング攻撃を防ぐため、受信するすべての接続で
Originヘッダーを検証しなければなりません (MUST)。Originヘッダーが存在し、かつ不正である場合、サーバーは HTTP 403 Forbidden を返さなければなりません (MUST)。HTTP レスポンス本文には、idを持たない JSON-RPC の error response を含めてもかまいません (MAY)。
- ローカルで実行する場合、サーバーはすべてのネットワークインターフェイス (
0.0.0.0) ではなく、localhost (127.0.0.1) のみにバインドするべきです (SHOULD)。 - サーバーは、すべての接続に対して適切な認証を実装するべきです (SHOULD)。
これらの保護がなければ、攻撃者は DNS リバインディングを利用して、リモートの Web サイトからローカルの MCP サーバーとやり取りできてしまう可能性があります。
Sending Messages to the Server
クライアントから送られるすべての JSON-RPC メッセージは、新しい HTTP POST リクエストとして MCP endpoint に送信されなければなりません (MUST)。
- クライアントは、HTTP POST を使って JSON-RPC メッセージを MCP endpoint に送信しなければなりません (MUST)。
- クライアントは、サポートするコンテンツ型として
application/jsonとtext/event-streamの両方を列挙したAcceptヘッダーを含めなければなりません (MUST)。 - POST リクエストの本文は、単一の JSON-RPC request、notification、または response でなければなりません (MUST)。
- 入力が JSON-RPC response または notification である場合:
- サーバーがその入力を受け入れるなら、HTTP ステータスコード 202 Accepted を本文なしで返さなければなりません。
- サーバーがその入力を受け入れられないなら、HTTP エラーステータスコード(たとえば 400 Bad Request)を返さなければなりません。HTTP レスポンス本文には、
idを持たない JSON-RPC の error response を含めてもかまいません。
- 入力が JSON-RPC request である場合、サーバーは次のいずれかを返さなければなりません。
Content-Type: text/event-streamを返して SSE ストリームを開始するContent-Type: application/jsonを返して 1 つの JSON オブジェクトを返す
クライアントは、これら両方のケースをサポートしなければなりません。
- サーバーが SSE ストリームを開始する場合:
- サーバーは、クライアントが再接続できるよう準備するために、イベント ID と空の
dataフィールドから成る SSE イベントを直ちに送信するべきです(そのイベント ID をLast-Event-IDとして使うため)。 - サーバーは、イベント ID を持つ SSE イベントをクライアントに送信した後であれば、長時間接続を保持しないようにするため、SSE stream 自体は終了させずに connection をいつでも閉じてもかまいません。その場合クライアントは、再接続を試みることで SSE stream を「ポーリング」するべきです。
- サーバーが、SSE stream を終了させる前に connection を閉じる場合、閉じる前に標準の
retryフィールドを持つ SSE イベントを送信するべきです。クライアントはretryフィールドを尊重し、指定されたミリ秒数だけ待ってから再接続を試みなければなりません。 - SSE stream には、最終的に POST 本文で送られた JSON-RPC request に対する JSON-RPC response が含まれるべきです。
- サーバーは、JSON-RPC response を送る前に JSON-RPC request や notification を送ってもかまいません。これらのメッセージは、元のクライアント request に関係するものであるべきです。
- session の有効期限が切れた場合、サーバーは SSE stream を終了してもかまいません。
- JSON-RPC response が送信された後、サーバーは SSE stream を終了するべきです。
- 切断は、ネットワーク状況などにより、いつでも起こりえます。したがって:
- 切断は、クライアントが request をキャンセルしたこととして解釈するべきではありません。
- キャンセルするには、クライアントは明示的に MCP の
CancelledNotificationを送信するべきです。 - 切断によるメッセージ損失を避けるため、サーバーは stream を resumable にしてもかまいません。
- サーバーは、クライアントが再接続できるよう準備するために、イベント ID と空の
Listening for Messages from the Server
- クライアントは MCP endpoint に対して HTTP GET を発行してもかまいません。これは、クライアントが先に HTTP POST でデータを送信しなくても、サーバーがクライアントと通信できるように SSE ストリームを開くために利用できます。
- クライアントは、サポートするコンテンツ型として
text/event-streamを列挙したAcceptヘッダーを含めなければなりません。 - サーバーは、この HTTP GET に対して
Content-Type: text/event-streamを返すか、あるいはこの endpoint では SSE ストリームを提供していないことを示す HTTP 405 Method Not Allowed を返さなければなりません。 - サーバーが SSE ストリームを開始する場合:
- サーバーは、ストリーム上で JSON-RPC request や notification を送信してもかまいません。
- それらのメッセージは、クライアントから同時に実行中の JSON-RPC request とは無関係であるべきです。
- サーバーは、以前のクライアント request に関連するストリームを resuming している場合を除き、ストリーム上で JSON-RPC response を送信してはなりません。
- サーバーは SSE ストリームをいつでも閉じてもかまいません。
- サーバーが stream を終了せずに connection を閉じる場合、POST request に対して説明したのと同じポーリング動作に従うべきです。つまり、
retryフィールドを送信し、クライアントが再接続できるようにします。 - クライアントは SSE ストリームをいつでも閉じてもかまいません。
Multiple Connections
- クライアントは、複数の SSE ストリームに同時に接続したままでいてもかまいません。
- サーバーは、自身の各 JSON-RPC メッセージを、接続されているストリームのうちただ 1 つにだけ送信しなければなりません。つまり、同じメッセージを複数ストリームにブロードキャストしてはなりません。
- メッセージ損失のリスクは、stream を resumable にすることで軽減される場合があります。
Resumability and Redelivery
切断された接続の再開と、それがなければ失われるかもしれないメッセージの再配送を支援するために、次のようにします。
- サーバーは、SSE 標準で説明されているように、SSE イベントに
idフィールドを付与してもかまいません。idが存在する場合、その ID は、その session 内のすべてのストリーム全体でグローバルに一意でなければなりません。session 管理を使っていない場合は、その特定のクライアントに関する全ストリーム内で一意でなければなりません。- イベント ID は、元のストリームを識別するのに十分な情報をエンコードし、サーバーが
Last-Event-IDを正しいストリームに対応付けられるようにするべきです。
- クライアントが切断後(ネットワーク障害でも、サーバー主導の切断でも)に再開したい場合、MCP endpoint に対して HTTP GET を発行し、最後に受信したイベント ID を示すために
Last-Event-IDヘッダーを含めるべきです。- サーバーは、このヘッダーを使って、切断されたそのストリーム上で最後のイベント ID の後に送られていたはずのメッセージを再送し、その地点からストリームを再開してもかまいません。
- サーバーは、別のストリームで配信されるはずだったメッセージを再送してはなりません。
- この仕組みは、元のストリームがどのように開始されたか(POST か GET か)にかかわらず適用されます。再開は常に
Last-Event-IDを付けた HTTP GET で行います。
言い換えると、これらのイベント ID は、各ストリームごとにサーバーが割り当て、その特定のストリーム内のカーソルとして機能するべきです。
Session Management
MCP の "session" とは、クライアントとサーバーの間で論理的に関連する一連のやり取りであり、initialization phase から始まります。状態を持つ session を確立したいサーバーを支援するため、次のようにします。
- Streamable HTTP トランスポートを使うサーバーは、初期化時に
InitializeResultを含む HTTP response のMCP-Session-Idヘッダーに session ID を含めることで、session ID を割り当ててもかまいません。- session ID は、グローバルに一意であり、かつ暗号学的に安全であるべきです(たとえば、安全に生成された UUID、JWT、あるいは暗号学的ハッシュ)。
- session ID は、表示可能な ASCII 文字(0x21 から 0x7E まで)だけを含まなければなりません。
- クライアントは session ID を安全に取り扱わなければなりません。詳しくは Session Hijacking mitigations を参照してください。
- 初期化時にサーバーから
MCP-Session-Idが返された場合、Streamable HTTP トランスポートを使用するクライアントは、その後のすべての HTTP request でMCP-Session-Idヘッダーにそれを含めなければなりません。- session ID を必要とするサーバーは、
MCP-Session-Idヘッダーのない request(初期化を除く)に対して HTTP 400 Bad Request を返すべきです。
- session ID を必要とするサーバーは、
- サーバーは session をいつでも終了してもかまいません。その後、その session ID を含む request に対しては HTTP 404 Not Found を返さなければなりません。
- クライアントは、
MCP-Session-Idを含む request に対する response として HTTP 404 を受け取った場合、新しいInitializeRequestを session ID なしで送って新しい session を開始しなければなりません。 - クライアントアプリケーションから離れる場合など、特定の session が不要になったクライアントは、その session を明示的に終了するため、
MCP-Session-Idヘッダーを付けた HTTP DELETE を MCP endpoint に送信するべきです。- サーバーは、この request に対して HTTP 405 Method Not Allowed を返してもかまいません。これは、クライアントによる session 終了をサーバーが許可していないことを示します。
Sequence Diagram
Protocol Version Header
HTTP を使用する場合、クライアントは、その後のすべての request に MCP-Protocol-Version: <protocol-version> HTTP ヘッダーを含めなければなりません。これにより、MCP サーバーは MCP プロトコルバージョンに基づいて応答できます。
例: MCP-Protocol-Version: 2025-11-25
クライアントが送るプロトコルバージョンは、initialization 中にネゴシエートされたものであるべきです。
後方互換性のため、サーバーが MCP-Protocol-Version ヘッダーを受け取らず、かつそのバージョンを識別する他の手段もない場合、たとえば初期化時にネゴシエートされたバージョンに依存できない場合には、サーバーはプロトコルバージョン 2025-03-26 を仮定するべきです。
サーバーが無効または未対応の MCP-Protocol-Version を持つ request を受け取った場合、HTTP 400 Bad Request を返さなければなりません。
Backwards Compatibility
クライアントとサーバーは、廃止予定の HTTP+SSE transport(プロトコルバージョン 2024-11-05)との後方互換性を、次のように維持できます。
古いクライアントをサポートしたいサーバー は、次のようにするべきです。
- 新しい Streamable HTTP トランスポート用に定義された "MCP endpoint" と並行して、旧トランスポートの SSE endpoint と POST endpoint の両方を引き続きホストすること。
- 旧 POST endpoint と新 MCP endpoint を統合することも可能ですが、不必要な複雑さを招く可能性があります。
古いサーバーをサポートしたいクライアント は、次のようにするべきです。
- ユーザーから MCP サーバー URL を受け取ります。その URL は旧トランスポートを使うサーバーを指している場合も、新トランスポートを使うサーバーを指している場合もあります。
- 上で定義した
Acceptヘッダーを付けて、そのサーバー URL にInitializeRequestを POST してみます。- 成功した場合、クライアントはそのサーバーが新しい Streamable HTTP トランスポートをサポートしていると判断できます。
- HTTP ステータスコード 400 Bad Request、404 Not Found、または 405 Method Not Allowed で失敗した場合:
- そのサーバー URL に対して GET request を発行し、それによって SSE ストリームが開かれ、最初のイベントとして
endpointイベントが返ることを期待します。 endpointイベントが到着した時点で、クライアントはそのサーバーが旧 HTTP+SSE トランスポートで動作していると判断でき、その後のすべての通信でそのトランスポートを使うべきです。
- そのサーバー URL に対して GET request を発行し、それによって SSE ストリームが開かれ、最初のイベントとして
Custom Transports
クライアントとサーバーは、それぞれの要件に合わせて追加の custom transport 機構を実装してもかまいません。プロトコルはトランスポート非依存であり、双方向のメッセージ交換をサポートする任意の通信チャネル上で実装できます。
custom transports をサポートする実装者は、MCP が定義する JSON-RPC メッセージ形式とライフサイクル要件を維持することを保証しなければなりません。custom transports は、相互運用性を高めるために、その接続確立方法およびメッセージ交換パターンを文書化するべきです。