MCP (Model Context Protocol) プロトコル文書
MCP (Model Context Protocol) 相互作用フロー
注意: AI支援生成、バックエンドサービス実装時は、コードを参照して詳細を確認してください!
このプロジェクトのMCPプロトコルは、バックエンドAPI(MCPクライアント)とESP32デバイス(MCPサーバー)間の通信に使用され、バックエンドがデバイスが提供する機能(ツール)を発見・呼び出しできるようにします。
プロトコル形式
コード(main/protocols/protocol.cc
, main/mcp_server.cc
)によると、MCPメッセージは基本通信プロトコル(WebSocketやMQTTなど)のメッセージ本体にカプセル化されています。その内部構造はJSON-RPC 2.0仕様に従います。
全体のメッセージ構造例:
{
"session_id": "...", // セッションID
"type": "mcp", // メッセージタイプ、固定で"mcp"
"payload": { // JSON-RPC 2.0ペイロード
"jsonrpc": "2.0",
"method": "...", // メソッド名 ("initialize", "tools/list", "tools/call"など)
"params": { ... }, // メソッドパラメータ (requestの場合)
"id": ..., // リクエストID (requestとresponseの場合)
"result": { ... }, // メソッド実行結果 (success responseの場合)
"error": { ... } // エラー情報 (error responseの場合)
}
}
その中で、payload
部分は標準のJSON-RPC 2.0メッセージです:
jsonrpc
: 固定文字列"2.0"。method
: 呼び出すメソッド名 (Requestの場合)。params
: メソッドのパラメータ、構造化値、通常はオブジェクト (Requestの場合)。id
: リクエストの識別子、クライアントがリクエスト送信時に提供、サーバーが応答時にそのまま返す。リクエストと応答をマッチングするために使用。result
: メソッド成功実行時の結果 (Success Responseの場合)。error
: メソッド実行失敗時のエラー情報 (Error Responseの場合)。
相互作用フローと送信タイミング
MCPの相互作用は主にクライアント(バックエンドAPI)がデバイス上の「ツール」(Tool)を発見・呼び出すことを中心に行われます。
1. 接続確立と能力通知
- タイミング: デバイス起動後、バックエンドAPIに正常に接続した後。
- 送信者: デバイス。
- メッセージ: デバイスがバックエンドAPIに基本プロトコルの"hello"メッセージを送信、メッセージにはデバイスがサポートする能力リストが含まれ、例えばMCPプロトコルサポート(
"mcp": true
)。 - 例(MCPペイロードではなく、基本プロトコルメッセージ):
{ "type": "hello", "version": 3, "features": { "mcp": true }, "transport": "websocket", // または"mqtt" "audio_params": { ... }, "session_id": "..." // デバイスがサーバーhello受信後に設定可能 }
2. MCPセッション初期化
タイミング: バックエンドAPIがデバイス"hello"メッセージを受信し、デバイスがMCPをサポートすることを確認後、通常MCPセッションの最初のリクエストとして送信。
送信者: バックエンドAPI(クライアント)。
メソッド:
initialize
メッセージ(MCPペイロード):
{ "jsonrpc": "2.0", "method": "initialize", "params": { "capabilities": { // クライアント能力、オプション // カメラ視覚関連 "vision": { "url": "...", //カメラ: 画像処理アドレス(httpアドレス必須、websocketアドレスではない) "token": "..." // urlトークン } // ... その他のクライアント能力 } }, "id": 1 // リクエストID }
デバイス応答タイミング: デバイスが
initialize
リクエストを受信・処理後。デバイス応答メッセージ(MCPペイロード):
{ "jsonrpc": "2.0", "id": 1, // リクエストIDをマッチング "result": { "protocolVersion": "2024-11-05", "capabilities": { "tools": {} // ここのtoolsは詳細情報をリストしない、tools/listが必要 }, "serverInfo": { "name": "...", // デバイス名 (BOARD_NAME) "version": "..." // デバイスファームウェアバージョン } } }
3. デバイスツールリスト発見
- タイミング: バックエンドAPIがデバイスの現在サポートする具体的機能(ツール)リストとその呼び出し方法を取得する必要がある時。
- 送信者: バックエンドAPI(クライアント)。
- メソッド:
tools/list
- メッセージ(MCPペイロード):
{ "jsonrpc": "2.0", "method": "tools/list", "params": { "cursor": "" // ページング用、初回リクエストは空文字列 }, "id": 2 // リクエストID }
- デバイス応答タイミング: デバイスが
tools/list
リクエストを受信し、ツールリストを生成後。 - デバイス応答メッセージ(MCPペイロード):
{ "jsonrpc": "2.0", "id": 2, // リクエストIDをマッチング "result": { "tools": [ // ツールオブジェクトリスト { "name": "self.get_device_status", "description": "...", "inputSchema": { ... } // パラメータスキーマ }, { "name": "self.audio_speaker.set_volume", "description": "...", "inputSchema": { ... } // パラメータスキーマ } // ... より多くのツール ], "nextCursor": "..." // リストが大きくページングが必要な場合、次のリクエストのcursor値が含まれる } }
- ページング処理:
nextCursor
フィールドが空でない場合、クライアントは再度tools/list
リクエストを送信し、params
にこのcursor
値を含めて次のページのツールを取得する必要があります。
4. デバイスツール呼び出し
- タイミング: バックエンドAPIがデバイス上の特定の具体的機能を実行する必要がある時。
- 送信者: バックエンドAPI(クライアント)。
- メソッド:
tools/call
- メッセージ(MCPペイロード):
{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "self.audio_speaker.set_volume", // 呼び出すツール名 "arguments": { // ツールパラメータ、オブジェクト形式 "volume": 50 // パラメータ名とその値 } }, "id": 3 // リクエストID }
- デバイス応答タイミング: デバイスが
tools/call
リクエストを受信し、対応するツール関数を実行後。 - デバイス成功応答メッセージ(MCPペイロード):
{ "jsonrpc": "2.0", "id": 3, // リクエストIDをマッチング "result": { "content": [ // ツール実行結果内容 { "type": "text", "text": "true" } // 例:set_volumeがboolを返す ], "isError": false // 成功を示す } }
- デバイス失敗応答メッセージ(MCPペイロード):
{ "jsonrpc": "2.0", "id": 3, // リクエストIDをマッチング "error": { "code": -32601, // JSON-RPCエラーコード、例:Method not found (-32601) "message": "Unknown tool: self.non_existent_tool" // エラー説明 } }
5. デバイス能動メッセージ送信(Notifications)
- タイミング: デバイス内部でバックエンドAPIに通知が必要なイベントが発生した時(例:状態変化、コード例では明確にこのようなメッセージを送信するツールはないが、
Application::SendMcpMessage
の存在はデバイスが能動的にMCPメッセージを送信する可能性を示唆)。 - 送信者: デバイス(サーバー)。
- メソッド:
notifications/
で始まるメソッド名、またはその他のカスタムメソッドの可能性。 - メッセージ(MCPペイロード): JSON-RPC Notification形式に従い、
id
フィールドなし。{ "jsonrpc": "2.0", "method": "notifications/state_changed", // 例メソッド名 "params": { "newState": "idle", "oldState": "connecting" } // idフィールドなし }
- バックエンドAPI処理: Notification受信後、バックエンドAPIは対応する処理を行うが、返信しない。
相互作用図
以下は主要なMCPメッセージフローを示す簡略化された相互作用シーケンス図です:
sequenceDiagram participant Device as ESP32 Device participant BackendAPI as バックエンドAPI (Client) Note over Device, BackendAPI: WebSocket / MQTT接続確立 Device->>BackendAPI: Hello Message ("mcp": trueを含む) BackendAPI->>Device: MCP Initialize Request Note over BackendAPI: method: initialize Note over BackendAPI: params: { capabilities: ... } Device->>BackendAPI: MCP Initialize Response Note over Device: result: { protocolVersion: ..., serverInfo: ... } BackendAPI->>Device: MCP Get Tools List Request Note over BackendAPI: method: tools/list Note over BackendAPI: params: { cursor: "" } Device->>BackendAPI: MCP Get Tools List Response Note over Device: result: { tools: [...], nextCursor: ... } loop オプショナルページング BackendAPI->>Device: MCP Get Tools List Request Note over BackendAPI: method: tools/list Note over BackendAPI: params: { cursor: "..." } Device->>BackendAPI: MCP Get Tools List Response Note over Device: result: { tools: [...], nextCursor: "" } end BackendAPI->>Device: MCP Call Tool Request Note over BackendAPI: method: tools/call Note over BackendAPI: params: { name: "...", arguments: { ... } } alt ツール呼び出し成功 Device->>BackendAPI: MCP Tool Call Success Response Note over Device: result: { content: [...], isError: false } else ツール呼び出し失敗 Device->>BackendAPI: MCP Tool Call Error Response Note over Device: error: { code: ..., message: ... } end opt デバイス通知 Device->>BackendAPI: MCP Notification Note over Device: method: notifications/... Note over Device: params: { ... } end
関連文書
- MCP プロトコル使用ガイド - IoT制御におけるMCPプロトコルの具体的な使用法
- WebSocket 通信プロトコル - WebSocket下層通信プロトコル
- MQTT + UDP 混合プロトコル - MQTT + UDP混合通信プロトコル
この文書はプロジェクトにおけるMCPプロトコルの主要な相互作用フローを概説しています。具体的なパラメータ詳細とツール機能は
main/mcp_server.cc
のMcpServer::AddCommonTools
および各ツールの実装を参照する必要があります。