Протокол JSON-RPC
Агент обращается к одному роуту — POST /mcp относительно пути API, например /api/mcp.
tools/list и tools/call — методы JSON-RPC этого адреса, отдельные HTTP-маршруты для них не нужны.
GET /mcp отвечает 405: отдельного SSE-потока нет.
Каждый запрос передаёт access-токен в заголовке Authorization: Bearer. Пользователь токена должен входить в группу «MCP: Клиенты».
Версии протокола
| Версия | Начало работы и методы |
|---|---|
| 2026-07-28 | server/discover, ping, tools/list и tools/call; метаданные в каждом запросе |
| 2025-11-25 | initialize, затем ping, tools/list и tools/call; notifications/initialized/cancelled принимаются без фоновой отмены |
Для версии 2026-07-28 каждый запрос передаёт заголовки MCP-Protocol-Version и Mcp-Method, а params._meta — версию протокола и объект clientCapabilities.
clientInfo необязателен; если он передан, это объект со строковыми name и version. Для tools/call нужен также заголовок Mcp-Name, совпадающий с params.name.
Для версии 2025-11-25 первоначальный initialize может не содержать заголовка версии; он передаёт protocolVersion, capabilities и clientInfo. Последующие запросы указывают согласованную версию. Принятое уведомление возвращает 202 без тела.
Получение каталога
ACCESS_TOKEN замените реальным access-токеном. Не размещайте токен в публичных файлах и URL.
curl 'https://example.com/api/mcp' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'MCP-Protocol-Version: 2026-07-28' \
-H 'Mcp-Method: tools/list' \
--data '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'Инструменты сортируются по имени и выдаются страницами по 50. Следующая страница запрашивается с params.cursor из nextCursor предыдущего ответа.
Курсор не даёт дополнительных прав: на каждом запросе снова учитываются текущие группы пользователя.
Вызов инструмента
Для вызова задайте заголовки Mcp-Method: tools/call и Mcp-Name с именем инструмента. Тело запроса:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "project_info",
"arguments": {},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}Результат контроллера возвращается в result.structuredContent и дублируется текстом JSON в result.content.
При ошибке выполнения роута ответ содержит result.isError = true и безопасную детализацию ошибки API-платформы с исходным id запроса.
Ошибки
| Ситуация | Ответ |
|---|---|
| Ошибка выполнения роута | result.isError = true с данными ошибки |
| Аргументы не соответствуют схеме инструмента | result.isError = true с кодом PARAMETERS_INVALID |
| Неизвестный или недоступный инструмент | error с кодом -32602 |
| Неверные метаданные или параметры запроса | error с кодом -32602 |
| Заголовки противоречат телу запроса | error с кодом -32020 |
| Неподдерживаемая версия протокола | HTTP 400, код -32022, data.supported и data.requested |
| Нет токена, нет группы или шлюз выключен | Обычный ответ API-платформы без формата JSON-RPC |
JSON-RPC batch-запросы не поддерживаются. Идентификатор запроса — строка или целое число; null не принимается. Запрос без id допускается только для уведомлений версии 2025-11-25.
Ограничения размера
Запрос ограничен 1 МиБ и глубиной JSON 32. Для результата действует бюджет 1 МиБ: сначала убирается дублирование текста и structuredContent, затем при необходимости данные заменяются сообщением с признаком _meta["native.mcp/resultOmitted"] = true.
Признак успеха или ошибки инструмента при этом сохраняется.
Не повторяйте изменяющую операцию после resultOmitted: она уже выполнена, пропущен только её результат.