Документация протокола MCP (Model Context Protocol)
Поток взаимодействия MCP (Model Context Protocol)
Протокол 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": { ... }, // Параметры метода (для запроса)
"id": ..., // ID запроса (для запроса и ответа)
"result": { ... }, // Результат выполнения метода (для успешного ответа)
"error": { ... } // Информация об ошибке (для ошибочного ответа)
}
}
Где часть payload
является стандартным сообщением JSON-RPC 2.0:
jsonrpc
: Фиксированная строка “2.0”.method
: Имя вызываемого метода (для Request).params
: Параметры метода, структурированное значение, обычно объект (для Request).id
: Идентификатор запроса, предоставляемый клиентом при отправке запроса, возвращаемый сервером в исходном виде. Используется для сопоставления запросов и ответов.result
: Результат при успешном выполнении метода (для Success Response).error
: Информация об ошибке при неудачном выполнении метода (для Error Response).
Поток взаимодействия и время отправки
Взаимодействие MCP в основном сосредоточено на том, что клиент (бэкенд API) обнаруживает и вызывает “инструменты” (Tool) на устройстве.
1. Установка соединения и уведомление о возможностях
- Время: После запуска устройства и успешного подключения к бэкенд API.
- Отправитель: Устройство.
- Сообщение: Устройство отправляет сообщение “hello” базового протокола бэкенд API, сообщение содержит список поддерживаемых устройством возможностей, например, поддержку протокола 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
и включить это значениеcursor
вparams
для получения следующей страницы инструментов.
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 - Конкретное использование протокола MCP в управлении IoT
- Протокол связи WebSocket - Базовый протокол связи WebSocket
- Смешанный протокол MQTT + UDP - Смешанный протокол связи MQTT + UDP
McpServer::AddCommonTools
в main/mcp_server.cc
и реализацию каждого инструмента.