MCP Docs ревизия 2026-07-28

Начало / Протокол / Шаблоны обмена

Шаблоны обмена

Запрос и ответ, многошаговые запросы, подписки

Перевод и пересказОснова: Спецификация, раздел «Message patterns»; список изменений 2026-07-28Сверено 05.10.2026, ревизия 2026-07-28Открыть .md

Базовый протокол поддерживает три шаблона обмена. Они заменили механизмы, которые зависели от долгого открытого соединения, и поэтому подходят для протокола без состояния.

Запрос и ответ#

Клиент отправляет запрос, сервер возвращает результат или ошибку. По Streamable HTTP каждый запрос — отдельный POST, а ответ — один объект JSON или поток SSE, привязанный к запросу. Запросы, которые идут по потоку, могут нести уведомления о ходе выполнения до итогового ответа.

Многошаговые запросы (MRTR)#

Многошаговый запрос (MRTR). Схема, по которой сервер возвращает промежуточный результат input_required, а клиент повторяет исходный запрос, добавив ответы. В глоссарии (Multi Round-Trip Requests, MRTR) заменил прежний подход, где сервер сам посылал клиенту запросы roots/list, sampling/createMessage и elicitation/create. Такие запросы требовали открытого потока от сервера к клиенту, а протокол без состояния его не предоставляет.

Работает это так.

  1. Клиент отправляет обычный запрос, например tools/call.
  2. Если серверу нужны дополнительные данные, он возвращает не итог, а результат с resultType: "input_required". Это объект InputRequiredResult. В поле inputRequests лежат запросы на недостающую информацию, каждому присвоен ключ.
  3. Клиент собирает данные (например, спрашивает пользователя) и повторяет исходный запрос с новым идентификатором JSON-RPC, добавив inputResponses и, если сервер прислал, requestState.
  4. Сервер возвращает итоговый результат или снова input_required.
json
{
  "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..."
  }
}

Повтор запроса с ответами:

json
{
  "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.

Запрос:

json
{
  "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 в потоке ответа на этот запрос. Подробное описание: оригинал.