Проблемы интеграции MCP-сервера: протокол, transport, права и schema

Диагностика ошибок и надёжности MCP-сервера по слоям: версия протокола, transport, запуск, права, inputSchema и безопасный Inspector tool call.

Если MCP-сервер не подключается или tool call завершается ошибкой, не меняйте одновременно конфигурацию клиента, код сервера и права. Сначала определите слой сбоя. Рабочий порядок такой: версия протокола → transport → запуск и окружение → permissions/auth → inputSchema → один read-only вызов.

По состоянию на 23 августа 2026 года актуальная проверенная спецификация MCP имеет версию 2026-07-28. В ней нет старого обязательного handshake через initialize: client может использовать server/discover, а версия протокола, сведения о client и его capabilities передаются с запросами в _meta. Для legacy-реализаций 2025-11-25 и старше действует другая последовательность — initialize, ответ сервера, затем notifications/initialized. Эти две эпохи нельзя соединять в один обмен.

Сразу отделите MCP от модельного API. MCP отвечает за связь client с tools и контекстом; вызов модели может идти по другому маршруту и с другими credentials. Изолируйте модельный слой по инструкции BetterToken: собственный API Key и выбранный OpenAI-compatible или Anthropic-compatible интерфейс дают отдельный проверяемый маршрут, поэтому ошибку модели не придётся искать в MCP. Этот Key не является credential MCP-сервера, а BetterToken не следует считать MCP-host или MCP-transport.

Быстрая классификация сбоя

До запуска Inspector запишите один симптом и последнюю подтверждённую точку:

  • процесс вообще не стартует;
  • процесс работает, но client не получает JSON-RPC;
  • transport отвечает, но версия или capabilities не согласуются;
  • сервер возвращает 401 или 403;
  • tools/list работает, но нужного tool нет;
  • tool виден, однако tools/call отклоняет arguments;
  • вызов проходит, но результат нельзя проверить.

Не записывайте в заметку API Key, bearer token, cookie, полный prompt или содержимое приватных файлов. Для корреляции достаточно времени, имени сервера, метода, JSON-RPC id, кода ошибки и очищенного сообщения.

1. Зафиксируйте эпоху протокола

Узнайте, какую версию поддерживают client, server и используемый SDK. Строка Connected подтверждает transport и часть discovery, но сама по себе не доказывает согласование 2026-07-28.

Для современной реализации проверьте три признака:

  1. SDK или release notes прямо заявляют поддержку 2026-07-28.
  2. В трассировке есть server/discover либо другой предусмотренный SDK путь discovery.
  3. На запросах присутствует корректная _meta с версией, сведениями о client и capabilities.

Не копируйте вручную форму _meta из чужого SDK: точный wire-формат должен формировать совместимый client или официальный SDK. Если server ждёт initialize, а client отправляет self-contained запросы 2026-07-28, это несовместимость эпох, а не ошибка tool schema.

Legacy initialize: только для 2025-11-25 и старше

Ниже показан минимальный legacy-запрос. Его нельзя добавлять в современный flow 2026-07-28 «для надёжности».

{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-11-25", "capabilities": {}, "clientInfo": { "name": "mcp-diagnostic-client", "version": "1.0.0" } } }

После успешного ответа legacy-client отправляет notifications/initialized. Если этот обмен обрывается, сначала сравните версии и список capabilities. До tools/list ещё рано.

2. Проверьте transport отдельно от семантики MCP

MCP определяет методы и данные, а transport — запуск, framing, доставку и отмену запросов. Переход со stdio на HTTP не исправит неверный inputSchema.

stdio

При stdio client запускает server как дочерний процесс. Сообщения идут через stdin и stdout как разделённые переводом строки UTF-8 JSON-RPC документы.

Проверяйте:

  1. command существует и запускается тем же пользователем.
  2. Аргументы переданы отдельными элементами, без зависимости от shell aliases.
  3. Рабочий каталог содержит нужные файлы либо пути абсолютные.
  4. Нужные переменные действительно доступны дочернему процессу.
  5. В stdout нет banner, отладочных строк и stack trace — логи направляются в stderr.

Один случайный console.log() в stdout способен сломать framing раньше, чем client увидит JSON-RPC response.

Streamable HTTP

При Streamable HTTP client отправляет сообщения методом POST на один MCP endpoint. Ответ может быть обычным JSON или request-scoped SSE. Проверьте точный URL, HTTP method, Content-Type, TLS, redirect, proxy и способ авторизации.

Сделайте transport-тест на loopback или в изолированном тестовом окружении. Публичный production endpoint без разрешения не сканируйте. Если POST возвращает HTML страницы входа, 301/302 на другой host или ответ reverse proxy, вы ещё не дошли до MCP.

3. Воспроизведите запуск в том же окружении

Для stdio сначала выполните server command напрямую из того же каталога и под тем же пользователем, что и MCP-client. Не подменяйте это запуском из IDE: там могут отличаться PATH, cwd, runtime и permissions.

Проверьте:

node --version pwd node ./dist/server.js

pwd не раскрывает secret, но не публикуйте путь, если в нём есть имя пользователя или название закрытого проекта. Команда сервера должна либо ждать JSON-RPC на stdin, либо завершиться с понятной ошибкой в stderr. Мгновенный exit без сообщения обычно указывает на неверный entrypoint, отсутствующую зависимость или обработанную без лога ошибку запуска.

Для Inspector CLI официальная документация на 23 августа 2026 года требует Node.js 22.19.0 или новее. Если версия ниже, остановитесь и переключите runtime до дальнейшей диагностики.

4. Разделите permissions и authentication

Код ответа помогает выбрать следующую проверку:

  • 401 Unauthorized — credential отсутствует, истёк или не принят;
  • 403 Forbidden — identity распознана, но у неё нет нужного permission или scope;
  • 404 — часто неверный endpoint или маршрут, а не нехватка прав;
  • timeout — server, proxy или tool не завершили операцию вовремя; это не доказательство ошибки auth.

Не отключайте permissions ради smoke test. Создайте отдельную тестовую identity с минимальным scope и выберите read-only tool без внешнего эффекта. Client должен оставлять человеку возможность отклонить вызов; annotations инструмента считаются недоверенными данными и не заменяют policy.

В логах сохраняйте решение auth (allowed/denied), имя scope и correlation ID. Сам credential, Authorization header и cookie должны быть удалены или замаскированы.

5. Проверьте capability и inputSchema

Server обязан объявить capability tools до обслуживания tools/list. У каждого tool должно быть уникальное имя и валидный объект JSON Schema в inputSchema. Arguments для tools/call должны соответствовать этой schema.

Минимальное объявление read-only инструмента:

{ "name": "echo", "description": "Возвращает переданный текст без изменений", "inputSchema": { "type": "object", "properties": { "text": { "type": "string" } }, "required": ["text"], "additionalProperties": false } }

Частые ошибки здесь простые: нет корневого type: object, обязательное поле отсутствует в properties, client отправляет число вместо строки, имя argument отличается регистром или server рекламирует два tools с одинаковым именем.

После согласования версии и transport метод можно проверить таким JSON-RPC payload:

{ "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {} }

А затем вызвать ровно один tool:

{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "echo", "arguments": { "text": "MCP_OK_2026" } } }

Эти два фрагмента показывают payload методов, а не полный bootstrap соединения. В flow 2026-07-28 совместимый client добавляет требуемую request metadata в _meta; в legacy-flow сначала выполняется initialize. Не отправляйте приведённые JSON вручную в production endpoint без разрешения.

6. Запустите безопасный тест через MCP Inspector CLI

Сначала установите Inspector как зафиксированную project dependency из доверенного lockfile. Команда --no-install ниже не скачивает случайную текущую версию во время диагностики.

Проверка списка tools у локального stdio-сервера:

npx --no-install @modelcontextprotocol/inspector --cli node ./dist/server.js --method tools/list

Один вызов echo:

npx --no-install @modelcontextprotocol/inspector --cli node ./dist/server.js \ --method tools/call \ --tool-name echo \ --tool-arg text=MCP_OK_2026

Для тестового Streamable HTTP endpoint на loopback:

npx --no-install @modelcontextprotocol/inspector --cli \ http://127.0.0.1:3000/mcp \ --transport http \ --method tools/list

Не вставляйте token в историю shell, URL или статью. Если endpoint требует auth, настройте credential штатным способом Inspector в локальном окружении либо остановите тест и запросите тестовую identity у владельца сервера. Команды выше намеренно не содержат реального Key.

Симптом → проверка → исправление

СимптомЧто проверить первымМинимальное исправление
spawn ENOENT или процесс не найденАбсолютный путь к command, runtime и PATH процесса clientУказать существующий executable или исправить окружение запуска
Процесс сразу завершаетсяcwd, entrypoint, зависимости, ошибка в stderrЗапускать из правильного каталога и вернуть понятный non-zero exit
Client пишет JSON parse errorПосторонний вывод в stdout, UTF-8 и перевод строкиОставить в stdout только JSON-RPC, логи перенести в stderr
HTTP возвращает HTML или redirectMCP URL, proxy, TLS и маршрут POSTУказать один корректный MCP endpoint, исправить proxy rule
Ошибка версии до tools/listЭпоха протокола и поддержка SDKОбновить совместимую сторону или явно сохранить legacy-path; не смешивать handshake
401 UnauthorizedНаличие и срок действия credentialПолучить отдельный тестовый credential штатным способом
403 ForbiddenScope, resource policy и identityВыдать только требуемый scope тестовой identity
tools/list → method/capability errorОбъявлена ли capability toolsИсправить capability declaration до регистрации tools
Tool отсутствует в спискеУникальное имя и фактическая регистрацияЗарегистрировать один tool и перезапустить server
tools/call отклоняет argumentsinputSchema, типы, required и регистр имёнПривести arguments к schema; не ослаблять её до произвольного объекта
Вызов зависаетtimeout, cancellation и внешняя зависимость toolЗаменить тест на локальный read-only echo, затем проверять зависимость отдельно

Критерий успешной проверки

Интеграция проходит минимальную приёмку, когда одновременно выполнены пять условий:

  1. В логах или telemetry видна ожидаемая согласованная версия протокола.
  2. Transport не повреждает framing: stdio не содержит лишнего stdout, а HTTP отвечает с MCP endpoint.
  3. tools/list возвращает один ожидаемый tool с валидным inputSchema.
  4. tools/call действительно вызывается с text=MCP_OK_2026 и возвращает MCP_OK_2026 без изменений.
  5. Тест не отключал permissions, не раскрывал credentials и не вызвал внешнего побочного эффекта.

Просто увидеть строку MCP_OK_2026 в ответе модели недостаточно. Нужен зафиксированный tool call с соответствующим JSON-RPC id или записью Inspector и очищенным server log.

Stop conditions

Остановите диагностику и не переходите к следующему слою, если:

  • неизвестно, какую эпоху протокола поддерживает хотя бы одна сторона;
  • Inspector предлагает установить незакреплённую версию пакета без проверки;
  • тест требует production credential, отключения auth или расширения scope;
  • единственный доступный tool пишет в базу, отправляет сообщение, меняет файл или запускает команду;
  • HTTP endpoint принадлежит третьей стороне и разрешение на тест не подтверждено;
  • в логах появились Key, token, cookie, персональные данные или содержимое приватного ресурса;
  • tools/list нестабилен или возвращает разные schema между повторными запусками;
  • server падает до появления валидного JSON-RPC response.

В этих случаях сохраните очищенный симптом, версию client/server/SDK, transport, correlation ID и минимальный фрагмент ошибки. Этого достаточно, чтобы передать проблему владельцу нужного слоя без раздачи лишних прав и секретов.

Источники

Сведения о версии спецификации, transport и минимальной версии Node.js проверены 23 августа 2026 года. Перед повторением диагностики после обновления client, server, SDK или Inspector сверьте текущую официальную документацию.

Готовы оптимизировать LLM workflow?

Подключите единый API, управляйте ключами и контролируйте расходы на AI-модели в BetterToken.