AI Extensions: MCP SDK 2.3.0 для Python і TypeScript затягує межі
Сервер, що мовчки приймає перенаправлення на інший хост чи необмежений масив аргументів, довіряє більше, ніж, можливо, хотів автор.

Сервер, що мовчки приймає перенаправлення на інший хост чи необмежений масив аргументів, довіряє більше, ніж, можливо, хотів автор. SDK MCP для Python і TypeScript випустили 2.3.0 2 жовтня, і частина змін стосується саме цих меж.
Коротко
Офіційні проєкти: modelcontextprotocol/python-sdk (MIT) і modelcontextprotocol/typescript-sdk (ліцензія переходить із MIT на Apache-2.0). Обидва випустили v2.3.0 2 жовтня. Спостереження 3 жовтня: Python SDK - 24 468 зірок, 4006 форків, останній push 2 жовтня о 22:02:27 UTC; TypeScript SDK - 13 504 зірки, 2248 форків, останній push 2 жовтня о 19:24:26 UTC. Зірки показують увагу, а не якість чи безпеку. Я прочитав випуски, не встановлював і не запускав SDK. ↗
Python SDK 2.3.0
Опубліковано 2 жовтня о 22:02:27 UTC, встановлення pip install -U mcp за примітками до випуску. Спершу в примітках перелічено зміни поведінки: потрібен httpx2 версії 2.10.0 або новіший; інструмент із хибною анотацією x-mcp-header тепер не реєструється, а не зникає мовчки зі списку клієнта; порожні _meta і params більше не надсилаються на старих з’єднаннях; інтерактивний вхід OAuth більше не зараховується в тайм-аут запиту. Нові параметри: max_sse_event_size (за замовчуванням 1 МіБ на подію SSE) і MCPServer(subscriptions=False). ↗
TypeScript SDK 2.3.0
Опубліковано 2 жовтня о 17:55:03 UTC. За нотатками про оновлення, екземпляр сервера тепер відхиляє connect(), якщо вже підключений, тож безстанові HTTP-сервери мають створювати сервер і транспорт на кожен запит. HTTP-транспорти клієнта слідують за перенаправленням лише в межах того самого origin, якщо redirectPolicy не встановлено в follow. Нові необов’язкові параметри: maxToolInputElements обмежує кількість елементів масивів і членів об’єктів в аргументах інструмента, а expectedResource під час перевірки bearer-токена приймає лише токени, видані для цього сервера. Супровідники повідомляють, що результат інструмента в 100 МБ однією подією прискорився з приблизно хвилини й 1,7 ГБ пікової пам’яті до менш ніж секунди й близько 0,5 ГБ. Це їхній тест, не мій. ↗
Перед встановленням: ліцензії, підтримка, налаштування
Файл LICENSE у Python SDK - MIT. У LICENSE TypeScript SDK сказано про перехід із MIT на Apache-2.0: новий код під Apache-2.0, давніші внески без згоди на зміну ліцензії лишаються MIT, документація крім специфікацій - CC-BY-4.0, тож називати його просто MIT чи просто Apache-2.0 неточно. Обидва репозиторії отримали push протягом доби до моєї перевірки й випустили релізи того ж дня: це активність, а не доказ придатності для вашого сервера. Для проби зафіксуйте версію, прочитайте нотатки про оновлення для вашого транспорту й спершу перевірте на тестовому сервері.
Де проходять межі дозволів
Мій аналіз: три зміни звужують те, що приймає сервер чи клієнт. Правило перенаправлення в межах origin обмежує, куди може потрапити запит, ліміт елементів аргументів - скільки може нести виклик, перевірка аудиторії прив’язує токен до одного сервера. Усі три вимкнені або налаштовуються, і жодна не замінює автентифікацію, авторизацію кожного інструмента та ставлення до результатів інструментів як до недовіреного вмісту. Збільшення max_sse_event_size або redirectPolicy у значення follow свідомо послаблює обмеження, тож записуйте причину.
Чек-лист, який я написав
Код нижче - спрощене правило перенаправлення з вигаданими адресами, виконане локально. Воно дозволяє той самий origin і перехід з http на https на тому ж хості та відхиляє інший хост чи порт. Це не реалізація SDK: прочитайте параметр транспорту й перевірте справжню поведінку перенаправлення на тестовій точці.
Чек-лист у коді
from urllib.parse import urlsplit
def origin(url):
u = urlsplit(url)
port = u.port or {"http": 80, "https": 443}[u.scheme]
return (u.scheme, u.hostname, port)
def follow(src, dst):
a, b = origin(src), origin(dst)
if a == b:
return True
# http to https on the same host and default ports is allowed
return a[1] == b[1] and (a[0], b[0]) == ("http", "https") and a[2] == 80 and b[2] == 443
assert follow("https://api.example.test/mcp", "https://api.example.test/v2/mcp")
assert follow("http://api.example.test/mcp", "https://api.example.test/mcp")
assert not follow("https://api.example.test/mcp", "https://other.example.test/mcp")
assert not follow("https://api.example.test/mcp", "https://api.example.test:8443/mcp")
print("redirect policy checks passed")
# Invented URLs and a simplified rule, not the SDK's implementation.
Джерела й обмеження
- https://github.com/modelcontextprotocol/python-sdk
- https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.3.0
- https://github.com/modelcontextprotocol/python-sdk/blob/main/LICENSE
- https://github.com/modelcontextprotocol/typescript-sdk
- https://github.com/modelcontextprotocol/typescript-sdk/releases/tag/v2.3.0
- https://github.com/modelcontextprotocol/typescript-sdk/blob/main/LICENSE