Руководство по миграции на stateless-протокол MCP: что меняет релиз-кандидат 2026-07-28 для каждого AI-шлюза
Спецификация MCP 2026-07-28 удаляет session ID и initialize-рукопожатие. Пошаговое руководство по миграции: сравнение кода до и после, настройка балансировщика нагрузки, обновление SDK, паттерн явных хендлов и путь отката.
Руководство по миграции на stateless-протокол MCP: что меняет релиз-кандидат 2026-07-28
Спецификация MCP 2026-07-28 удаляет session ID и initialize-рукопожатие. Если вы управляете MCP-сервером, прокси или шлюзом — каждый запрос теперь самодостаточен и может быть обработан любым экземпляром сервера. Это руководство проведёт вас через миграцию шаг за шагом: сравнение кода до/после, изменения инфраструктуры, обновление SDK и путь отката — чтобы вы были готовы к финальной дате спецификации 28 июля.
Мы написали это руководство, потому что stateless-изменение MCP напрямую влияет на маршрутизацию AI-трафика через шлюзы. TheRouter маршрутизирует OpenAI-совместимые запросы через настроенных провайдеров, и когда операторы шлюзов меняют обработку MCP-трафика, политики routing и fallback должны следовать за ними. Источник: MCP 2026-07-28 Release Candidate, получено 2026-07-20.
Что изменилось: до и после
Ключевое изменение в MCP 2026-07-28 — удаление двух функций протокола, которые требовали stateful-развёртывания:
- Рукопожатие
initialize/initialized(удалено SEP-2575). Версия протокола, информация о клиенте и capabilities теперь передаются в_metaкаждого запроса. Новый методserver/discoverзаменяет обмен capabilities. - Header
Mcp-Session-Idи протокольные сессии (удалены SEP-2567). Больше нет session pinning, нет необходимости в shared session store.
До (2025-11-25): Клиент обязан сначала отправить initialize-запрос, получить session ID и включать Mcp-Session-Id header в каждый последующий вызов:
// Шаг 1: Initialize-рукопожатие
POST /mcp
{"jsonrpc":"2.0","id":1,"method":"initialize",
"params":{"protocolVersion":"2025-11-25","capabilities":{},
"clientInfo":{"name":"my-app","version":"1.0"}}}
// Сервер возвращает Mcp-Session-Id: 1868a90c-3a3f-4f5b
// Шаг 2: Каждый последующий вызов несёт session header
POST /mcp
Mcp-Session-Id: 1868a90c-3a3f-4f5b
{"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"search","arguments":{"q":"otters"}}}
После (2026-07-28): Один самодостаточный запрос, который может обработать любой экземпляр:
POST /mcp
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
Content-Type: application/json
{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"search","arguments":{"q":"otters"},
"_meta":{"io.modelcontextprotocol/clientInfo":{"name":"my-app","version":"1.0"}}}}
Нет рукопожатия, нет session ID, ничто не привязывает к конкретному экземпляру. Источник: MCP 2026-07-28 Release Candidate, получено 2026-07-20.
Чек-лист миграции: инфраструктура
- Меняйте три значения, а не три SDK. Замените
api_key,base_urlиmodelв существующем клиенте OpenAI. Код запроса и ответа оставьте неизменным. - Сопоставьте model ID явно. ID модели у целевого провайдера почти никогда не совпадает с OpenAI ID. Держите словарь
{ openai_id: target_id }вне бизнес-логики. - Проверьте формат streaming. SSE-чанки должны соответствовать контракту OpenAI:
data: {...}+data: [DONE]. Прогоните один streaming вызов до продакшена. - Проверьте rate-limit заголовки. Некоторые провайдеры не возвращают
x-ratelimit-*. Добавьте обёртку с безопасным дефолтом. - Оставьте путь отката. Раскатайте замену под feature flag, гоняйте оба endpoint в shadow-режиме 24 часа, затем переключайтесь.
Шаг 1: Отключите sticky sessions и session affinity
Если ваш балансировщик нагрузки (NGINX, HAProxy, AWS ALB, Azure App Service ARR) использует sticky routing на основе Mcp-Session-Id или cookie affinity для MCP-эндпоинтов — отключите это. Протокол теперь stateless, любой экземпляр сервера может обработать любой запрос.
NGINX до:
upstream mcp_backend {
ip_hash; # или sticky cookie
server mcp1:8080;
server mcp2:8080;
}
NGINX после:
upstream mcp_backend {
# Round-robin, sticky sessions не нужны
server mcp1:8080;
server mcp2:8080;
}
Azure App Service: Установите clientAffinityEnabled: false в ARM-шаблоне или конфигурации App Service. Источник: Microsoft Tech Community — MCP Stateless on App Service, получено 2026-07-20.
Шаг 2: Настройте routing по Mcp-Method headers
Streamable HTTP transport теперь требует header Mcp-Method для каждого запроса и Mcp-Name для вызовов инструментов, чтения ресурсов и запроса prompts (SEP-2243). Это позволяет вашему шлюзу маршрутизировать, ограничивать частоту запросов или логировать MCP-трафик без разбора JSON-RPC body.
Пример NGINX — routing по Mcp-Method:
location /mcp {
# Отдельные лимиты для tools/call и tools/list
if ($http_mcp_method = "tools/call") {
set $rate_zone tool_calls;
}
if ($http_mcp_method = "tools/list") {
set $rate_zone tool_lists;
}
proxy_pass http://mcp_backend;
}
Серверы отклоняют запросы, в которых headers и body не совпадают. Убедитесь, что ваш reverse proxy сохраняет headers Mcp-Method и Mcp-Name при проксировании.
Шаг 3: Выведите из эксплуатации shared session store
Если вы использовали Redis, Memcached или базу данных для разделения маппингов Mcp-Session-Id → состояние между экземплярами MCP-серверов — эта инфраструктура больше не нужна для состояния протокола. Вы можете вывести её из эксплуатации или перепрофилировать для состояния приложения (см. паттерн явных хендлов ниже). Источник: 4sysops — MCP 2026-07-28 Overview, получено 2026-07-20.
Шаг 4: Включите кеширование ответов
Результаты списков и чтения ресурсов теперь содержат поля ttlMs и cacheScope (SEP-2549), по аналогии с HTTP Cache-Control. Ваш шлюз может кешировать ответы tools/list на время, указанное в ttlMs, а cacheScope сообщает, можно ли разделять ответ между пользователями ("global") или только для одного пользователя.
Это устраняет необходимость держать SSE-поток открытым только для отслеживания изменений списка инструментов.
Чек-лист миграции: SDK и серверный код
Шаг 5: Обновите MCP SDK
Beta-версии всех четырёх SDK Tier 1 доступны сейчас. Источник: Beta SDKs for the 2026-07-28 MCP Spec Release Candidate, получено 2026-07-20.
| SDK | Beta-версия | Команда установки |
|---|---|---|
| Python | v2.0.0b1 | uv add "mcp[cli]==2.0.0b1" или pip install "mcp[cli]==2.0.0b1" |
| TypeScript | v2 beta | npm install @modelcontextprotocol/server@beta |
| Go | v1.7.0-pre.1 | Pre-release тег на существующем модуле |
| C# | 2.0.0-preview.1 | Установите preview-пакет ModelContextProtocol |
Важно для авторов библиотек: Если вы публикуете библиотеку, зависящую от Python-пакета mcp, добавьте верхнюю границу сейчас (например, mcp>=1.27,<2), чтобы релиз v2 не застал ваших пользователей врасплох.
Шаг 6: Удалите код initialize-рукопожатия
Если ваш сервер реализует собственный обработчик initialize — его можно удалить. В новой модели:
- Информация о клиенте приходит из
_meta.io.modelcontextprotocol/clientInfoв каждом запросе - Версия протокола приходит из HTTP-header
MCP-Protocol-Version - Capabilities сервера предоставляются через новый метод
server/discoverвместо ответа наinitialize
Python v1 (до):
@app.handle("initialize")
async def handle_initialize(params):
return {"protocolVersion": "2025-11-25",
"capabilities": {"tools": {}},
"serverInfo": {"name": "my-server", "version": "1.0"}}
Python v2 (после):
from mcp.server import MCPServer
mcp = MCPServer("my-server")
@mcp.tool()
def search(q: str) -> str:
"""Поиск."""
return f"Results for {q}"
# server/discover обрабатывается SDK автоматически
Шаг 7: Используйте паттерн явных хендлов для stateful-инструментов
Удаление протокольной сессии не означает, что ваше приложение не может хранить состояние. Если инструментам нужно сохранять состояние между вызовами — создайте явный хендл и пусть модель передаёт его как аргумент:
@mcp.tool()
def create_session(config: dict) -> dict:
"""Создать рабочую сессию и вернуть хендл."""
session_id = store.create(config) # сохранить в Redis/БД
return {"session_id": session_id}
@mcp.tool()
def continue_work(session_id: str, action: str) -> dict:
"""Продолжить работу в существующей сессии."""
state = store.get(session_id) # получить из shared store
result = process(state, action)
store.update(session_id, state)
return result
Этот паттерн мощнее скрытого session state: модель видит хендл, может комбинировать его между инструментами, рассуждать о нём и передавать между шагами. Источник: MCP 2026-07-28 Release Candidate — Stateless Protocol, Stateful Applications, получено 2026-07-20.
Шаг 8: Обновите обработку кодов ошибок
Код ошибки для отсутствующего ресурса меняется с кастомного MCP -32002 на стандартный JSON-RPC -32602 (Invalid Params) согласно SEP-2164. Обновите весь клиентский код, который проверяет литеральное значение -32002.
- if error.code == -32002:
- handle_resource_not_found()
+ if error.code == -32602:
+ handle_resource_not_found()
Шаг 9: Обработайте устаревшие функции
В этом релизе три функции помечены как deprecated (SEP-2577):
| Функция | Замена | Срочность |
|---|---|---|
| Roots | Параметры инструментов, URI ресурсов или конфигурация сервера | Низкая — работает 12+ месяцев |
| Sampling | Прямая интеграция с API LLM-провайдеров | Низкая — работает 12+ месяцев |
| Logging | stderr для stdio transport; OpenTelemetry для структурированной observability | Низкая — работает 12+ месяцев |
Это аннотационные deprecation. Методы, типы и capability flags продолжают работать в этом релизе и во всех версиях спецификации, опубликованных в течение года. Но планируйте миграцию уже сейчас.
Запросы от сервера к клиенту: Multi Round-Trip Requests (MRTR)
Если ваш сервер отправляет запросы клиенту во время вызова инструмента (например, диалоги подтверждения через elicitation), механизм изменился. Вместо удержания SSE-потока сервер теперь возвращает InputRequiredResult:
{
"resultType": "inputRequired",
"inputRequests": {
"confirm": {
"type": "elicitation",
"message": "Удалить 3 файла?",
"schema": {"type": "boolean"}
}
},
"requestState": "eyJzdGVwIjox..."
}
Клиент собирает ответы и повторно отправляет исходный вызов с inputResponses и переданным requestState. Любой экземпляр сервера может обработать повторный запрос, потому что всё необходимое содержится в payload. Источник: MCP 2026-07-28 Release Candidate — Multi Round-Trip Requests, получено 2026-07-20.
Путь отката
28 июля ничего не сломается принудительно. Новые SDK поддерживают обратную совместимость:
- Новые клиенты и старые серверы: Клиенты с протоколом 2026-07-28 автоматически возвращаются к
initialize-рукопожатию при подключении к серверам версии 2025-11-25 и старше. - Новые серверы и старые клиенты: Python v2 серверы отвечают как на устаревшее
initialize-рукопожатие, так и наserver/discover, поэтому существующие клиенты продолжают подключаться. - Смешанное развёртывание: Во время перехода можно одновременно запускать экземпляры серверов 2025-11-25 и 2026-07-28. Старые экземпляры сохраняют session affinity, новые — stateless.
Если миграция столкнётся с проблемами — откатите SDK на v1 и снова включите sticky sessions. Старый протокол продолжает работать.
Изменение стоимости
Stateless-протокол снижает инфраструктурные затраты тремя способами:
- Нет shared session store. Больше не нужен Redis или Memcached для хранения состояния протокольных сессий между экземплярами.
- Проще балансировка нагрузки. Round-robin вместо sticky sessions — не нужны балансировщики с поддержкой affinity или сложные health checks.
- Кеширование ответов.
ttlMsиcacheScopeв результатах списков позволяют шлюзам кешировать ответыtools/list, сокращая избыточные вызовы.
Компромисс: если ваши инструменты имеют сложные stateful-workflow, теперь вы управляете состоянием явно (Redis, БД и т.д.) вместо того, чтобы полагаться на протокол. Но это состояние всегда лучше было выносить наружу — протокольная сессия была удобством, а не решением.
Интеграция с TheRouter
TheRouter маршрутизирует OpenAI-совместимые запросы через настроенных провайдеров и поддерживает routing и fallback провайдеров/моделей, когда продуктовые пути поддерживают это. Stateless-изменение MCP влияет на то, как операторы шлюзов проксируют MCP-трафик наряду со стандартными вызовами LLM API:
- Routing на основе headers. Headers
Mcp-MethodиMcp-Nameпозволяют маршрутизировать MCP и LLM API трафик через один шлюз с разными правилами rate limiting и routing. - Единый fallback. Если MCP-сервер недоступен — применяются те же паттерны fallback routing, что и для LLM API провайдеров. См. наше руководство по LLM API Fallback Routing.
- Согласованная миграция. Если вы мигрируете с OpenAI на TheRouter — stateless-изменение MCP упрощает шлюзовый слой. См. наше руководство по миграции с OpenAI на TheRouter.
Таймлайн и следующие шаги
| Дата | Событие |
|---|---|
| 21 мая 2026 | Release candidate заморожен |
| Сейчас (июль 2026) | Beta-версии SDK доступны для всех четырёх Tier 1 SDK |
| 28 июля 2026 | Публикация финальной спецификации |
| ~Январь 2027 | Устаревшие функции (Roots, Sampling, Logging) — самое раннее возможное удаление |
Пункты действий:
- Протестируйте beta SDK на ваших рабочих нагрузках сейчас.
- Проведите аудит конфигурации балансировщика нагрузки и шлюза на предмет session affinity.
- Проверьте весь код, зависящий от
Mcp-Session-Id,initializeили кода ошибки-32002. - Спланируйте миграцию stateful-инструментов на паттерн явных хендлов.
- Обновите мониторинг для отслеживания нового header
Mcp-Methodв целях observability.
Источники
- MCP 2026-07-28 Release Candidate, получено 2026-07-20
- Beta SDKs for 2026-07-28, получено 2026-07-20
- MCP Specification — Transports, получено 2026-07-20
- 4sysops — MCP 2026-07-28 Overview, получено 2026-07-20
- Microsoft Tech Community — MCP Stateless on App Service, получено 2026-07-20