はじめに
モデルコンテキストプロトコル (Model Context Protocol, MCP) は、大規模言語モデル (LLM) アプリケーションと外部データソースやツールとの間に、標準化された橋渡しを構築することを目的とする。本稿では、MCP の中核概念、ライフサイクル、重要な機能、実用的なユーティリティを詳しく掘り下げる。最新の 2025-03-26 プロトコル改訂版と具体的な JSON-RPC リクエスト/レスポンスの例を交えながら、開発者向けの包括的な実践ガイドを提供する。
MCP の主要コンポーネント
MCP は、連携して動作する複数の主要コンポーネントで構成されている:
- 基本プロトコル:中核となる JSON-RPC メッセージ種別を定義する。
- ライフサイクル管理:接続の初期化、機能ネゴシエーション、セッション管理を制御する。
- サーバー機能:リソース (Resources)、プロンプト (Prompts)、ツール (Tools) など、サーバーが提供する機能。
- クライアント機能:サンプリング (Sampling)、ルート (Roots) など、クライアントが提供する機能。
- ユーティリティ:ログ (Logging)、自動補完 (Completion)、進捗追跡 (Progress)、キャンセル (Cancellation) など、分野をまたぐ機能。
すべての実装は、基本プロトコルとライフサイクル管理の サポートが必須 (MUST)。その他のコンポーネントは、アプリケーションの要件に応じて選択的に実装できる。
基本プロトコル:JSON-RPC メッセージ
MCP は完全に JSON-RPC 2.0 仕様に基づいている。
リクエスト
操作を開始するために使われる。
レスポンス
リクエストに対する応答で、結果またはエラーを含む。
レスポンスの result と error は、必ず (MUST) 一方だけを設定し、同時に設定してはならない (MUST NOT)。
通知
レスポンスの不要な一方向のメッセージ。
通知に id を 含めてはならない (MUST NOT)。
バッチ処理
MCP 実装はバッチ処理のリクエスト/通知を 送信できる (MAY) が、バッチの受信は サポートしなければならない (MUST)。
ライフサイクル管理
MCP 接続は、厳格なライフサイクルに従う:初期化 -> 操作 -> 終了。
初期化フェーズ
クライアントとサーバー間の最初のやり取りであり、プロトコルバージョンと機能をネゴシエートする。
初期化リクエスト (クライアントから送信)
注意:初期化リクエストをバッチ処理に 含めてはならない (MUST NOT)。
初期化レスポンス (サーバーから送信)
バージョンのネゴシエーション:クライアントはサポートしている最新バージョンを送信する。サーバーがそのバージョンをサポートしていれば、同じバージョンを返す。支持していなければ、サーバーがサポートする最新バージョンを返す。クライアントが返されたバージョンをサポートしていない場合は、接続を 切断すべきである (SHOULD)。
機能のネゴシエーション:双方は capabilities オブジェクトで、対応する機能とサブ機能(listChanged、subscribe など)を宣言する。その後の操作では、ネゴシエーションに成功した機能のみを使用できる。
初期化完了通知 (クライアントから送信)
成功した initialize レスポンスを受け取った後、クライアントは、操作フェーズへ入る準備ができたことを示すため、この通知を 送信しなければならない (MUST)。
initialize レスポンスを受け取るまで、クライアントは ping 以外のリクエストを送信してはならない。initialized 通知を受け取るまで、サーバーは ping と logging 以外のリクエストを送信してはならない。
操作フェーズ
双方は、ネゴシエーションされた機能とプロトコルバージョンに基づいて通常の通信を行う。
終了フェーズ
通常はクライアントから開始し、基盤となる転送機構(stdio ストリームや HTTP 接続を閉じるなど)を使って接続を終了する。MCP に特定の終了メッセージはない。
サーバー機能の詳細
サーバーは次の主要機能を公開できる。
1. リソース
サーバーがコンテキストデータ(ファイル、データベーススキーマなど)を共有できるようにする。各リソースは一意の URI で識別される。
機能:resources(subscribe と listChanged は任意)
リソース一覧 (resources/list)(ページング対応)
リソースの読み取り (resources/read)
リソース更新通知 (notifications/resources/updated)(サーバーがサブスクライバーへ送信)
クライアントは、この通知を受け取った後、通常は resources/read を再実行して最新のコンテンツを取得する。
リソース一覧変更通知 (notifications/resources/list_changed)(listChanged 機能が必要)
クライアントは、この通知を受け取った後、通常は resources/list を再実行する。
リソーステンプレート:サーバーは resources/templates/list を通じて、引数付きの URI テンプレート (RFC6570) を公開できる。
一般的な URI スキーム:https://、file://、git://(実装ごとに独自のスキームを定義できる)。
2. ツール
言語モデルが、サーバーが提供する外部機能(API、計算など)を呼び出せるようにする。
機能:tools(listChanged は任意)
ツール一覧 (tools/list)(ページング対応)
注意:クライアントは、ツールのアノテーションを信頼できないものとして 扱わなければならない (MUST)。ただし、信頼できるサーバーから届いた場合はこの限りでない。
ツールの呼び出し (tools/call)
ツール一覧変更通知 (notifications/tools/list_changed)(listChanged 機能が必要)
セキュリティ:クライアントは、機微な操作の前にユーザーへ確認を求め、ツールに渡される入力内容を提示してデータ漏えいを防ぐ べきである (SHOULD)。
3. プロンプト
サーバーは、ユーザーが明示的に選択して LLM と対話するための構造化されたメッセージテンプレートを提供する。
機能:prompts(listChanged は任意)
プロンプト一覧 (prompts/list)(ページング対応)
プロンプトの取得 (prompts/get)
プロンプト一覧変更通知 (notifications/prompts/list_changed)(listChanged 機能が必要)
クライアント機能の詳細
クライアントは次の主要機能を公開できる。
1. ルート
クライアントが、ファイルシステムへのアクセス範囲をサーバーへ公開できるようにする。
機能:roots(listChanged は任意)
ルート一覧 (roots/list)(サーバーがリクエスト)
ルート一覧変更通知 (notifications/roots/list_changed)(クライアントが送信。listChanged 機能が必要)
2. サンプリング
サーバーが、LLM を使ってクライアントにコンテンツ(テキスト、画像、オーディオ)を生成するよう要求できるようにする。モデルへのアクセスと選択はクライアントが制御する。
機能:sampling
メッセージ作成 (sampling/createMessage)(サーバーがリクエスト)
セキュリティ:クライアントはユーザー承認フローを 実装し、送信前にユーザーがプロンプトを確認・編集できるようにする べきである (SHOULD)。
ユーティリティ
MCP は、選択的に利用できる補助機能を多数提供する。
Ping
接続が維持されているかを確認する。
進捗
長時間実行される操作の進捗を報告する。
リクエストで progressToken を指定する:送信側(クライアントなど)は、リクエストの _meta に一意の progressToken を含める。
進捗通知 (notifications/progress):受信側(サーバーなど)が進捗の更新を送信する。
ログ
サーバーがクライアントに構造化ログを送信できるようにする。
機能:logging
ログレベルの設定 (logging/setLevel):クライアントは、サーバーが送信すべき最低ログレベルを設定できる(debug, info, notice, warning, error, critical, alert, emergency)。
ログメッセージ通知 (notifications/message):サーバーがログを送信する。
キャンセル
一方が、以前送信した、まだ実行中のリクエストのキャンセルを依頼できるようにする。
キャンセル通知 (notifications/cancelled):送信側が出す。
受信側は、キャンセル対象のリクエストの処理を 停止すべきである (SHOULD)。そのリクエストに対するレスポンスは 送信すべきでない (SHOULD NOT)。送信側は、キャンセル後に届く可能性のあるレスポンスを 無視すべきである (SHOULD)。
自動補完
サーバーは、プロンプト引数またはリソース URI に対して自動補完候補を提供する。
機能:completions
自動補完のリクエスト (completion/complete)
ページング
多数の結果を返す可能性のあるリスト操作(resources/list、tools/list、prompts/list、resources/templates/list)では、MCP はカーソルベースのページングを使用する。
サーバーからのレスポンス:結果に nextCursor を含める。値が空でなければ、次のページが存在する。
クライアントの次ページ要求:リクエストの params に、受け取った cursor を含める。
クライアントは、カーソルを不透明な文字列として 扱わなければならない (MUST)。
エラー処理
MCP は標準の JSON-RPC エラーコードを使う。
- -32600 Invalid Request:JSON が無効、または仕様に準拠していない。
- -32601 Method not found:メソッドが存在しない、または利用できない。
- -32602 Invalid params:メソッドの引数が無効。
- -32603 Internal error:サーバー内部のエラー。
- -32000 to -32099 Server error:実装固有のサーバーエラー(例:
-32002はリソースが見つからない場合に使用)。
セキュリティと信頼
MCP 実装者は、セキュリティと信頼の問題を慎重に考慮 しなければならない (MUST):
- ユーザーの同意と制御:すべてのデータアクセスと操作には、ユーザーの明示的な同意が必要。
- データプライバシー:ユーザーの同意なく、ユーザーデータを共有してはならない。
- ツールセキュリティ:ツール呼び出しはコード実行を意味するため、慎重に扱い、ユーザーの同意を得る必要がある。
- サンプリング制御:ユーザーは、サンプリング要求を制御し、結果を確認できる必要がある。
- 検証:クライアントとサーバーの双方が、入力と出力を検証しなければならない。
- 権限:適切なアクセス制御を実施する。
おわりに
モデルコンテキストプロトコル (MCP) は、標準化されたメッセージ、ライフサイクル管理、豊富な機能群により、強力で安全かつ相互運用可能な AI アプリケーションを構築するための基盤を提供する。中核となる概念とプロトコルの詳細を理解し、具体的なリクエスト/レスポンス例と組み合わせるのは、MCP を有効に活用して LLM と外の世界をつなぐうえで 도움이になる。
参考資料: