Python SDK v1 · mcp==1.30.0 · протокол 2025-11-25. Для SDK v2 требуется отдельная миграция.
Перед началом
Нужны файлы первого урока, .venv с SDK 1.30.0, созданная configure_client.py конфигурация .mcp.json и общий lab_session.py из контракта. Если конфигурация ещё не создана, выполните один раз:
.\.venv\Scripts\python.exe configure_client.pyПовторный запуск намеренно откажется перезаписывать существующую конфигурацию. Не удаляйте чужую .mcp.json ради упражнения; работайте в новой учебной папке из первого урока.
1. Посмотрите на рабочую запись
Get-Content -LiteralPath .mcp.jsonУ label-lab должны быть type stdio, абсолютный command вашего .venv\Scripts\python.exe и args с label_server.py. В stdio клиент запускает этот процесс и обменивается JSON-RPC через stdin/stdout. Начало обмена — initialize, ответ с согласованной версией, затем notifications/initialized. Только после этого получаем список инструментов.
stdout не является местом для логов: каждый посторонний print может повредить поток сообщений. stderr отделён и пригоден для диагностики. Завершение контекста клиента закрывает транспорт и дочерний процесс; постоянный веб-сервис в этом режиме не требуется.
2. Сохраните проверку конфигурации
Создайте check_transport.py:
"""Classify a configuration; exercise HTTP syntax without a network call."""
import asyncio
import json
from pathlib import Path
from urllib.parse import urlsplit
from lab_session import lab_session
def classify(configuration: dict) -> str:
has_command = bool(configuration.get("command"))
has_url = bool(configuration.get("url"))
if has_command == has_url:
raise ValueError("Provide exactly one of command or url")
if has_command:
if configuration.get("type", "stdio") != "stdio":
raise ValueError("A command uses stdio in this exercise")
return "stdio"
url = urlsplit(configuration["url"])
if url.scheme != "https" or not url.hostname or url.username or url.password:
raise ValueError("Use an HTTPS endpoint without credentials in its URL")
return "streamable-http"
async def main():
root = Path(__file__).resolve().parent
configuration = json.loads((root / ".mcp.json").read_text(encoding="utf-8"))["mcpServers"]["label-lab"]
assert classify(configuration) == "stdio"
async with lab_session() as (session, initialized):
assert initialized.protocolVersion == "2025-11-25"
assert (await session.list_tools()).tools[0].name == "normalize_label"
hypothetical_http = {"url": "https://example.invalid/mcp"}
assert classify(hypothetical_http) == "streamable-http"
bad_configurations = [{}, {"command": "python", "url": "https://example.invalid/mcp"}, {"url": "http://example.invalid/mcp"}]
errors = []
for bad in bad_configurations:
try:
classify(bad)
except ValueError as error:
errors.append(str(error))
else:
raise AssertionError("Expected a configuration error")
print("PASS: real stdio handshake; HTTP configuration only; three invalid configurations")
print(json.dumps({"local": {"transport": "stdio", "protocol": initialized.protocolVersion, "messages": ["initialize", "notifications/initialized", "tools/list"]}, "http_exercise": {"transport": classify(hypothetical_http), "endpoint": hypothetical_http["url"], "server_implemented": False, "authorization_implemented": False, "network_called": False}, "configuration_errors": errors}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
asyncio.run(main())Функция classify — узкая проверка этого упражнения, не полная схема всех конфигураций редактора. Она требует ровно одно из command и url, для команды принимает stdio, для учебного HTTP-адреса требует HTTPS без учётных данных внутри URL. Она не подтверждает существование сервера, поддержку транспорта, безопасность или наличие авторизации.
3. Запустите и отделите факты от предположений
.\.venv\Scripts\python.exe check_transport.pyОжидаемая первая строка:
PASS: real stdio handshake; HTTP configuration only; three invalid configurationsВ JSON local.protocol должен быть 2025-11-25. В http_exercise три поля — server_implemented, authorization_implemented и network_called — будут false. Адрес example.invalid специально нерабочий: это упражнение на конфигурацию, не endpoint для подключения.
Пустая запись, одновременно command и url, а также учебный http:// адрес дадут ValueError. Если чтение .mcp.json завершилось FileNotFoundError, выполните генератор из первого урока в той же лаборатории. Если появился KeyError, сравните переносимый верхний ключ mcpServers с ключом servers у .vscode/mcp.json: эти файлы имеют разные схемы.
Что понадобится для настоящего HTTP
Streamable HTTP использует отдельный MCP endpoint и HTTP-запросы. Удалённый сервер требует решения по аутентификации и авторизации, проверке Origin, токенам, разрешениям и жизненному циклу соединений. В протоколе 2025-11-25 сервер обязан проверять Origin при его наличии, а локальный HTTP-сервер следует привязывать к localhost. Наличие HTTPS само по себе не даёт права читать или менять чужие данные.
Включение HTTP одной заменой строки транспорта не реализует OAuth или права на инструменты. Авторизация HTTP описана отдельным разделом спецификации; stdio обычно получает необходимые параметры окружения от host. Наш сервер не работает с секретами, файловыми ресурсами или операциями записи, поэтому этот урок не выдаёт его за готовый удалённый сервис.
Проверьте себя
В копии теста добавьте URL с username и password: classify должен отклонить его. Добавьте stdio-команду с type http: она тоже должна отклониться. Верните исходные данные и получите PASS. Для будущего HTTP-проекта составьте отдельно список: endpoint, проверка Origin, идентификация клиента, разрешение tool, отсутствие секретов в логах, тест отказа доступа. Эти пункты здесь не реализованы и не принимаются за результат упражнения.
Версия и источники
Упражнение закреплено за Python 3.11 и mcp==1.30.0, SDK v1, протоколом 2025-11-25. SDK v2 требует отдельной миграции. Примеры используют синтетические подписи, без внешнего API и модели. Документация сверена 8 октября 2026 года.
Проверены локальный stdio initialize/tools/list и чистая логика трёх ошибок конфигурации. HTTP endpoint, OAuth, Origin на работающем сервере и UI клиента не запускались.
Источники: транспорты 2025-11-25 (в новой вкладке), жизненный цикл (в новой вкладке), HTTP-авторизация (в новой вкладке), форматы VS Code (в новой вкладке).
Вопросы по материалу
Проверка HTTPS-адреса подтверждает, что к серверу можно подключиться?
Нет. classify проверяет только форму учебной конфигурации. Сервер по example.invalid не запрашивается; доступность, поддержка MCP и авторизация остаются непроверенными.
HTTP API из практики — это тот же транспорт, что Streamable HTTP?
Это разные соединения. В практике HTTP-клиент читает данные источника, а MCP-клиент связан с инструментом в памяти. Такой тест не поднимает удалённый MCP endpoint и не проверяет его авторизацию.
Продукты ATOMNO
Другие задачи для AI-помощника
Это отдельные продукты ATOMNO для задач с данными. Они не входят в учебные примеры.
Узнать курс и ставку ЦБ
Помощник получает курсы валют и ключевую ставку.
Курсы и ставка Банка России
Опубликованный клиент; свежесть конкретного ответа сверяйте с источником.
Проверить организацию
ИНН или ОГРН → ограниченная проверка организации.
Проверка контрагента
Состав проверки и доступ уточняйте в документации.
Найти госзакупку
Поиск извещения → чтение карточки закупки.
Поиск госзакупок
Полнота архива и доставка уведомлений не обещаются.
Открыть карточку товарного знака
Номер свидетельства → карточка российского знака.
Карточка товарного знака
Поиск по названию и оценка сходства не входят.