はじめに
-
MCP(Model Context Protcol)を触る機会が皆さんも増えていることと思います
-
少しMCPの構造について踏み込みたい人向けの記事になってます (ただの私の備忘録でもあります)
-
下記の書籍を参考にさせていただきました。とてもわかりやすいので手元に置いておきたい書籍です
MCP の基本構造
基本的に以下の3つで構成されている
- Host : LLMを内包し、全体を指揮する頭脳的なやつ
- Client : 特定のサーバーと通信を担う通信セッション
- Server : DBアクセスやAPI実行などの具体的な機能をツールとして提供
MCPの共通言語「JSON-RPC2.0」
-
JSON-RPCとは?
- RPC(Remote Procedure Call)の一種
- 「プロシジャーコール」とは、関数を呼び出すこと
- 仕様が比較的シンプル
- 扱いやすいJSONベース
-
なぜ、JSON-RPC2.0を採用しているか?
- AIが外部の機能やデータを利用する際の 「使いやすさ」を追求
- LLMのツールコーリングとRPCの親和性が高いこと
- RPCの一種
-
主要なメッセージタイプ
- リクエスト
- これをやってほしいという要求
- メソッド名、パラメータ、IDを含む
- レスポンス
- 処理結果を返すメッセージ
- 成功orエラーを返す
- 通知
- 相手からの応答は必要としない、情報伝達のメッセージ
- リクエスト
-
JSON-RPCメッセージの構造
- jsonrpc:"2.0"
- id : リクエストの識別子
- method:呼び出すメソッド名
- params:メソッドのパラメータ
- result:処理結果
- error:エラー情報
-
JSON-RPC vs REST API (★)
- 主な違いは「どこに要求を送るか?(エンドポイントの考え方)」と「何をしたいかをどう伝えるか?(操作の指定方法)」である
- エンドポイントの考え方としては、「単一窓口 vs 多数の窓口」
- 操作の指定方法は、「methodフィールド vs URLとHTTPメソッド」
- 上記の設計思想から、LLMのツールコーリング機能の実装には、REST APIよりも、JSON-RPCが適している
- JSON-RPC 2.0はMCPにおけるコミュニティのまさに土台
- 異なる種類のサーバーやルールであっても、統一された方法で連携できる
MCPにおける「セッション」
-
セッション
- コンテキストの共有に必要
- 重要な役割は、対話の開始時に交換される互いの「ケイパビリティ」を管理すること
- セッションはステートレスなJSON-RPCプロトコル上で、状態(State)を持つ効率的な対話を実現するための規約
-
セッションのライフサイクル
- (1)初期化
- (2)メッセージ交換
- (3)終了
- クリーンシャットダウン
- トランスポート層での切断
- エラー条件による終了
-
ケイパビリティ交渉
- 初期化で行われている重要な工程
- 下記の情報交換実施
- プロトコルバージョン
- クライアントの機能
- サーバーの機能
- 実装情報
- 単なる接続確認ではなく、クライアントとサーバーが互いの「できること」を理解しあい、その後の円滑なコミュニケーションの土台を築くための重要なステップ
トランスポート層
- 概要
- 会話の内容をどのようにして相手に届けるか?ここを担うのが「トランスポート層」である
- クライアントとサーバーでやり取りする具体的な手段を指す
- いわゆる「通信手段」と考えて良い
- 主要なトランスポート
- 「stdio」
- 「Standard Input(標準入力)」と「Standard Output(標準出力)」の略
- 基本的な入出力チャネルを利用してJSON-RPCメッセージを送受信する方法
- 同一マシン上で動作するプロセス間でのケースに対応
- つまり、ローカルでMCPサーバーを起動し連携するパターン
- 「Streamable HTTP」
- HTTPプロトコルをベースとした通信方法
- この方法は、ネットワークを介した通信のユースケース適している
- 「stdio」
MCPサーバー開発の留意点
- 適切な粒度。数のツールを提供する
- LLMにとって理解しやすいツールを提供する
- エラーを適切に処理する
- プロトコルに準拠した実装を行う
終わりに
- さらに、深掘りすれば細かい実装部分の話は色々ありますが、今回はこのぐらいの内容にしておきたいと思います
- 特に、JSON-RPC vs REST APIの違いはぜひ押さえておきたいポイントでもありますね