Почему Skill может быть доступен, а tools — нет

В issue #86154 описан воспроизводимый сценарий для Windows: один и тот же plugin при обычном подключении предоставляет MCP-инструменты, а при передаче каталога через --plugin-dir загружает Skills, но не запускает MCP-серверы. Автор отчёта указывает, что в базовом варианте видел 44 инструмента, а в sideload-сценарии не увидел ни одного. Это пользовательский баг-репорт, а не опубликованное Anthropic объяснение первопричины.

В issue автор сравнил два способа загрузки одного plugin. При обычном подключении установленного расширения в сессии появились MCP-инструменты с префиксом mcp__plugin_ado-mcp_ado__*. При загрузке того же каталога через --plugin-dir Skills по-прежнему появлялись, но MCP-tools отсутствовали. В репорте указаны Claude Code 2.1.221 и 2.1.228 для Windows.

Из этого не следует, что Claude Desktop в целом не умеет запускать MCP-серверы plugin или что инструменты теряются в любой desktop-сессии. В issue нет опубликованного объяснения Anthropic, исправления или подтверждения универсальности проблемы. Корректнее говорить об узком сценарии для Windows, определённого способа sideloading и конкретного plugin.

Сам симптом важен и за пределами конкретной версии Claude Code. Агент может следовать workflow-инструкции, упоминать нужную систему или вызывать Skill по имени, но не иметь доступа к Jira, GitHub либо внутреннему сервису. Вопрос «видит ли Claude plugin?» слишком широк. Нужно определить, на каком этапе остановилась цепочка: при обнаружении пакета, регистрации Skill, принятии MCP-конфигурации, подключении к серверу или предоставлении модели схемы инструмента.

  • Skills и MCP-серверы относятся к разным компонентам plugin.
  • Документация указывает, что MCP-серверы включённого plugin запускаются автоматически.
  • Наличие Skill подтверждает работу его слоя, но не успешное соединение с MCP-сервером.

Что Claude Code ищет в plugin

Plugin в Claude Code представляет собой контейнер расширения, а не одну команду. Он может включать Skills, agents, hooks, MCP-серверы, конфигурации языковых серверов и другие компоненты. Документация описывает типовую структуру: метаданные размещаются в .claude-plugin/plugin.json, Skills находятся в skills/, а MCP-конфигурация может быть расположена в .mcp.json или задана inline в plugin.json.

Skill представляет собой управляемый контекст: инструкции, файлы и правила для модели. Его наличие в расширении или доступность как slash-команды означает, что Claude Code прочитал соответствующий компонент. Но это не подтверждает выполнение команды из .mcp.json, наличие нужного токена, запуск локального процесса или регистрацию API-инструментов.

MCP решает другую задачу: клиент подключается к внешнему серверу и получает инструменты, ресурсы или prompts. Для локального stdio-сервера runtime должен запустить дочерний процесс с правильными аргументами и окружением. Для удалённого сервера необходимы корректный transport, сетевое соединение и, если требуется, авторизация. Ошибка на любом шаге оставит Skill видимым, но сделает tool-слой недоступным.

В логах полезнее фиксировать не формулу «plugin не работает», а точный диагноз: «workflow-компонент зарегистрирован, но MCP-компонент не дошёл до состояния, доступного агенту». Такая формулировка сразу задаёт перечень артефактов для проверки: манифест, .mcp.json, окружение, статус сервера, policy и список инструментов в конкретной сессии.

  • Найденный SKILL.md означает discovery Skill, но не успешный запуск сервера.
  • Найденный .mcp.json не гарантирует, что runtime принял валидную конфигурацию.
  • Список tools в начале диалога не всегда отражает доступность сервера из-за tool search.
Цитата в переводе

«Когда plugin включён, его MCP-серверы запускаются автоматически.»

Claude Code Docsтехническая документация Anthropic

Пять стадий диагностики

Первый этап, discovery, означает, что runtime находит файлы и метаданные расширения. Второй, registration, означает появление Skill среди инструкций или команд. Третий этап относится к MCP: Claude Code читает конфигурацию сервера и готовит запуск локального процесса либо удалённое соединение. Эти стадии нельзя сводить к одному тесту: успех на ранней стадии не подтверждает успех на следующей.

На этапе connection сервер может подключиться, ожидать авторизации, не пройти trust-проверку или завершиться с ошибкой. Для project-scoped MCP имеют значение доверие к рабочей папке и одобрение пользователя. Команда claude mcp list нужна, чтобы наблюдать состояние MCP, а не только удостовериться, что конфигурационный файл лежит на диске.

Последний этап, tool exposure, означает доступность инструмента агенту. Claude Code использует MCP tool search: полные определения инструментов не обязательно заранее загружаются в контекст. Модель получает сведения о серверах и запрашивает конкретную схему, когда задача требует действия. Поэтому отсутствие полного списка функций в первом сообщении ещё не доказывает, что сервер не запущен.

Ценность репорта #86154 в том, что он сопоставляет два способа запуска одного plugin. Если Skills доступны в обоих вариантах, а ожидаемые MCP-tools исчезают только при --plugin-dir, следует изучить sideload-путь, а не сразу переписывать Skill или менять модель. Это направление диагностики, а не установленная причина дефекта.

  • Discovery: найдены файлы plugin.
  • Registration: Skill доступен пользователю или модели.
  • Initialization: MCP-конфигурация принята, запуск или соединение подготовлены.
  • Connection: сервер прошёл подключение, авторизацию и необходимые approval.
  • Exposure: агент способен обнаружить и вызвать конкретный tool.

Почему Desktop и CLI нельзя считать одной и той же проверкой

Claude Code Desktop не следует автоматически считать графической оболочкой над идентичным ручным запуском CLI. Документация выделяет desktop application как отдельный режим работы, а автор issue #86154 связывает симптом с передачей каталогов plugin в desktop runtime через --plugin-dir. Это не доказывает ошибку именно в Desktop, но позволяет проверить конкретную гипотезу: различается путь разрешения и загрузки расширения, а не его содержимое.

Если claude mcp list в отдельном терминале показывает сервер, это не подтверждает исправность desktop-сессии. Результат относится к конкретному процессу, набору настроек и моменту запуска. Аналогично, видимый в Desktop Skill не доказывает, что именно эта сессия создала MCP subprocess или подключилась к удалённому endpoint.

Нужно учитывать и managed settings. Документация configuration описывает политики, которые могут контролировать расширения и sideloading. Связанный issue #80763 сообщает о ситуации, когда disableSideloadFlags: true мешает Local Session Claude Desktop запустить CLI-процесс: Desktop использует --plugin-dir для bundled integrations. Это другой симптом, не доказывающий причину #86154, однако policy необходимо включить в проверку.

В корпоративной среде один и тот же plugin может проверяться на личной машине разработчика и на управляемом рабочем устройстве с разными политиками и настройками окружения. Не нужно предполагать локальную специфику Claude Code. Достаточно зафиксировать, какие settings применены на конкретной машине и каким способом стартовала сессия.

  • Не переносите состояние MCP из отдельного CLI-процесса на Desktop без проверки.
  • Сравнивайте установленный plugin и тот же каталог через --plugin-dir.
  • Если проблема возникает на корпоративном устройстве, проверяйте managed settings.

Tool search, cache и transport: где диагностика часто ошибается

Tool search является штатной оптимизацией, а не обязательным признаком сбоя. Согласно документации, Claude Code откладывает загрузку определений MCP-инструментов до момента, когда Claude требуется конкретный tool. Это снижает расход контекста, особенно при большом наборе серверов и функций. Поэтому запрос «покажи все доступные инструменты» не всегда подходит для строгого smoke test. Надёжнее проверить, способен ли агент найти и вызвать известный tool для узкой задачи.

Второй источник путаницы связан с discovery cache для удалённых HTTP- и SSE-серверов. Claude Code может использовать сохранённый список инструментов и фактически подключаться только при первом обращении. Статус cached не означает ни гарантированно работающий сервер, ни гарантированную ошибку. Для чистого диагностического прогона документация рекомендует MCP_DISCOVERY_CACHE=0.

Третья причина связана с transport-конфигурацией. Запись для удалённого сервера с url, но без корректного type, может быть обработана как stdio-конфигурация и пропущена. В режиме stream-json Claude Code сообщает о таких пропусках в mcp_server_errors события system/init; документация указывает, что это поле доступно начиная с версии 2.1.219. Это полезный машинный сигнал для CI-логов.

При корпоративном gateway различия между средами также может создавать непрямой endpoint. Документация сообщает: если ANTHROPIC_BASE_URL ведёт на non-first-party host, Claude Code по умолчанию отключает tool search, поскольку многие proxy не пересылают блоки tool_reference. Это описание поведения при непрямом endpoint, а не утверждение о доступности сервиса в конкретной стране.

  • Для чистого теста cache используйте MCP_DISCOVERY_CACHE=0.
  • Чтобы проверить работу без отложенной загрузки схем, можно использовать ENABLE_TOOL_SEARCH=false.
  • Для безинтерактивной диагностики используйте --output-format stream-json и анализируйте mcp_server_errors.
Цитата в переводе

«Tool search удерживает потребление контекста MCP на низком уровне, откладывая определения инструментов до момента, когда Claude они понадобятся.»

Claude Code Docsтехническая документация Anthropic

Практический runbook: от манифеста до A/B-теста

Начните с пакета, а не с диалога с моделью. Запустите claude plugin validate /path/to/plugin, затем откройте Claude Code с --debug. Plugin reference рекомендует эти действия для поиска ошибок в манифесте, структуре каталогов и регистрации компонентов. В MCP-командах не следует жёстко указывать путь машины разработчика. Для локальных stdio-серверов используйте ${CLAUDE_PLUGIN_ROOT} в command, args и env, где это поддерживается.

Для диагностики удобно разложить расширение на минимальные части: .claude-plugin/plugin.json с метаданными, skills/<имя>/SKILL.md со Skill и .mcp.json с MCP-конфигурацией. Это не единственный допустимый вариант структуры, но он помогает отделить prompt-компонент от tool-компонента. Если Skill обнаружен, а MCP-конфигурация отсутствует в пакете или не принята runtime, качество инструкции не создаст tools.

После валидации проведите A/B-тест. В варианте A используйте установленный и enabled plugin. В варианте B передайте тот же каталог через абсолютный --plugin-dir. Не меняйте prompt, рабочую папку, версию Claude Code, переменные окружения и учётные данные. Сопоставляйте отладочные события, /mcp, статус сервера и способность обнаружить конкретный ожидаемый tool, а не общее впечатление от ответа модели.

Если Skill доступен в обоих прогонах, но MCP-сервер или инструменты исчезают только в варианте B, картина близка к описанной в #86154. Это не устанавливает виновника, но сужает поиск до sideload-пути, desktop invocation и policy. Если tools отсутствуют в обоих вариантах, вернитесь к .mcp.json, путям, окружению, approval и логам подключения.

  • claude plugin validate /absolute/path/to/plugin проверяет пакет до запуска агента.
  • claude --debug помогает наблюдать загрузку plugin и инициализацию MCP.
  • /mcp показывает состояние в текущей интерактивной сессии.
  • После изменения состояния plugin в открытой сессии используйте /reload-plugins.
  • claude mcp list и claude mcp get <server-name> дополняют проверку, но не заменяют её в проблемной desktop-сессии.

Как отделить сбой loader от сбоя MCP-сервера

Сначала проверьте проблему вне агента. Для stdio-сервера это означает запуск той же команды, которая задана в .mcp.json, с теми же аргументами и переменными окружения. Если процесс сразу завершается, не находит бинарник или ждёт интерактивного ввода, Claude Code не сделает его работоспособным. Для удалённого endpoint отдельно проверяют URL, transport, DNS, TLS и учётные данные.

Затем зафиксируйте последнее положительное подтверждение. Сработавший Skill доказывает только работу инструкционного слоя. Сервер в claude mcp list подтверждает, что конкретный runtime знает о конфигурации и сообщает её статус. Успешный вызов ожидаемого tool из той же сессии служит более сильным тестом, чем перечень названий. Успешная операция во внешней системе подтверждает весь путь, включая авторизацию и policy.

Не подменяйте технический smoke test оценкой поведения модели. Агент может не выбрать пригодный инструмент из-за расплывчатой задачи, ограничений или конфликтующих инструкций. С другой стороны, Skill может правильно объяснить последовательность действий, даже если сервер недоступен. Для проверки лучше задать узкий запрос с известным ожидаемым вызовом и безопасным read-only результатом.

В реальном pipeline полезно сохранять версию Claude Code, ОС, способ установки, хеш plugin, .mcp.json без секретов, вывод validation, фрагмент system/init, состояние MCP и тестовый prompt. Тогда скриншот из Desktop превращается в сопоставимый инженерный кейс, который можно воспроизвести на другой машине и сравнить между версиями.

  • Skill сработал: подтверждён слой инструкций, но не доступность внешнего действия.
  • Сервер отображается: подтверждён не весь путь до вызова tool.
  • Успешный вызов конкретного tool является наиболее полезным smoke test в текущей сессии.

Что изменить в агентном pipeline

Plugin не следует тестировать как монолит. Для локальной разработки и CI нужны отдельные проверки: валидация пакета, discovery Skill, доступность MCP-конфигурации, подключение сервера и вызов хотя бы одного безопасного инструмента. Такая декомпозиция не исключает регрессии, но сокращает область поиска, когда агент теряет доступ к внешней системе.

Командам, которые распространяют расширения через marketplace или локальные каталоги, полезно отдельно проверять обычную установку и development/sideload-режим. Документация описывает marketplaces и локальные plugin directories как разные способы работы с расширениями. Кейс #86154 показывает, почему это различие не стоит считать косметическим: одинаковое содержимое plugin следует тестировать в целевом пути запуска.

Для production-агента release gate «Skill виден» недостаточен. Более содержательный критерий таков: в целевом режиме запуска MCP-сервер имеет ожидаемый статус, нужный tool обнаруживается, безопасный вызов возвращает ожидаемый формат, а логи позволяют объяснить отказ.

Это не аргумент против Skills или MCP. Разделение слоёв позволяет обновлять инструкции независимо от сервера и диагностировать сервер без переписывания prompt. Проблемы начинаются, когда продуктовая команда сводит разные состояния к формуле «мы подключили plugin» и не измеряет путь до реального инструментального действия.

  • Добавьте в release checklist A/B-проверку установленного plugin и пути --plugin-dir.
  • Сделайте read-only MCP smoke test частью CI.
  • Сохраняйте диагностические артефакты из целевой сессии, а не только из локального CLI.

Практический чек-лист

Сохраните памятку в PDF: она нужна для повторяемой проверки plugin при регрессии, смене версии Claude Code или переносе расширения между средами.

Что это означает на практике

Issue #86154 не позволяет считать Claude Desktop ненадёжным для MCP или объявлять --plugin-dir повсеместно сломанным. Однако он напоминает об инженерной дисциплине: discovery, registration, connection и tool exposure нужно проверять по отдельности.

Если Claude Code нашёл Skill, но агент не получил инструменты, спрашивайте не «почему модель игнорирует plugin», а «на каком участке pipeline исчезло подтверждение готовности». Проверяемая причина может быть в манифесте, transport, cache, approval, корпоративной policy или возможной регрессии sideload-пути.

Источники

Практический чек-лист

Чек-лист: диагностика Claude Code plugin с MCP

Используйте пункты последовательно и фиксируйте результат в той среде, где возникает проблема. Не заменяйте проверку MCP-сессии результатом из другого CLI-процесса.

1. Проверить пакет plugin

  • Запустите claude plugin validate /absolute/path/to/plugin.
  • Проверьте .claude-plugin/plugin.json, структуру skills/ и наличие MCP-конфигурации.
  • Для локального MCP не используйте жёстко заданный путь машины разработчика: применяйте ${CLAUDE_PLUGIN_ROOT} там, где это поддерживается.
  • Запустите Claude Code с --debug и сохраните диагностический вывод без секретов.

2. Разделить состояния

  • Зафиксируйте отдельно discovery файлов plugin и регистрацию Skill.
  • Проверьте, принята ли MCP-конфигурация и подготовлен ли запуск или удалённое соединение.
  • Проверьте подключение сервера, авторизацию, trust state и approval.
  • Подтвердите tool exposure безопасным вызовом известного read-only инструмента.

3. Выполнить A/B-тест

  • В варианте A используйте установленный enabled plugin.
  • В варианте B передайте тот же каталог через абсолютный --plugin-dir.
  • Не меняйте prompt, рабочую папку, версию Claude Code, переменные окружения и учётные данные.
  • Сравните /mcp, debug-вывод, состояние сервера и результат вызова ожидаемого tool.

4. Убрать неоднозначность диагностики

  • Для чистого прогона cache используйте MCP_DISCOVERY_CACHE=0.
  • Если нужно исключить отложенную загрузку схем, используйте ENABLE_TOOL_SEARCH=false.
  • Для безинтерактивного прогона используйте --output-format stream-json и проверьте mcp_server_errors в system/init.
  • На корпоративном устройстве зафиксируйте managed settings, включая политики sideloading.

Вопросы и ответы

Почему Claude Code видит Skill, но не показывает MCP-инструменты?

Skill и MCP-сервер проходят разные стадии. Обнаруженный `SKILL.md` подтверждает загрузку инструкционного компонента, но не подтверждает принятие MCP-конфигурации, запуск процесса, подключение, авторизацию и доступность схемы инструмента агенту.

Что сравнить при проблеме с `--plugin-dir`?

Проведите A/B-тест: в варианте A используйте установленный enabled plugin, в варианте B передайте тот же каталог через абсолютный `--plugin-dir`. Не меняйте версию Claude Code, рабочую папку, prompt, переменные окружения и учётные данные.

Доказывает ли `claude mcp list`, что инструмент доступен в Claude Desktop?

Нет. Команда отражает состояние конкретного процесса и конфигурации. Для desktop-сессии отдельно проверьте `/mcp`, отладочные события и успешный вызов известного read-only tool именно в проблемной сессии.

Зачем отключать MCP discovery cache и tool search?

Это помогает убрать неоднозначность при диагностике. `MCP_DISCOVERY_CACHE=0` исключает использование сохранённого discovery-списка, а `ENABLE_TOOL_SEARCH=false` позволяет проверить сценарий без отложенной загрузки определений tools.