Ядро без состояния
Что значит «MCP без состояния» в редакции 2026-07-28 - обязательные поля _meta в каждом запросе, отказ от initialize и сессий, коды ошибок
описана редакция 2026-07-28, сверено со спецификацией 4 октября 2026
Правило
Заголовок раздела «Правило»Формулировка из раздела Statelessness базового протокола:
- сервер не должен опираться на предыдущие запросы по тому же соединению, чтобы узнать версию, возможности или клиента;
- серверу следует быть готовым к тому, что по одному соединению идут запросы разных задач и разговоров;
- серверу не следует требовать, чтобы связанные операции шли по одному соединению или через один процесс;
- состояние, которое живёт дольше одного запроса, обязано иметь явный идентификатор, и клиент передаёт его в каждом запросе.
Практический вывод для stdio: один запущенный процесс сервера - это не один разговор. Клиент может чередовать в нём несвязанные запросы.
Что лежит в _meta запроса
Заголовок раздела «Что лежит в _meta запроса»Клиент прикладывает к каждому запросу поля с префиксом io.modelcontextprotocol/.
| Ключ | Обязателен | Что это |
|---|---|---|
io.modelcontextprotocol/protocolVersion |
да | версия протокола для этого запроса |
io.modelcontextprotocol/clientCapabilities |
да | возможности клиента, важные для этого запроса |
io.modelcontextprotocol/clientInfo |
нет, но рекомендуется | имя и версия клиента |
io.modelcontextprotocol/logLevel |
нет | минимальный уровень журнала для этого запроса |
{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "get_weather", "arguments": { "location": "Moscow" }, "_meta": { "io.modelcontextprotocol/protocolVersion": "2026-07-28", "io.modelcontextprotocol/clientInfo": { "name": "ExampleClient", "version": "1.0.0" }, "io.modelcontextprotocol/clientCapabilities": {} } }}Запрос без обязательного поля считается некорректным: сервер обязан отклонить его с кодом -32602, а на HTTP - со статусом 400.
Сервер, в свою очередь, по рекомендации спецификации называет себя в _meta каждого результата, под ключом io.modelcontextprotocol/serverInfo.
Имена клиента и сервера никто не проверяет: стороны сообщают их сами. Спецификация не рекомендует менять по ним поведение и строить на них решения о безопасности.
Что убрано
Заголовок раздела «Что убрано»Список из перечня изменений редакции.
Было до 2026-07-28 |
Что теперь |
|---|---|
рукопожатие initialize и notifications/initialized |
версия и возможности в _meta каждого запроса |
сессии и заголовок Mcp-Session-Id |
явные идентификаторы, которые сервер выдаёт и клиент передаёт как обычные аргументы |
ping |
удалён |
logging/setLevel |
уровень журнала задаётся в _meta запроса |
| запросы от сервера к клиенту | многошаговые запросы |
возобновление потока SSE по Last-Event-ID |
не поддерживается; оборванный запрос отправляется заново с новым id |
Списки tools/list, resources/list и prompts/list больше не зависят от соединения: сервер не может показывать разные наборы «в этой сессии».
Коды ошибок
Заголовок раздела «Коды ошибок»Спецификация закрепила за собой диапазон от -32020 до -32099. Сейчас в нём три кода.
| Код | Имя | Когда |
|---|---|---|
-32020 |
HeaderMismatch |
заголовки HTTP не совпадают с телом запроса или отсутствуют |
-32021 |
MissingRequiredClientCapability |
запросу нужна возможность, которую клиент не объявил |
-32022 |
UnsupportedProtocolVersion |
сервер не поддерживает запрошенную версию |
Диапазон от -32000 до -32019 оставлен за кодами, которые реализации заняли раньше. Новые коды там выделять нельзя.
Два кода прежних редакций в 2026-07-28 не используются: -32002 («ресурс не найден», заменён на -32602) и -32042 («нужен переход по ссылке», был только в 2025-11-25).
Что читать дальше
Заголовок раздела «Что читать дальше»- Редакции и версии - как Modern и Legacy уживаются вместе.
- Обнаружение: server/discover - как узнать о сервере до первого запроса.
- Транспорты - какие поля дублируются в заголовках HTTP.