Начало / Протокол / Шаблоны обмена
Шаблоны обмена
Запрос и ответ, многошаговые запросы, подписки
Базовый протокол поддерживает три шаблона обмена. Они заменили механизмы, которые зависели от долгого открытого соединения, и поэтому подходят для протокола без состояния.
Запрос и ответ#
Клиент отправляет запрос, сервер возвращает результат или ошибку. По Streamable HTTP каждый запрос — отдельный POST, а ответ — один объект JSON или поток SSE, привязанный к запросу. Запросы, которые идут по потоку, могут нести уведомления о ходе выполнения до итогового ответа.
Многошаговые запросы (MRTR)#
Многошаговый запрос (MRTR). Схема, по которой сервер возвращает промежуточный результат input_required, а клиент повторяет исходный запрос, добавив ответы. В глоссарии (Multi Round-Trip Requests, MRTR) заменил прежний подход, где сервер сам посылал клиенту запросы roots/list, sampling/createMessage и elicitation/create. Такие запросы требовали открытого потока от сервера к клиенту, а протокол без состояния его не предоставляет.
Работает это так.
- Клиент отправляет обычный запрос, например
tools/call. - Если серверу нужны дополнительные данные, он возвращает не итог, а результат с
resultType: "input_required". Это объектInputRequiredResult. В полеinputRequestsлежат запросы на недостающую информацию, каждому присвоен ключ. - Клиент собирает данные (например, спрашивает пользователя) и повторяет исходный запрос с новым идентификатором JSON-RPC, добавив
inputResponsesи, если сервер прислал,requestState. - Сервер возвращает итоговый результат или снова
input_required.
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"resultType": "input_required",
"inputRequests": {
"github_login": {
"method": "elicitation/create",
"params": {
"mode": "form",
"message": "Please provide your GitHub username",
"requestedSchema": {
"type": "object",
"properties": { "name": { "type": "string" } },
"required": ["name"]
}
}
}
},
"requestState": "eyJsb2NhdGlvbiI6Ik5ldyBZb3JrIn0..."
}
}Повтор запроса с ответами:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": { "location": "New York" },
"inputResponses": {
"github_login": { "action": "accept", "content": { "name": "octocat" } }
},
"requestState": "eyJsb2NhdGlvbiI6Ik5ldyBZb3JrIn0..."
}
}Идентификатор JSON-RPC повторного запроса ДОЛЖЕН отличаться от идентификатора первого. Поле requestState непрозрачно для клиента: сервер кладёт в него то, что нужно для продолжения, и получает обратно.
Подписка на изменения (subscriptions/listen)#
Уведомления об изменениях подписочные: клиент заранее выбирает, какие из них хочет получать. Для этого он отправляет запрос subscriptions/listen с фильтром notifications. Ответ на него — долгий поток, который остаётся открытым.
Типы уведомлений, которые клиент может выбрать:
| Фильтр | Что присылает сервер |
|---|---|
toolsListChanged |
notifications/tools/list_changed при изменении перечня инструментов. |
promptsListChanged |
Уведомление при изменении перечня шаблонов запросов. |
resourcesListChanged |
Уведомление при изменении перечня ресурсов. |
resourceSubscriptions |
notifications/resources/updated по перечисленным URI. |
Запрос:
{
"jsonrpc": "2.0",
"id": 4,
"method": "subscriptions/listen",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": { "name": "example-client", "version": "1.0.0" },
"io.modelcontextprotocol/clientCapabilities": { "elicitation": {} }
},
"notifications": { "toolsListChanged": true }
}
}Сервер подтверждает подписку уведомлением notifications/subscriptions/acknowledged: оно первое в потоке с идентификатором подписки в _meta, а в его поле notifications указана та часть фильтра, которую сервер согласен выполнять (неподдерживаемые типы пропущены). Дальше каждое уведомление в потоке несёт io.modelcontextprotocol/subscriptionId в _meta. Значение равно идентификатору запроса subscriptions/listen, поэтому клиент сопоставляет уведомление с подпиской.
- Уведомление доступно, только если сервер объявил соответствующую возможность, например
"listChanged": trueуtools. - Доставка «по возможности»: нет гарантии, что каждое уведомление будет отправлено или получено, особенно при переподключении. Свежесть результатов клиентам СЛЕДУЕТ дополнительно поддерживать опросом.
- Уведомления, привязанные к запросу, такие как
notifications/progressиnotifications/message, идут в потоке ответа на тот запрос, к которому относятся, а не в потоке подписки. - Получив уведомление, клиент обычно запрашивает обновлённый перечень (
tools/list).
Отмена#
По Streamable HTTP закрытие потока ответа SSE — это отмена запроса. По stdio используется уведомление notifications/cancelled. Подробности: «Транспорты».
Прогресс#
Клиент может подписать запрос на уведомления о ходе выполнения, передав progressToken в _meta. Сервер присылает notifications/progress в потоке ответа на этот запрос. Подробное описание: оригинал.