18 KiB
#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(permissionscenario 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 или MCPlist_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:
- Администратор регистрирует live-binding на DEV/PREPROD-среду через admin API
PUT /api/scenario-live-bindings/{binding_ref}(backend/src/api/routes/dashboard_testing/scenario_live_bindings.py, permissionadmin:settings WRITE). Snapshot содержит только identity/fingerprints — никаких секретов;execution_principal_fingerprint=sha256(actor)— имя пользователя, чьим OAuth-токеном будут стартовать раны (пример:sha256("admin")). - Аналитик просит агента: «поставь сценарий X на cron …» →
upsert_scenario_schedule(permissionscenario:automation MANAGE). - Каждый 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