Files
ss-tools/docs/mcp-client-setup.md

18 KiB
Raw Permalink Blame History

#region Doc.McpClientSetup [C:2] [TYPE ADR] [SEMANTICS mcp,onboarding,runbook,oauth,rbac,scenario,gitea] @BRIEF Onboarding-гайд для BI-аналитика: как подключить внешнего MCP-агента (kilocode / opencode / openwebui / другой MCP-клиент) к ss-tools, какие scopes нужны по фазам работы, типовые цепочки инструментов, PROD-гейт, typed errors и два канала Gitea-конфигурации. @RELATION DEPENDS_ON -> [McpServer.RbacLayer] @RELATION DEPENDS_ON -> [ScenarioExecution.PublishedCatalogSource] @RELATION DEPENDS_ON -> [Api.ScenarioLiveBindings] @RATIONALE UX-3 (docs/reports/ux-flow-improvement-plan-2026-09-11.md): единственный путь создания сценария тестирования дашборда — внешний MCP-агент, но документа по подключению не было; сюда же влез остаток UX-2 (runbook двух каналов Gitea).

Подключение MCP-агента к ss-tools (гайд для BI-аналитика)

Документ описывает, как подключить внешнего MCP-клиента (агента) к ss-tools и довести работу до первого smoke-check. Путь «создать сценарий тестирования дашборда» существует только через внешнего агента — в продуктовом UI агентских контролов нет (frontend boundary 2026-09-08).

1. Подключение клиента

Endpoint: {ss-tools}/mcp (например, http://127.0.0.1:8000/mcp на локальном стенде). Транспорт: Streamable HTTP.

OAuth-флоу (проверено live 2026-09-11, см. docs/2026-09-11-sales-prod-mcp-replay.md §Execution facts): REST login + OAuth discovery → Dynamic Client Registration (public client) → PKCE consent в браузере → access token. Клиент регистрируется сам при первом подключении; заранее создавать client_id не нужно. Логинитесь своей учётной записью ss-tools — права агента равны правам вашего пользователя (см. §2).

Конфиги клиентов (типовые; точные поля зависят от версии клиента)

kilocode — в настройках MCP (mcp_settings.json):

{
  "mcpServers": {
    "ss-tools": {
      "url": "http://127.0.0.1:8000/mcp",
      "transport": "streamable-http"
    }
  }
}

opencode — в opencode.json:

{
  "mcp": {
    "ss-tools": {
      "type": "remote",
      "url": "http://127.0.0.1:8000/mcp",
      "oauth": true
    }
  }
}

openwebui — Admin Panel → Settings → External Tools: добавить MCP-сервер с URL http://127.0.0.1:8000/mcp, тип подключения Streamable HTTP / OAuth. Версии openwebui отличаются по названиям полей; ищите «MCP» / «Streamable HTTP» в настройках инструментов.

При первом вызове инструмента клиент откроет браузер для PKCE-consent: подтвердите доступ под своим пользователем.

Smoke-check

Шаг Ожидание
tools/list до 62 tools — каталог фильтруется по вашим RBAC-правам, поэтому реальное число зависит от роли (исторический ориентир: live-replay 2026-09-11 фиксировал 61 tool; каталог растёт только аддитивно)
search_dashboards(environment_id="ss-prod", query="sales") находит dashboard ID 11 («Sales Dashboard») — так на live-стенде 2026-09-11

Если tools/list пуст — у пользователя нет ни одного нужного permission (см. §2).

2. Scopes по фазам работы

Права проверяются по каталогу backend/src/mcp_server/rbac_server.py (permission объявлен рядом с каждым tool). Нужные grants выдаёт администратор в RBAC ss-tools.

Фаза Permission Инструменты
Inspect / search без спец-scopes (достаточно аутентификации) search_dashboards, inspect_dashboard_context, inspect_scenario, validate_scenario, generate_draft_pack, bootstrap_authoring_scenario
Authoring dashboard:testing EXECUTE + dashboard:testing WRITE create_agent_run (EXECUTE), register_draft_pack (WRITE)
Run (не-PROD) scenario RUN start_scenario_run, list_checkpoints, decide_checkpoint
Approve (PROD) scenario RUN_PROD start_scenario_run на PROD-среде, list_pending_approvals, decide_approval, publish_baseline_catalog
Automation scenario:automation MANAGE upsert_scenario_schedule, delete_scenario_schedule, upsert_scenario_trigger_rule, upsert_scenario_automation_policy (list/get — без спец-scopes)

Для start_scenario_run сервер сам выбирает RUN vs RUN_PROD по environment policy: неизвестная среда — fail-closed отказ, PROD-среда — требуется RUN_PROD.

Human-only правило. 47 из 62 инструментов каталога помечены service_allowed=False — service principal (SERVICE_JWT-интеграции) не подойдёт: вся сценарная работа, approvals, checkpoints и publish доступны только живому пользователю с OAuth-токеном. Не пытайтесь подключить агента под service account.

3. Типовые фразы агенту и что он сделает

Цепочки подтверждены live-прогоном docs/2026-09-11-sales-prod-mcp-replay.md (E2E-EXT-002, стенд, dashboard 11 на ss-prod).

Фраза Цепочка инструментов под капотом Результат
«Создай сценарий для sales на ss-prod» search_dashboards → inspect_dashboard_context → create_agent_run → inspect_scenario → validate_scenario → generate_draft_pack → register_draft_pack → bootstrap_authoring_scenario Сценарий + current revision в реестре; context_authority=verified
«Запусти» (на ss-prod) start_scenario_run pending_approval — создан durable PROD-гейт; повторный вызов идемпотентен (тот же гейт, не новый ран)
«Запусти» (на DEV/PREPROD) start_scenario_run ран уходит в исполнение сразу, без гейта
«Есть ли раны, ждущие моего решения?» list_pending_approvals список pending PROD-гейтов
«Подтверди ран» decide_approval гейт approved → scheduler исполняет ран
«Поставь на cron» upsert_scenario_schedule расписание; PROD — гейт на каждый due-ран (см. §4)

Compile/validate детерминированы (без LLM внутри): агент передаёт в inspect_scenario capabilities, возвращённые inspect_dashboard_context (derived_capabilities), плюс caller-заявки вроде screenshot: true; сервер не даёт caller-заявке понизить верифицируемый факт.

4. PROD-гейт и human checkpoint

  • Approve — только человек. Решение принимается в UI (панель рана в мониторе) или через MCP list_pending_approvals / decide_approval (permission scenario RUN_PROD, human-only). Автоматического approve не существует by design.

  • Scheduled PROD = гейт на КАЖДЫЙ due-ран (by design): cron создаёт ран и durable гейт; без вашего решения ран не исполняется. Это подтверждено live-цепочкой cron → PROD gate → approval → execution (specs/044-dashboard-scenario-execution/prototype/live_scheduled_run.py).

  • Автономные расписания — только не-PROD (см. §8).

  • HumanCheckpoint (шаг с tool=human) переводит ран в waiting_human; disposition — через UI или MCP list_checkpoints / decide_checkpoint. Иммутабельный маппинг исходов (044):

    Кнопка / disposition Персистентный исход
    «Подтвердить соответствие» (confirm) passed — проверка пройдена, не подтверждение дефекта
    «Проблема не подтверждена» (false_positive) inconclusive
    «Недостаточно данных» (inconclusive) inconclusive
  • Сценарий с human-шагом не может стоять на расписании: scheduler завершит такой due-ран typed AUTOMATION_INELIGIBLE_HUMAN_STEP.

5. Параметры фильтров

native_filters_key из URL Superset эфемерен и не импортируется (by design): ссылка на дашборд с применённым фильтром не переносится в сценарий. Фильтры задаются typed-параметром графа filter_values (объявляется в inspect_scenario → parameters, образец — _author_b01 в specs/044-dashboard-scenario-execution/prototype/live_scheduled_run.py:

"parameters": {
  "filter_values": {"type": "string_list", "required": true, "default": []}
}

Просите агента явно: «добавь параметр filter_values и проверь с region=South».

С 2026-09-12 (plan UX-1/UX-6) значение параметра доезжает до исполнения: apply_native_filter — read-only browser-действие (filter bar, чекпоинты filter_applied/charts_settled), и filter_values из параметров запуска биндится в его input при derivation RunnerPlan (Ref(name="param.filter_values") из графа резолвится сервером). Семантика fail-closed:

  • параметр задан → фильтр применяется к заданным значениям;
  • параметр не задан / пустая строка → шаг работает в режиме наблюдения текущего состояния (current_state);
  • пустой список [] → тоже режим наблюдения; невалидный тип параметра → typed reject рана до создания строк (никакой «тихой» подмены фильтра).

UI (RunConfigurationPanel) сегодня передаёт string-строку параметра = одно значение; список значений — через MCP start_scenario_run c params.filter_values списком.

6. Troubleshooting: typed errors

Fail-closed: неподдержанное/недоступное — всегда typed non-pass, PASS не синтезируется.

Код Трактовка Что делать
AUTOMATION_INELIGIBLE_HUMAN_STEP У текущей revision есть human-шаг — автоматический (scheduled/triggered) запуск запрещён by design Запускайте вручную (trigger=manual) или пересоберите граф без HumanCheckpoint
*_BINDING_MISSING (SUPERSET_/BROWSER_/SCREENSHOT_BINDING_MISSING) Для dashboard/environment нет live-binding — ран стартовал без авторизованного слепка Зарегистрируйте binding через admin API (§8)
*_BINDING_UNAVAILABLE Binding есть, но enabled=false Включите: PATCH /api/scenario-live-bindings/{ref} ({"enabled": true})
*_BINDING_INVALID Слепок binding не прошёл валидацию формы Перерегистрируйте binding корректным snapshot
*_BINDING_MISMATCH Идентичность шага/релиза не совпала с запиненной в binding (dashboard/release/principal drift) Перерегистрируйте binding под актуальный релиз и actor
DRAFT_PACK_ACCESS_DENIED register_draft_pack под чужим/несуществующим AgentRun — владение проверяется по principal Создайте AgentRun сами (create_agent_run) и используйте его id; side effects при отказе — ноль
PUBLISH_HEAD_MOVED HEAD целевой ветки Gitea сдвинулся с момента approve (CAS publish) Запросите новый approve и повторите publish
PUBLISH_SOURCE_UNCONFIGURED Не заданы PUBLISHED_CATALOG_GITEA_* env (§7) Настройте process env и перезапустите backend
BROWSER_ACTION_NOT_SUPPORTED Изолированный browser-транспорт допускает только read-only каталог (open_dashboard, wait_for_state, refresh, apply_native_filter) + контрактные SQL-Lab мутации; запрос не из каталога Действие не входит в versioned ActionRegistry — проверьте inspect_scenario/дескриптор шага; терминал рана честный inconclusive
BROWSER_SELECTOR_NOT_FOUND Filter-bar контрол не найден в текущей версии Superset UI Fail-closed по дизайну (план UX-1): без retry; уточните selector_hint шага или обновите дескриптор

7. Runbook: два канала Gitea-конфигурации

Gitea используется в двух независимых местах — настройка одного не включает другой:

Канал Где настраивается Для чего
Settings → Git (UI, ConfigManager) Веб-интерфейс ss-tools Git-плагин: ветки, коммиты, deploy дашбордов
PUBLISHED_CATALOG_GITEA_URL / PUBLISHED_CATALOG_GITEA_TOKEN / PUBLISHED_CATALOG_REPO / PUBLISHED_CATALOG_REF (+ опционально PUBLISHED_CATALOG_PATH_TEMPLATE) Только process env backend-процесса (backend/src/services/dashboard_testing/execution/published_catalog_source.py:38-43) Baseline catalog: чтение published-слепков при старте рана и publish worker

@INVARIANT: токен читается только из process environment, никогда не из БД и не логируется. На чистом стенде без PUBLISHED_CATALOG_* publish завершится typed PUBLISH_SOURCE_UNCONFIGURED (HTTP 503), а baseline-backed старт — fail-closed BASELINE_NOT_PUBLISHED.

Как проверить: GET /api/catalog-publications — список публикаций; smoke publish на DEV-ветку через publish_baseline_catalog (требует scenario RUN_PROD + approval). Отсутствие env сразу даёт typed PUBLISH_SOURCE_UNCONFIGURED — это ожидаемый сигнал, а не сбой.

8. DEV/PREPROD: автономные расписания («поставил и забыл»)

Без человеческого гейта расписание работает только вне PROD:

  1. Администратор регистрирует live-binding на DEV/PREPROD-среду через admin API PUT /api/scenario-live-bindings/{binding_ref} (backend/src/api/routes/dashboard_testing/scenario_live_bindings.py, permission admin:settings WRITE). Snapshot содержит только identity/fingerprints — никаких секретов; execution_principal_fingerprint = sha256(actor) — имя пользователя, чьим OAuth-токеном будут стартовать раны (пример: sha256("admin")).
  2. Аналитик просит агента: «поставь сценарий X на cron …» → upsert_scenario_schedule (permission scenario:automation MANAGE).
  3. Каждый due-ран на DEV/PREPROD исполняется до терминала без approve. Условия: revision без human-шагов (иначе AUTOMATION_INELIGIBLE_HUMAN_STEP) и валидный enabled binding (иначе typed *_BINDING_*).

На PROD та же конфигурация даёт гейт на каждый due-ран — автономных PROD-расписаний не бывает by design.

Источники

  • Live-доказательства: docs/2026-09-11-sales-prod-mcp-replay.md (E2E-EXT-002).
  • План: docs/reports/ux-flow-improvement-plan-2026-09-11.md (UX-2, UX-3, UX-6, UX-7, UX-8).
  • Каталог tools/permissions: backend/src/mcp_server/rbac_server.py.
  • Binding admin API: backend/src/api/routes/dashboard_testing/scenario_live_bindings.py.
  • Publish source env: backend/src/services/dashboard_testing/execution/published_catalog_source.py.
  • Typed filter_values: specs/044-dashboard-scenario-execution/prototype/live_scheduled_run.py (_author_b01).
  • Disposition labels: frontend/src/lib/i18n/locales/ru/dashboard-testing.json, specs/044-dashboard-scenario-execution/spec.md (Field-run Amendment). #endregion Doc.McpClientSetup