MCP убрал сессии протокола — любой сервер отвечает на любой запрос

Иллюстрация: MCP больше не требует липкой сессии к одному серверу

Многие люди уверены: свой сервер для агента в облаке — это всегда боль. Два–три запроса подряд, и вот оно: «сессия не найдена», липкий контейнер, отдельная база «ради протокола».

Им кажется, что протокол просто такой — приклеивайся к одному серверу или страдай.

Точнее, так было. В спецификации 2026-07-28 ядро стало безсессионным: каждый запрос самодостаточен, любой экземпляр сервера может ответить на любой вызов. Липкий балансировщик и общее хранилище для сессии протокола больше не нужны.

Это не гайд «как подключить помощника в редакторе кода». Это смена провода между клиентом и своим сервером.

Раньше нужно было приклеиться

Сравнение: липкая сессия MCP раньше и полный запрос без привязки сейчас

До этого релиза MCP держал двустороннее ядро с памятью на соединении. Сначала рукопожатие — «initialize» / «initialized». Потом заголовок сессии «Mcp-Session-Id». Клиент «прилипал» к одному контейнеру.

Рестарт контейнера. Выкат. Запросы прыгают между серверами без привязки. Сессия ломалась. Неудивительно.

В версии 2026-07-28 — пятый релиз; предыдущая была 2025-11-25 — официальный блог MCP и changelog зафиксировали переход: запрос–ответ без состояния на уровне протокола.

Убрали рукопожатие «initialize» / «notifications/initialized». Убрали идентификатор сессии «Mcp-Session-Id». Списки инструментов и прочие list-методы больше не «зависят от соединения».

Вместо рукопожатия на каждом запросе в «_meta» идут версия протокола и возможности клиента. Клиент желательно передаёт «clientInfo», сервер — «serverInfo» в ответе. Версии не сошлись — ошибка неподдерживаемой версии. Всё.

Метод «server/discover» серверы обязаны реализовать. Клиент может вызвать заранее — выбрать версию, пощупать сервер. Перед каждым вызовом инструмента он не обязателен.

Какой смысл был в липком контейнере

Схема: полный запрос MCP уходит на любой экземпляр сервера без липкой базы

Какой смысл требовать «липкий» сервер, если любой экземпляр теперь отвечает на любой запрос?

Обычный круговой разброс запросов без липкой привязки. Рестарт контейнера или выкат не «убивает сессию протокола». Serverless — в разборе Google Developers Blog от 5 августа 2026 про Cloud Run и Cloud Functions — может уходить в ноль без отдельного хранилища сессий протокола.

На Streamable HTTP POST обязательны заголовки «Mcp-Method», «Mcp-Name» и «MCP-Protocol-Version»: они зеркалят JSON-тело запроса. Прокси, WAF и балансировщик могут роутить и логировать, не разбирая тело. Заголовок и тело разошлись — ошибка несовпадения заголовков.

Практический сигнал из продакшена: GitHub MCP Server (changelog 23 июля 2026, подтверждение в посте Google 5 августа) убрал Redis session store целиком. Пропали запись в базу на каждое подключение и чтение на каждый вызов.

Claude / Anthropic в день релиза спеки — 28 июля 2026 — объявили поддержку новой версии: катит по продуктам Claude. Не «уже везде на сто процентов». В экосистеме — больше 400 млн загрузок SDK в месяц и 950+ серверов в каталоге connectors.

Отдельного официального анонса Cursor «мы включили 2026-07-28» на момент проверки нет. Речь про формат провода своих и удалённых серверов, не про дату поддержки клиента Cursor.

Память приложения — это не сессия протокола

Чеклист: память приложения через явный id, не через сессию протокола MCP

Убрать сессию протокола не значит «приложение без памяти».

Если между вызовами нужна корзина, задача или страница пагинации — паттерн простой: явный идентификатор. Инструмент возвращает «basket_id» / «job_id» / другой id. Модель передаёт его обычным аргументом следующего вызова.

Redis, Cosmos и любая база остаются для бизнес-данных по этому идентификатору. Запрещён не Redis вообще. Запрещён обязательный session store ради «Mcp-Session-Id».

Все просто: протокол больше не прячет память в заголовке сессии. Если память нужна — она лежит в аргументах, на виду.

Если серверу нужно уточнение у пользователя (раньше часто держали длинный поток SSE): вместо удержания соединения сервер может вернуть «нужен ввод» с состоянием запроса. Клиент повторяет исходный вызов с ответами. Продолжить может любой экземпляр сервера.

Долгие задачи вынесены в расширение Tasks: опрос статуса вместо старого блокирующего ожидания результата в ядре. Для кэша списков — «ttlMs» и область кэша public/private, чтобы не держать SSE «список tools изменился».

Что проверить на своём удалённом MCP

Если сервер ещё на старой модели сессий, при миграции на 2026-07-28:

  • обновить SDK на сборку со спецификацией 2026-07-28 (официальные Tier-1: TypeScript, Python, Go, C#; часть пакетов ещё в beta — сверять актуальные релизы, не цепляться к одной beta-пин-версии из обзора);
  • убрать обработку session / ожидание «initialize» и «Mcp-Session-Id»;
  • читать версию и возможности из «_meta» на каждом запросе;
  • реализовать «server/discover»;
  • валидировать HTTP-заголовки метода и имени;
  • состояние с заголовка сессии перенести в явные идентификаторы в аргументах инструментов;
  • проверить хардкод старого кода «ресурс не найден» (−32002) — в новой спеке это другой код (−32602); иначе ошибка сломается тихо.

Типичные ловушки. Оставить липкую привязку у балансировщика «на всякий случай» как требование протокола. Ждать от сервера старое рукопожатие на клиенте новой спеки. Думать, что без сессии нельзя помнить корзину — нужен явный id в аргументах.

Окно устареваний — не меньше 12 месяцев. Roots уходят в явные параметры и URI. Старый HTTP+SSE — в Streamable HTTP. Оборванный SSE: клиент обязан повторить запрос с новым id — возобновление по Last-Event-ID убрано.

Коротко

MCP перестал требовать «приклеиться к одному контейнеру», как обычный HTTP API.

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

Куда дальше

Разборы MCP, агентов и Cursor — в канале Ковчег в Telegram: t.me/maya_pro. Тот же ритм в MAX: max.ru/maya_pro. Практика Cursor + Make + AI: kv-ai.ru/obuchenie-po-make.

Источники по фактам релиза: официальный блог MCP (2026-07-28), changelog спецификации, Google Developers Blog (5 авг 2026), GitHub Changelog, Claude: MCP 2026-07-28.