Головна / Статті

Міграція сервера MCP до специфікації 2026-07-28: двадцять хвилин, крок за кроком

Міграція сервера MCP до специфікації 2026-07-28 протягом приблизно двадцяти хвилин: сесії зникли, п’ять важливих змін, кроки використання Python SDK 2.0 та переписування MRTR.

Видавець: REACTAPP.TOP10 хв читання2207 слів

Джерела: Your MCP Server Is Running on a Deprecated Spec. Here’s the 20-Minute Migration.

Нічого не зламалося, і саме це є тривожним. 28 липня 2026 року Model Context Protocol оприлюднив свою специфікацію 2026-07-28 — найбільшу зміну з моменту появи віддаленого MCP. Заголовок, від якого залежали сервери, було скасовано, а модель транспорту змінила свою структуру, проте сумісність збереглася. Сервери продовжували працювати без запису стеку викликів, попереджень чи ознак проблем зі збіркою.

Це і є таємничий вид технічного боргу. Він залишається прихованим, поки хтось не потребує масштабування чи поки не закінчиться дванадцятимісячний термін виходу з ужитку, після чого залежність перестає підтримуватися. Сервер, який все ще використовує версію 2025-11-25, відстає від сучасних стандартів. Сервер, що працює за старою моделлю HTTP+SSE, використовує технологію, яка вже виходить з ужитку, а також, можливо, три функції, розвиток яких зупинено.

У наступному описано, що змінилося, чому це зробили адміністратори та як наздогнати ситуацію. Для більшості серверів це займає близько двадцяти хвилин роботи. Однак одна зі змін — це справжнє переписування коду для деяких серверів, і краще сказати про це заздалегідь.

Чому з’явилися сесії

Інженерні мотиви пояснюють усе інше. MCP було запущено наприкінці 2024 року як протокол, орієнтований на сесії: клієнт відкриває зв’язок за допомогою команди initialize, сервер надсилає Mcp-Session-Id, і кожен наступний запит передає його. Це підходило для початкової ситуації, коли був один клієнт та один сервер на одній машині через стандартний ввод-вивід.

Потім сервери перейшли на справжню інфраструктуру, і дизайн натрапив на перешкоду. Інженери Google описали це у своєму звіті про безстановий оновлення: дизайн, ідеальний для одного локального клієнта, перестав працювати, коли сервери MCP розмістилися на хмарній інфраструктурі.

Розгляньте, що вимагає ідентифікатор сесії. Або механізм „sticky routing“, який забезпечує, щоб один клієнт завжди підключався до однієї й тієї самої інстанції, або спільний сховище сесій, до якого може звертатися будь-яка інстанція. Звичайний HTTP-сервіс раптово потребує механізмів балансування навантаження, що враховують прив’язку клієнтів, та інструментів на кшталт Redis, просто для забезпечення передачі даних, перш ніж він зможе виконувати якісь корисні функції.

У своїй публікації Девід Сорія Парра та Ден Делімарський прямо кажуть: MCP переходить від двостороннього, станового протоколу до протоколу запит/відповідь без стану, що було однією з найбільш затребуваних змін з боку розробників, які прагнули надійності та масштабованості. Нагальність цього відображається у розмірах. SDK версії Tier 1 мають майже півмільярда завантажень на місяць, а SDK на TypeScript та Python вже перевищили по мільярд загальних завантажень. Протокол такого масштабу не може постійно вимагати від кожної інсталяції вирішення проблеми прив’язки сесій.

Отже, сеанс більше не існує. Кожен запит містить власну версію протоколу, ідентифікатор клієнта та його можливості, що означає, що будь-який запит може досягти будь-якої інстанції за допомогою звичайного балансувальника типу round-robin без спільного зберігання даних. Усе, що йде далі, випливає з цього.

П’ять змін, які потрібно зрозуміти

1. Без обміну сигналами, без заголовка сеансу

Обмін даними initialize та initialized та заголовок Mcp-Session-Id офіційно скасовані (SEP-2575 та SEP-2567). Кожен запит є автономним, з версією, ідентифікатором клієнта та його можливостями у полі _meta. Запит за новою специфікацією виглядає так:

POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search

{"jsonrpc":"2.0","id":1,"method":"tools/call",
 "params":{"name":"search","arguments":{"q":"otters"},
 "_meta":{"io.modelcontextprotocol/clientInfo":
              {"name":"my-app",
                "version":"1.0"}
          }}}

Клієнт, який хоче заздалегідь дізнатися про можливості сервера, може використовувати новий RPC server/discover, який є необов’язковим та більше не є обов’язковою процедурою взаємодії.

Поширеним страхом є те, що додатки більше не зможуть зберігати стан. Однак це все ще можливо. Видалення сеансу з протоколу не зобов’язує додаток бути безстановим. Коли серверу потрібна безперервність, інструмент має створити явний ідентифікатор, який модель пізніше поверне як аргумент. Це краще, ніж зберігання стану в процесі передачі даних, оскільки модель може бачити цей ідентифікатор та передавати його від одного інструменту до іншого. Видимий стан кращий за невидимий.

2. Два обов’язкові заголовки

Відтепер запити HTTP у Streamable повинні містити поля Mcp-Method та Mcp-Name (SEP-2243), і від сервера очікується підтвердження їхньої відповідності запиту. Це приносить переваги інфраструктурі: шлюз, обмежувач швидкості чи WAF можуть керувати трафіком та вимірювати обсяги за допомогою цих заголовків, уникаючи парсингу JSON. Ті, хто раніше відмовився від обмеження швидкості для окремих інструментів через те, що назва інструменту була прихована всередині вмісту запиту, тепер мають вихід.

3. Відповіді списку, які можна кешувати

Результати виконання tools/list, prompts/list, resources/list та resources/read тепер містять параметри ttlMs та cacheScope (SEP-2549) та повертаються у детермінованому порядку. Клієнти можуть кешувати ваш каталог інструментів та зберігати стабільність кешів запитів під час повторних підключень. Оскільки значна частина витрат агента на токени припадає на постійну передачу визначень інструментів, це також є засобом економії коштів.

4. Суворіша авторизація

Було впроваджено чотири зміни, одна з яких може пояснити баг, з яким ви вже стикалися:

  • Сервери авторизації повинні повертати параметр iss, визначений у RFC 9207, і клієнти зобов’язані перевіряти його перед використанням коду (SEP-2468), що усуває можливість атак типу плутанини.
  • Клієнти встановлюють application_type під час динамічної реєстрації клієнтів (SEP-837), тому сервери авторизації більше не відхиляють перенаправлення з localhost для десктопних та CLI-додатків. Якщо процес OAuth для CLI коли-небудь зазнавав невдачі через помилку redirect_uri, ймовірно, це є причиною.
  • Креденціали клієнта прив’язані до організації, яка їх створила, і не можуть використовуватися на різних серверах авторизації (SEP-2352).
  • Сама процедура динамічної реєстрації клієнтів офіційно вважається застарілою на користь документів метаданих ідентифікатора клієнта. Вона все ще працює, але буде видалена у наступній версії.

5. Список застарілих функцій

Тут термін «застарілий» має важливе значення. Функції Roots, Sampling and Logging (SEP-2577) є застарілими, але все ще працюють, і у них є ще принаймні дванадцять місяців на існування; нові реалізації не повинні їх використовувати. Старий спосіб передачі даних HTTP+SSE також вважається застарілим, і для його відмови також виділено рік.

Функція Tasks була переміщена, а не видалена. Вона перейшла з експериментального ядра до розширення io.modelcontextprotocol/tasks; її можна отримати за допомогою tasks/get, а оновити — через нову функцію tasks/update (SEP-2663). Тепер сповіщення про зміни надходять через єдиний потік subscriptions/listen, до якого клієнти можуть підключитися за власним бажанням.

Найкращою новиною є формальна політика видалення з мінімальним терміном у дванадцять місяців. У матеріалах Real Python зазначається, що 90-денний термін застосовується лише до активних безпекових ризиків, що є більшим терміном попередження, ніж коли-небудь було в цій екосистемі. Ця політика може мати більше значення, ніж щось інше в цьому оновленні, адже вона відрізняє протокол, з яким можна експериментувати, від того, на якому можна будувати бізнес.

Міграція, крок за кроком

У цьому посібнику використовується Python SDK, перейменування якого є найбільш проблематичним із чотирьох варіантів, хоча структура залишається однаковою у TypeScript, Go та C#.

Хвилини 0–2: прийняти рішення. Якщо сервер використовує методи вибірки даних, збору інформації чи інші подібні підходи, йому потрібна повна переробка, про що йдеться нижче. Якщо він лише надає інструменти та ресурси, можна продовжувати.

Хвилини 2–5: оновити SDK. Python SDK досяг версії 2.0.0 у день оприлюднення специфікації, і команда pip install mcp тепер завантажує версії 2.x.

pip install --upgrade "mcp>=2"

Одна важлива зміна, про яку варто знати: SDK було переміщено з httpx на httpx2. Якщо httpx використовується в інших частинах вашої ієрархії залежностей, вирішіть це проблему негайно.

Хвилини 5–10: перейменувати клас. Це стосується кожного Python-сервера. FastMCP тепер називається MCPServer — без аліасів та без засобів для поступового видалення:

# Before, on mcp 1.x
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Demo")

# After, on mcp 2.x
from mcp.server.mcpserver import MCPServer

mcp = MCPServer("Demo")

У цьому ж випуску ще три перейменування:

# Wire types are snake_case now
result.isError        # → result.is_error
tool.inputSchema      # → tool.input_schema

# The error class matches the new capitalisation
except McpError:      # → except MCPError:

mcp-types тепер є окремим пакетом, але mcp.types залишається підтримуваним шляхом імпорту, тому такі імпорти продовжують працювати. Увага: це не впливає на тих, хто використовує окремий пакет fastmcp замість офіційного SDK. Це окремий проект із власними версіями 3.x, і однією з причин перейменування є необхідність розділення цих двох проектів.

Хвилини 10–15: видалити механізми роботи з сеансами. Словники сеансів, таймери очищення та екземпляр Redis, створений виключно для зберігання стану сеансу, можна повністю видалити. Якщо справді потрібна безперервність між викликами, використовуйте паттерн обробки об’єктів:

# Instead of hiding state in a session the model can't see:
@mcp.tool()
def open_dataset(path: str) -> str:
    """Open a dataset and return a handle for subsequent calls."""
    handle = register_dataset(path)     # your own store, your own TTL
    return handle                        # the model now HOLDS this

@mcp.tool()
def query_dataset(handle: str, query: str) -> list[dict]:
    """Query a previously opened dataset."""
    return lookup(handle).query(query)

Хвилини 15–18: перевірка нових заголовків. Сервер має переконатися, що надіслані значення Mcp-Method та Mcp-Name узгоджуються з запитом. SDK покриває звичайний сценарій, але у випадку використання власного шлюзу чи ручно написаного механізму передачі даних необхідно перевіряти все від початку до кінця.

Хвилини 18–20: виправлення коду помилки. Його легко пропустити, що призводить до незрозумілої поведінки клієнта. Помилки через відсутність ресурсу мають використовувати стандартний код JSON-RPC invalid-params -32602, а не власний код MCP -32002.

Готово до випуску

Один MCPServer підтримує обидві версії протоколу, тому клієнт 2025 року продовжує працювати з мігрованим сервером без необхідності налаштувань з жодної сторони. Саме тому його можна випустити у звичайний вівторок, без необхідності координувати спеціальний день для всіх клієнтів.

Коли це займає більше часу

Сервери, які використовують вибірку даних, запити або інші подібні методи, змушені повністю переписати свою логіку, що, за словами Real Python, є найскладнішим етапом у процесі міграції. Раніше сервер міг ініціювати запит та надсилати відповідь клієнту через відкритий двосторонній потік даних. У безстановому дизайні такого потоку немає, тому для обміну даними використовуються багаторазові запити-відповіді (SEP-2322).

Новий підхід працює так: сервер відповідає з кодом resultType: „input_required“ та переліком запитань, на які потрібні відповіді, а клієнт повторює початковий запит, надсилаючи свої відповіді у полі inputResponses. Це змінює спосіб написання інструментів – обробник не може зупинитися на півдорозі та чекати на відповідь. Його можуть викликати кілька разів для однієї логічної операції, і він мусить правильно продовжити роботу, як тільки надійдуть дані, тому все, що зберігається у локальних змінних під час перерви, має бути збережено в місці, до якого може дістатися під час повторної спроби.

Переваги є реальними. Керівник відділу продуктів Supabase сказав, що реалізація цього функціоналу давно була у планах, але не була можлива через те, що їхній сервер MCP працює без зберігання стану, тоді як MRTR уможливлює це, дозволяючи інструментам спочатку підтвердити все з користувачем — наприклад, вартість нового проєкту чи запит, який може видалити дані. Складніше стає розробка інструментів, але їхнє масштабне використання без зберігання стану стає можливим.

Що дає новий протокол

Manufact пропонує тисячі серверів MCP та підтримує фреймворк відкритого коду mcp-use. Вони виявили, що версія SDK v2 є приблизно на 83% меншою та на 25% швидшою завдяки новій архітектурі клієнт-сервер. У звіті екосистеми Agentic AI Foundation зазначається, що сервер тепер функціонує як будь-який інший HTTP-сервіс, відповідаючи з тієї інстанції, яку обирає балансувальник, а гейтвеї здійснюють маршрутизацію та обмеження швидкості за допомогою заголовків. Дванадцятимісячна стратегія розвитку означає, що протокол також не буде змінюватися під час його використання.

Швидке прийняття – це рідкість для відкритого стандарту. Вже протягом кількох днів постачальники інфраструктури, адміністратори SDK, хмарні платформи та виробники інструментів оголосили про свою підтримку, оприлюднили інструкції з міграції та випустили версії для продакшну. SDK Agents від Cloudflare почав працювати згідно зі специфікацією вже з першого дня, Amazon Bedrock AgentCore постачає безстановий ядро, а до проекту приєдналися Microsoft Foundry, Netlify, Figma, Supabase та Honeycomb. Honeycomb стверджує, що майже кожна п’ята їхніх щомісячних інтерактивних запитів тепер надходить від агентів, що пояснює важливість цього розвитку. Агенти вже вийшли за межі демо-фази.

Залишатися на версії 1.x

Це цілком обґрунтований вибір. Просто зафіксуйте версію та чекайте:

# Buys you time, keeps security patches coming
pip install "mcp>=1.28,<2"

Дізнайтеся дві речі під час роботи з цим. Лінійка 1.x знаходиться у режимі технічного обслуговування, де вносяться лише виправлення безпеки. Крім того, розширення Tasks ще не включено до версії Python SDK 2.0, тому воно залишило основні специфікації, не потрапивши до SDK. Для користувачів Python, які залежать від Tasks, правильним рішенням є очікування. Додайте нагадування у календар на дванадцять місяців щодо Roots, Sampling та Logging, адже періоди виходу з ужитку здаються нескінченними, поки вони не закінчаться.

Небезпека тихого виходу з ужитку

Кардинальна зміна є помітною: вона заважає складанню проекту, спричиняє проблеми та потім виправляється. Виходження з ужитку за своєю суттю є тихим. Сервер працює, тести проходять, і ніщо не показує помилок, проте проблеми накопичуються: транспорт з терміном дії, відсутність можливості легкого горизонтального масштабування та залежність у режимі технічного обслуговування, поки екосистема розвивається далі. Версія, вказана у MCP-Protocol-Version, — це дата, тож варто перевірити, наскільки вона вже стара.

Для більшості серверів достатньо щонайбільше одного дня, причому менше ніж півгодини — це час безпосередньої роботи. Сервери, які використовують методи вибірки даних чи інші способи збору інформації, повинні виділити цілий день та спочатку ознайомитися зі специфікацією MRTR. У будь-якому разі це потрібно зробити до того, як дванадцять місяців тихо перетворяться на два.

Пов’язана література

  • Порівняння 16 архітектур RAG: яка схема підходить для якої проблеми — огляд шістнадцяти схем RAG у чотирьох категоріях, від стандартних та гібридних методів пошуку до агентних, графових та федеративних рішень, із поетапним планом створення за місяцями.
  • ClickHouse MCP та обмеження режиму лише для читання: структурований доступ для агентів — доступ MCP лише для читання зупиняє записи, але не помилкові значення, витоки даних та викриття схеми. Дізнайтеся, що показують тестування ClickHouse та як інструменти структурованих метрик зменшують ризики.
  • Створіть сервер MCP для щоденника роботи з пошуком за 190 рядків TypeScript — невеликий сервер MCP для файлів Markdown: чотири інструменти на основі інтентів, описи у стилі запитів, демонстраційний клієнт stdio, який виконує також функцію тесту, а також реальні проблеми під час роботи.