Skip to main content
Glama

🛡️ MCPResilience

Устойчивый, соответствующий спецификации MCP-сервер на официальном SDK v2

Говорите на MCP так, как говорит ваш клиент. MCPResilience автоматически определяет эпохи протокола — легаси и современную — уже по первому запросу и переживает разницу.

MCP Spec SDK Language License


🔌 Режимы клиентов

MCPResilience автоматически определяет, какую эпоху протокола использует подключающийся клиент — настройка не требуется:

  1. ⚡ Современные клиенты без состояния — клиенты, чей первый запрос несёт конверт _meta (io.modelcontextprotocol/protocolVersion + clientInfo), полностью пропускают рукопожатие. tools/call может быть их самым первым сообщением.

  2. 🤝 Клиенты с легаси-рукопожатием — клиенты без такого конверта направляются через традиционный поток initialize, с принудительным -32600 Invalid request parameters для всего, что отправлено до завершения initialize.

Полную разбивку обеих эпох см. в разделе Поддержка протокола.


Related MCP server: mcp-uni

🧠 Что это такое

MCPResilience существует потому, что замена самописного MCP-сервера на официальный SDK — не замена «на лету»: формат провода меняется так, что ломает наивные миграции. Этот проект решает задачу в два этапа:

  1. Миграция на SDK — замена самописного ядра MCP-сервера на официальный MCP SDK v2, нацеленный на спецификацию 2026-07-28, чтобы получить ядро без состояния и типобезопасную сериализацию Pydantic.

  2. Упрочнение совместимости — гарантия, что миграция не приведёт к молчаливой потере поддержки клиентов, всё ещё использующих легаси-рукопожатие, не потеряет данные из-за пробелов в вышестоящей схеме и не сломает экспериментальное расширение Tasks на полпути.

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


📊 Ключевые результаты

Все тесты совместимости фазы 5 и бенчмарки фазы 6 проходят — от начала до конца, на официальном MCP SDK v2 — с полной поддержкой обеих эпох протокола и экспериментального расширения Tasks, плюс один обнаруженный и пропатченный баг вышестоящего SDK (см. Известная особенность SDK).

Расширение Tasks: что изменилось при миграции на SDK

Аспект

Поведение легаси

Поведение SDK v2

Объявление поддержки задач

Булев флаг longRunning: true

Объект execution, например execution: {"taskSupport": "required"}

Расположение дескриптора задачи

Верхнеуровневый taskHandle в result

Перемещено в конверт метаданных: result._meta.taskHandle

Конечное состояние успеха

"succeeded"

"completed"

Доставка содержимого задачи

Через опрос tasks/get

Только через поток ответа tools/calltasks/get возвращает только метаданные статуса (statusMessage, createdAt и т.д.)

Повторная отмена завершённой задачи

{cancelled: true} или ошибка -32602

Идемпотентно — возвращает CancelTaskResult со статусом "cancelled"


🏗️ Как это работает

Incoming connection
        │
        ▼
  First request received
        │
        ▼
  Does it carry the _meta envelope?
  (protocolVersion + clientInfo)
        │
   ┌────┴────┐
  Yes         No
   │           │
   ▼           ▼
Modern Era   Legacy Era
(stateless)  (handshake required)
   │           │
   ▼           ▼
tools/call   initialize → any request
runs          (initialize enforced,
immediately    notifications/initialized
               not blocked)
   │           │
   └─────┬─────┘
         ▼
  Era locked for the
  life of the connection

📡 Поддержка протокола

Эпоха без состояния (2026-07-28)

Согласно современной спецификации, традиционное рукопожатие initializenotifications/initialized устарело. Сервер запускает serve_dual_era_loop:

  • Если первый запрос включает конверт _meta с io.modelcontextprotocol/protocolVersion и io.modelcontextprotocol/clientInfo, сервер фиксируется в современной эпохе без состояния.

  • Клиенты могут отправлять tools/call самым первым запросом — вызов initialize не требуется.

Эпоха легаси

Если первый запрос не содержит современного конверта _meta, сервер фиксируется в эпохе легаси:

  • Любой запрос, отправленный до initialize (например, tools/call), отклоняется с -32600 Invalid request parameters.

  • После ответа на initialize сервер не ждёт notifications/initialized перед обработкой дальнейших запросов.

Обработка несоответствия версий

Современные запросы, указывающие неподдерживаемую версию протокола в конверте _meta, аккуратно отклоняются с -32022 Unsupported protocol version — само соединение сохраняется, а не разрывается.


🧩 Глубокое погружение в расширение Tasks

Экспериментальное расширение Tasks претерпело наибольшие изменения формата провода из всего, что было в миграции (см. сравнительную таблицу в Ключевых результатах). Стоит особо выделить два поведения:

  • tasks/get теперь только метаданные. Содержимое задач доставляется исключительно через поток ответа tools/call; опрос tasks/get будет возвращать только поля статуса, такие как statusMessage и createdAt, — но никогда сам полезный груз.

  • Отмена идемпотентна по замыслу. Повторная отмена задачи, которая уже completed или cancelled, возвращает успешный CancelTaskResult, а не ошибку, в отличие от легаси-сервера с -32602 при повторной отмене.

Известная особенность SDK

Проблема SDK #2156 — поле execution удаляется из tools/list. Текущая схема Pydantic для v2026_07_28.Tool не определяет экспериментальное поле execution, поэтому serialize_server_result молча удаляет его из ответов tools/list.

Обходной путь: точечный monkeypatch на mcp_types.methods.serialize_server_result перехватывает проверенный вывод и восстанавливает словарь execution из исходных данных обработчика. Это временное решение — удалите его, как только вышестоящая схема нативно включит это поле.


🔧 Технические заметки (то, что было нетривиальным)

  1. Определение эпохи происходит ровно один раз, по первому запросу. Пути обновления на середине соединения нет — клиент, открывший соединение без конверта _meta, остаётся в эпохе легаси на всё время этого соединения, даже если позже начнёт отправлять запросы современного вида.

  2. Дескриптор задачи не просто переехал — изменился его контракт. Перенос taskHandle из верхнеуровневого result в result._meta также освободил верхнеуровневый объект result для того, чтобы он был зарезервирован исключительно под немедленный вывод содержимого и флаг isError — более чистое разделение, чем допускала форма легаси.

  3. Monkeypatch намеренно узко ограничен. Он перехватывает только serialize_server_result, чтобы восстановить одно недостающее поле, а не форкает и не оборачивает схему SDK целиком — это упрощает удаление патча, как только вышестоящий SDK выпустит исправление.


🛠️ Технологический стек

  • Протокол: JSON-RPC 2.0 поверх Model Context Protocol, спецификация 2026-07-28

  • SDK: Официальный MCP SDK v2 — проверка схемы и сериализация на основе Pydantic

  • Ядро сервера: Python, обработка запросов без состояния (serve_dual_era_loop)

  • Тестирование: набор совместимости фазы 5 + прогон бенчмарков фазы 6


🚀 Начало работы

git clone https://github.com/HoorShumail/MCPResilience.git
cd MCPResilience
pip install -r requirements.txt

Подгоните команды выше под фактическую структуру вашего пакета и точку входа.

Запустите набор совместимости и бенчмарки с помощью:

pytest

⚠️ Честные ограничения

  • Расширение Tasks всё ещё экспериментально в вышестоящем проекте. Оно не финализировано в основной спецификации MCP, поэтому его формат провода может снова измениться в будущих версиях SDK — этот сервер отслеживает текущую экспериментальную реализацию SDK, а не стабильную цель.

  • Исправление поля execution — это monkeypatch, а не постоянное решение. Он патчит serialize_server_result во время выполнения, а не исправляет базовую схему — его нужно удалить, как только проблема SDK #2156 получит вышестоящее исправление.

  • Определение эпохи — только по первому запросу. Клиент, зафиксированный в эпохе легаси при старте соединения, не имеет пути «обновления» до эпохи без состояния на середине соединения, даже если его последующие запросы выглядят современно.


🙏 Благодарности

  • Официальный MCP SDK v2 — сопровождающие Model Context Protocol

  • Спецификация Model Context Protocol (2026-07-28)

🧑💻 Автор

Hoor Shumail AI | Машинное обучение | Агентный ИИ | Мультиагентные системы | Карьерный интеллект

📜 Лицензия

Этот проект разработан в образовательных, исследовательских и портфолио-целях.

Он построен на основе официального Model Context Protocol SDK — для условий, регулирующих эти компоненты, обратитесь к собственной лицензии этого SDK и спецификации Model Context Protocol.

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    A dual-protocol MCP server that supports both modern Streamable HTTP and legacy HTTP+SSE protocols, providing backward compatibility for clients while offering advanced features like session resumability.
  • A
    license
    Not graded
    quality
    C
    maintenance
    A universal MCP server that acts as a unified gateway for dynamically connecting and managing multiple MCP servers via a single HTTP endpoint.
    10
    6
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that enables agents to dynamically switch between multiple AI models (OpenAI, Anthropic, Google, etc.) with unified protocol-driven configuration and capability discovery.
    Apache 2.0

View all related MCP servers

Related MCP Connectors

  • Manage feature requests, votes, roadmaps, and changelogs from any MCP client.

  • Official MCP server for Qase — manage test cases, runs, suites, defects via AI tools.

  • Official remote MCP server for Archivist AI TTRPG campaign memory: characters, sessions, and more.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/HoorShumail/MCPResilience'

If you have feedback or need assistance with the MCP directory API, please join our Discord server