Транспорты MCP
Как сообщения MCP передаются в редакции 2026-07-28 - stdio и Streamable HTTP, обязательные заголовки, статусы ответов, отмена запроса и статус устаревшего HTTP+SSE
описана редакция 2026-07-28, сверено со спецификацией 4 октября 2026
Статус транспортов
Заголовок раздела «Статус транспортов»| Транспорт | Статус | Где описан |
|---|---|---|
| stdio | действует | stdio |
Streamable HTTP в форме 2026-07-28 |
действует | Streamable HTTP |
Streamable HTTP в форме 2025-03-26 - 2025-11-25 (сессии, поток по GET) |
Legacy: описан в своих редакциях, в текущую не входит | раздел Backward Compatibility той же страницы |
HTTP+SSE из редакции 2024-11-05 |
устарел с 2025-03-26, не удалён |
реестр устаревшего |
| свой транспорт | разрешён | обзор транспортов |
Транспорта на WebSocket в спецификации 2026-07-28 нет.
Свой транспорт обязан сохранить формат JSON-RPC, шаблоны обмена и поля _meta. Если он работает поверх надёжного потока байтов (сокет Unix, TCP), спецификация рекомендует взять правила stdio: одно сообщение на строку.
Клиент запускает сервер как дочерний процесс и общается с ним через стандартные потоки.
- Сервер читает сообщения из
stdinи пишет вstdout. - Одно сообщение - одна строка. Переводов строки внутри сообщения быть не должно.
- В
stdoutсервер не должен писать ничего, кроме сообщений MCP. - В
stderrсервер может писать что угодно: журнал, отладку, ошибки. Клиенту не следует считать вывод вstderrпризнаком сбоя. - Сервер не отправляет запросы. Клиент не отправляет ответы.
{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}{"jsonrpc":"2.0","id":1,"result":{"resultType":"complete","tools":[],"ttlMs":0,"cacheScope":"private"}}Отмена. Клиент отправляет уведомление notifications/cancelled с номером запроса. Серверу следует остановить работу как можно скорее. Присылать по этому запросу новые сообщения он не должен.
Завершение. Клиенту следует закрыть stdin сервера и подождать выхода процесса. Если процесс не вышел за разумное время, клиент завершает его принудительно: в POSIX это обычно SIGTERM, затем SIGKILL. Серверу следует выходить сразу, как только stdin закрыт.
Сбой процесса. Клиенту следует перезапустить сервер. Незавершённые запросы теряются, их можно повторить.
Streamable HTTP
Заголовок раздела «Streamable HTTP»Сервер работает как отдельный сервис и даёт один адрес, например https://example.com/mcp. Этот адрес принимает POST.
- Каждое сообщение клиента - отдельный POST.
- Клиент обязан указать в
Acceptоба типа:application/jsonиtext/event-stream. - На запрос сервер отвечает либо одним объектом JSON, либо потоком SSE, привязанным к этому запросу. Клиент обязан понимать оба варианта.
- В потоке сервер может прислать уведомления по этому запросу, например о ходе выполнения, а затем итоговый ответ.
- Сервер не отправляет по потоку собственные запросы.
Обязательные заголовки
Заголовок раздела «Обязательные заголовки»| Заголовок | Откуда значение | Когда нужен |
|---|---|---|
MCP-Protocol-Version |
версия из _meta запроса |
в каждом POST |
Mcp-Method |
поле method |
в каждом запросе |
Mcp-Name |
params.name или params.uri |
для tools/call, resources/read, prompts/get |
Mcp-Param-{имя} |
аргумент инструмента, помеченный в схеме свойством x-mcp-header |
когда сервер так пометил параметр |
Заголовки повторяют тело запроса, чтобы балансировщики и шлюзы могли направлять запросы, не разбирая JSON. Источником истины остаётся тело.
POST /mcp HTTP/1.1Content-Type: application/jsonAccept: application/json, text/event-streamMCP-Protocol-Version: 2026-07-28Mcp-Method: tools/callMcp-Name: get_weather
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "get_weather", "arguments": { "location": "Seattle, WA" }, "_meta": { "io.modelcontextprotocol/protocolVersion": "2026-07-28", "io.modelcontextprotocol/clientCapabilities": {} } }}Если значение нельзя записать обычными символами ASCII (например, в нём кириллица), клиент обязан закодировать его в Base64 и обернуть так: =?base64?ЗНАЧЕНИЕ?=. Правило действует для Mcp-Name и Mcp-Param-{имя}.
Статусы ответов
Заголовок раздела «Статусы ответов»| Ситуация | Статус HTTP | Ошибка JSON-RPC |
|---|---|---|
| заголовок не совпал с телом, отсутствует или содержит недопустимые символы | 400 |
-32020 HeaderMismatch |
| сервер не поддерживает запрошенную версию | 400 |
-32022 UnsupportedProtocolVersion |
| клиент не объявил нужную возможность | 400 |
-32021 MissingRequiredClientCapability |
| сервер не знает такого метода | 404 |
-32601 |
заголовок Origin есть и он недопустим |
403 |
необязательно |
| принято уведомление | 202 |
тела нет |
Отмена и обрыв
Заголовок раздела «Отмена и обрыв»Клиент отменяет запрос, закрывая поток ответа. Отдельное уведомление на HTTP не нужно.
Возобновить оборванный поток нельзя: заголовок Last-Event-ID не поддерживается. Клиент отправляет запрос заново с новым id.
Открывая поток SSE, серверу следует добавлять заголовок X-Accel-Buffering: no, чтобы обратный прокси не задерживал события. Для долгих потоков спецификация советует время от времени присылать строку-комментарий SSE, чтобы соединение не закрылось по простою.
Защита адреса
Заголовок раздела «Защита адреса»Три требования из раздела Security & Endpoint.
- Сервер обязан проверять заголовок
Originво всех входящих соединениях. Это защита от подмены DNS (DNS rebinding). - Локально запущенному серверу следует слушать только
127.0.0.1, а не все интерфейсы. - Серверу следует проверять подлинность всех соединений. Как устроена авторизация, описано в разделе «Модель авторизации».
Авторизация из спецификации относится к HTTP. На stdio учётные данные берутся из окружения процесса.
Что отвечает новый сервер старому клиенту
Заголовок раздела «Что отвечает новый сервер старому клиенту»Серверу, который поддерживает только 2026-07-28, спецификация рекомендует:
- на GET и DELETE по своему адресу отвечать
405; - заголовок
Mcp-Session-Idигнорировать и номера сессий не выдавать; - заголовок
Last-Event-IDигнорировать.
HTTP+SSE: устарел, но не удалён
Заголовок раздела «HTTP+SSE: устарел, но не удалён»Срок в реестре - это момент, с которого функцию можно удалить, а не дата удаления. Само удаление - отдельное решение ведущих разработчиков при подготовке очередной редакции. Новым реализациям HTTP+SSE использовать не следует, существующим следует перейти на Streamable HTTP.
Как клиенту работать и со старым, и с новым сервером, спецификация описывает так: отправить POST с новым набором заголовков; если пришёл ответ 400, 404 или 405 и в теле нет распознанной ошибки Modern, отправить GET и ждать событие endpoint - это признак сервера на HTTP+SSE.
Что читать дальше
Заголовок раздела «Что читать дальше»- Редакции и версии - как определить эпоху сервера.
- Что устарело - полный реестр и сроки.
- HTTP-развёртывание - практическая сторона: прокси, сертификаты, запуск.