Skip to content

Контракт init_eva_session ​

Как платформа привязывает сессию MCP к чату, что передаёт сервису, сколько живут выданные доступы и почему модель их никогда не видит.

Про имя ​

Инструмент называется init_eva_session. В некоторых документах он упоминается как eva_mcp_init, такого имени в коде нет ни в платформе, ни в сервисах. Правильное имя одно, оно приведено выше.

Зачем он нужен ​

Сервису MCP нужно знать, с каким чатом он работает и как ему дотянуться до файлов этого чата. Передавать эти сведения через параметры рабочих инструментов нельзя: их формирует модель, а модель не должна видеть ни ключей доступа, ни адресов хранилища.

Поэтому есть отдельный инструмент. Его вызывает Runtime, он скрыт от модели, и только через него передаются доступы.

Кто и когда вызывает ​

Вызывает только Runtime. Модель этот инструмент не видит в своём списке и вызвать не может.

Вызов происходит перед каждым обращением к инструментам сервиса, а не один раз на чат. Это же и есть механизм обновления доступа: повторный вызов с тем же чатом просто перезаписывает сохранённые данные.

Что передаётся ​

json
{
  "chatId": "sess_123",
  "userId": "usr_456",
  "workspace": {
    "kind": "chat",
    "title": "Название чата"
  },
  "capabilities": {
    "sessionFiles": true,
    "uiBlocks": true,
    "chatS3": true
  },
  "chatS3": {
    "endpoint": "http://localhost:3000/api/chat-s3",
    "bucket": "chat-files",
    "prefix": "sessions/sess_123/",
    "region": "auto",
    "authMode": "query-token",
    "token": "eyJ....sig",
    "expiresAt": "2026-07-30T10:30:00.000Z"
  }
}

Обязательное поле только одно.

ПолеОбязательноЧто означает
chatIdдаИдентификатор чата. Без косых черт
userIdнетИдентификатор пользователя
workspaceнетВид рабочего пространства и его название
capabilitiesнетЧто умеет платформа в этом чате
chatS3нетДоступ к файлам чата. Если его нет, сервис работает без файлов

Минимальный вызов выглядит так:

json
{ "chatId": "sess_123" }

Поля доступа к файлам ​

ПолеЧто означает
endpointАдрес слоя доступа к файлам, всегда заканчивается на /api/chat-s3
bucketИмя корзины, по умолчанию chat-files
prefixГраницы чата, всегда sessions/<chatId>/
regionВсегда auto. Сервисы его сохраняют, но не используют
authModeВсегда query-token. Другое значение сервис обязан отклонить
tokenКлюч доступа
expiresAtВремя истечения ключа

Что возвращается ​

json
{
  "ok": true,
  "sessionBound": true,
  "serverSessionId": "mcp_local_sess_abc"
}

Значение serverSessionId сервис формирует сам, платформа его не разбирает.

Что сервис обязан проверить ​

Порядок проверок жёстко описан в общем регламенте сервисов.

  1. Сначала личность: chatId не пустой и не содержит косых черт. Иначе ошибка неверной сессии.
  2. Затем разбор доступа: обязательны адрес, корзина, префикс и ключ. Значение authMode, отличное от query-token, отклоняется. Адрес, корзина и префикс приводятся к единому виду.
  3. Затем главная проверка доверия: префикс обязан быть в точности sessions/<chatId>/. Если нет, сессия отклоняется.
  4. Сохраняется только простой набор данных, пригодный к сериализации. Живые объекты вроде открытых соединений сохранять нельзя.
  5. Возвращается ответ с признаком привязки.

Третья проверка это и есть защита

Именно совпадение префикса с идентификатором чата не даёт сервису обратиться к файлам другого чата. Скрытость инструмента от модели защитой не считается.

Два разных срока ​

Их нельзя путать.

СрокКто управляетПорядок величины
Время жизни состояния сессииБиблиотека сервисаЧасы
Время жизни ключа доступаПлатформа, поле expiresAt15 минут

Проверять нужно именно второй срок, и делать это перед каждым обращением к хранилищу.

Пример отклонения ​

Попытка привязаться к чужому чату:

json
{
  "chatId": "sess_test",
  "chatS3": { "prefix": "sessions/another_chat/", "...": "..." }
}

Ответ: ошибка с кодом неверной сессии.

Резервный инструмент list_eva_tenants ​

Платформа умеет спрашивать у сервиса список пространств, если сервис объявляет инструмент list_eva_tenants. Он тоже скрыт от модели и вызывается при подключении и проверке источника.

Ответ имеет вид {"tenants": [{"id", "name", "isDefault"}]}, ровно одно пространство должно быть помечено основным.

Ни один сервис его не реализует

Ни один из переданных сервисов этот инструмент не объявляет, поэтому платформа считает многопространственность выключенной и поле tenantId в вызов не добавляет. Если источник когда-нибудь пометить многопространственным, все четыре реализации init_eva_session получат незнакомый параметр, которого нет в их сигнатурах.

Что важно знать про обработку ошибок ​

Сервисы возвращают неудачу в виде обычного успешного ответа MCP, внутри которого стоит признак ok: false и код ошибки. Платформа при этом смотрит только на признак ошибки самого протокола MCP.

Неудачная привязка может быть принята за успешную

Для сервисов, у которых init_eva_session завёрнут в общий формат ответа, платформа не увидит неудачу привязки и продолжит работу. Чтобы платформа увидела неудачу, привязку сессии стоит оставлять без общей обёртки: тогда ошибка приходит как настоящая ошибка протокола.

Документация платформы EVA