Производительность
Что протокол MCP редакции 2026-07-28 даёт для скорости и масштабирования - отсутствие сессий, подсказки кэширования, отмена, потоки SSE - и где начинается практика
описана редакция 2026-07-28, сверено со спецификацией и документацией nginx 4 октября 2026
Что даёт протокол
Заголовок раздела «Что даёт протокол»| Средство | Что оно даёт | Сила | Где описано |
|---|---|---|---|
| Нет сессий | запрос можно отдать любому экземпляру | сервер не должен полагаться на прежние запросы | основы протокола |
ttlMs, cacheScope | клиент реже запрашивает списки заново | сервер обязан их указывать | Caching |
| Постоянный порядок инструментов | стабильный кэш списка и кэш запроса к модели | серверу следует | Tools |
| Постраничная выдача | длинный список не приходит одним ответом | размер страницы выбирает сервер | Pagination |
| Отмена | сервер не тратит ресурсы на ненужный запрос | серверу следует остановить работу | Cancellation |
X-Accel-Buffering: no | события SSE не задерживаются в прокси | серверу следует | Streamable HTTP |
Заголовки Mcp-Method, Mcp-Name | посредник направляет запрос, не разбирая тело | Mcp-Method обязателен во всех запросах, Mcp-Name - в tools/call, resources/read и prompts/get | там же |
Нет сессий - нет привязки к экземпляру
Заголовок раздела «Нет сессий - нет привязки к экземпляру»По основам протокола MCP в этой редакции - протокол без состояния: всё нужное для обработки запроса есть в самом запросе.
- Сервер не должен полагаться на прежние запросы по тому же соединению, чтобы узнать версию протокола, возможности клиента или его имя. Эти сведения приходят в
_metaкаждого запроса. - Серверу не следует требовать, чтобы клиент выполнял связанные операции через то же соединение или тот же процесс.
- Состояние, которое должно жить дольше одного запроса, обязано адресоваться явным идентификатором, который клиент передаёт в каждом запросе.
Журнал изменений редакции удаляет сессии протокола и заголовок Mcp-Session-Id из Streamable HTTP. Механизм MRTR описан в спецификации как способ получить от клиента дополнительные данные без общего хранилища между экземплярами и без балансировки с учётом состояния.
Следствие: самому протоколу Modern привязка клиента к экземпляру не нужна. Это не снимает вопроса о состоянии вашего приложения. Если инструмент создаёт что-то долгоживущее, все экземпляры должны уметь найти это по идентификатору из запроса. Как это устроить, спецификация не определяет.
Подсказки кэширования
Заголовок раздела «Подсказки кэширования»Правила взяты со страницы Caching.
Сервер обязан включать подсказки в завершённые результаты шести операций: server/discover, tools/list, prompts/list, resources/list, resources/templates/list, resources/read. Промежуточные результаты с resultType: "input_required" не кэшируются и подсказок не несут.
Сколько миллисекунд клиент может считать результат свежим.
- Сервер обязан указывать значение не меньше нуля.
0- результат следует считать устаревшим сразу.- Поля нет - клиенту следует принять
0. По спецификации так бывает только у старых серверов. - Отрицательное значение клиенту следует считать нулём.
Это подсказка, а не обещание: данные могут измениться раньше срока. Клиенту не следует превращать ttlMs в период опроса. Свежесть проверяется тогда, когда данные понадобились. Реализация, которая всё же опрашивает сервер по расписанию, обязана добавлять случайный разброс и увеличивать паузы.
cacheScope
Заголовок раздела «cacheScope»| Значение | Кто может хранить ответ |
|---|---|
"public" | любой клиент, общий шлюз или кэширующий прокси, для любого пользователя |
"private" | только для того же контекста авторизации; делить кэш между разными контекстами нельзя |
Спецификация советует "public" для списков, одинаковых у всех пользователей, и "private" для чтения ресурсов, зависящих от пользователя, и для списков, отфильтрованных под пользователя.
Что ещё входит в правила
Заголовок раздела «Что ещё входит в правила»- Ключ кэша - метод и параметры, влияющие на результат. Клиент не должен отдавать сохранённый ответ на запрос с другим методом или параметрами.
- Результаты повторных запросов MRTR, то есть запросов с
inputResponsesилиrequestState, кэшировать нельзя. - Каждая страница списка кэшируется отдельно и несёт свой
ttlMs. Сервер обязан ставить один и тот жеcacheScopeна все страницы одного списка. - Уведомление об изменении списка сразу делает сохранённый ответ устаревшим, даже если срок не вышел.
- Клиент может отдать устаревший ответ, если повторный запрос не удался.
Порядок инструментов
Заголовок раздела «Порядок инструментов»По странице Tools серверу следует возвращать инструменты в одном и том же порядке, пока набор не изменился. Спецификация называет две причины: клиент может надёжно кэшировать список, и чаще срабатывает кэш запроса к языковой модели, когда инструменты входят в её контекст.
Там же сказано, что набор инструментов не должен зависеть от соединения и меняться как побочное действие других запросов. Он может зависеть от авторизации, предъявленной в запросе.
Постраничная выдача
Заголовок раздела «Постраничная выдача»По странице Pagination:
- Размер страницы выбирает сервер. Клиент не должен рассчитывать на постоянный размер.
- Курсор - непрозрачная строка. Клиент обязан не разбирать и не менять его.
- Серверу следует выдавать устойчивые курсоры.
Числа записей на страницу спецификация не называет.
Размер результата инструмента
Заголовок раздела «Размер результата инструмента»Предела на размер результата инструмента в разделе Tools спецификации нет. Есть одно относящееся к делу средство: инструмент может вернуть ссылку на ресурс (resource_link), то есть URI, по которому клиент сам запросит данные или подпишется на них. Спецификация не называет это способом уменьшить ответ, она лишь разрешает такой вид результата.
Пределы, которые ставит клиент или языковая модель, протоколом не описаны. Смотрите страницу своего клиента в разделе Клиенты MCP.
Отмена и время ожидания
Заголовок раздела «Отмена и время ожидания»По странице Cancellation:
- В Streamable HTTP отмена - это закрытие потока ответа. Сервер обязан считать разрыв соединения клиентом отменой этого запроса.
- В stdio клиент обязан отправить уведомление
notifications/cancelledс номером запроса. - Серверу следует прекратить обработку и освободить ресурсы.
- Реализациям следует ставить время ожидания на все отправленные запросы. Уведомление о ходе выполнения может сбрасывать отсчёт, но предельное время следует соблюдать всегда.
Для производительности важен первый пункт. Сервер, который не замечает закрытия потока, продолжает считать ответ, который никто не прочтёт. В Legacy было наоборот: разрыв соединения отменой не считался.
Значений времени ожидания спецификация не задаёт.
Потоки SSE
Заголовок раздела «Потоки SSE»По странице Streamable HTTP:
- Открывая поток SSE, серверу следует отправить заголовок
X-Accel-Buffering: no. Без него прокси может копить сообщения и отдавать их с задержкой. - Для долгих потоков, прежде всего у
subscriptions/listen, спецификация в примечании предлагает время от времени отправлять строку-комментарий SSE, то есть строку, начинающуюся с двоеточия. Это совет, а не требование. Он не даёт посреднику или клиенту закрыть соединение в тихий период. - Возобновления потока по
Last-Event-IDнет. Оборванный поток теряет запрос, и клиент обязан отправить его заново как новый, с новым номером запроса (это требование записано в перечне изменений редакции).
Практика, не правило MCP
Заголовок раздела «Практика, не правило MCP»Ниже - общие приёмы эксплуатации. Спецификация MCP их не требует.
Сначала измерьте
Заголовок раздела «Сначала измерьте»Спецификация не содержит ни одной цифры производительности. Любое число из чужой статьи относится к чужому серверу, чужим инструментам и чужой сети. Прежде чем что-то менять, измерьте свой сервер: время ответа по каждому инструменту, долю отменённых запросов, время до первого события в потоке.
Для проверки запросов к Streamable HTTP руководство по отладке на сайте MCP называет обычные средства HTTP: curl и вкладку сети в инструментах разработчика браузера. Нагрузочный запрос должен быть настоящим запросом Modern: POST на адрес MCP с заголовками MCP-Protocol-Version, Mcp-Method и, где нужно, Mcp-Name. Иначе вы измеряете скорость отказа с кодом 400.
Буферизация в прокси
Заголовок раздела «Буферизация в прокси»По документации модуля proxy в nginx:
proxy_bufferingпо умолчанию включена, и nginx сначала собирает ответ в буферы. При выключенной буферизации ответ передаётся клиенту сразу по мере получения.- Заголовок ответа
X-Accel-Bufferingсо значениемnoвыключает буферизацию для этого ответа. Директиваproxy_ignore_headersможет отключить эту способность. proxy_read_timeoutотсчитывается между двумя чтениями, а не на весь ответ. Если сервер молчит дольше, соединение закрывается. Отсюда польза строк-комментариев в долгом потоке.
Повторное использование соединений
Заголовок раздела «Повторное использование соединений»В Modern каждое сообщение клиента - отдельный POST. Сколько при этом открывается соединений TCP, зависит не от MCP, а от HTTP и от настройки посредников.
По документации nginx директива proxy_http_version задаёт версию HTTP для связи с сервером за прокси, и для постоянных соединений рекомендуется версия 1.1 или 2. Директива keepalive в блоке upstream включает хранение простаивающих соединений с серверами за прокси для повторного использования. Значения по умолчанию у обеих директив менялись между версиями nginx, поэтому сверяйтесь с документацией своей версии.
Чего здесь нет и что неизвестно
Заголовок раздела «Чего здесь нет и что неизвестно»- Измерений нет: ни числа запросов в секунду, ни объёма памяти, ни рекомендуемых значений времени ожидания. Их нет в спецификации, а чужие числа к вашему серверу не относятся.
- Как каждый клиент пользуется
ttlMsиcacheScopeи соблюдает ли он их, по спецификации установить нельзя. Сведения по SDK - в разделе SDK. - Пределы на размер результата инструмента у клиентов и моделей протоколом не заданы.
- Настройка ядра, пулы соединений с базами данных, очереди и автоматическое масштабирование не рассматриваются: к MCP они отношения не имеют.
- Балансировка сессий Legacy разобрана не здесь, а на странице про сервер для двух эпох.