# Ядро без состояния

> Что значит «MCP без состояния» в редакции 2026-07-28 - обязательные поля _meta в каждом запросе, отказ от initialize и сессий, коды ошибок

Страница: https://mcpdoc.ru/protocol/stateless/
Указатель сайта: https://mcpdoc.ru/llms.txt

В редакции `2026-07-28` всё, что нужно для обработки запроса, лежит в самом запросе. Рукопожатия `initialize` и сессий на уровне протокола больше нет. Открытое соединение - не разговор и не сессия.

описана редакция 2026-07-28, сверено со спецификацией 4 октября 2026

## Правило

Формулировка из раздела [Statelessness](https://modelcontextprotocol.io/specification/2026-07-28/basic#statelessness) базового протокола:

- сервер не должен опираться на предыдущие запросы по тому же соединению, чтобы узнать версию, возможности или клиента;
- серверу следует быть готовым к тому, что по одному соединению идут запросы разных задач и разговоров;
- серверу не следует требовать, чтобы связанные операции шли по одному соединению или через один процесс;
- состояние, которое живёт дольше одного запроса, обязано иметь явный идентификатор, и клиент передаёт его в каждом запросе.

Практический вывод для stdio: один запущенный процесс сервера - это не один разговор. Клиент может чередовать в нём несвязанные запросы.

## Что лежит в `_meta` запроса

Клиент прикладывает к каждому запросу поля с префиксом `io.modelcontextprotocol/`.

| Ключ | Обязателен | Что это |
|---|---|---|
| `io.modelcontextprotocol/protocolVersion` | да | версия протокола для этого запроса |
| `io.modelcontextprotocol/clientCapabilities` | да | возможности клиента, важные для этого запроса |
| `io.modelcontextprotocol/clientInfo` | нет, но рекомендуется | имя и версия клиента |
| `io.modelcontextprotocol/logLevel` | нет | минимальный уровень журнала для этого запроса |

```json title="Вызов инструмента"
{
  "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`.

Имена клиента и сервера никто не проверяет: стороны сообщают их сами. Спецификация не рекомендует менять по ним поведение и строить на них решения о безопасности.

## Что убрано

Список из [перечня изменений редакции](https://modelcontextprotocol.io/specification/2026-07-28/changelog).

| Было до `2026-07-28` | Что теперь |
|---|---|
| рукопожатие `initialize` и `notifications/initialized` | версия и возможности в `_meta` каждого запроса |
| сессии и заголовок `Mcp-Session-Id` | явные идентификаторы, которые сервер выдаёт и клиент передаёт как обычные аргументы |
| `ping` | удалён |
| `logging/setLevel` | уровень журнала задаётся в `_meta` запроса |
| запросы от сервера к клиенту | [многошаговые запросы](https://mcpdoc.ru/protocol/mrtr/) |
| возобновление потока 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`).

## Что читать дальше

- [Редакции и версии](https://mcpdoc.ru/protocol/versions/) - как Modern и Legacy уживаются вместе.
- [Обнаружение: server/discover](https://mcpdoc.ru/protocol/discovery/) - как узнать о сервере до первого запроса.
- [Транспорты](https://mcpdoc.ru/protocol/transports/) - какие поля дублируются в заголовках HTTP.
