Filled all sections from source docs: - ~/projects/.workshop/.archive/2026-05-12-using-synology-ops-skill.md - ~/projects/.wiki/concepts/synology-ops-mcp-design.md Sections: When to use (triggers), Inputs, Steps (4 flows), Failure modes, Side effects, What NOT to do (mistakes + red flags). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.7 KiB
6.7 KiB
name, version, description
| name | version | description |
|---|---|---|
| using-synology-ops | 0.1.2 | Use when diagnosing docker containers on the Synology NAS — the `synology-ops` HTTP MCP server (https://opsmcp.kzntsv.site/mcp) exposes 4 read-only tools — `ops.docker.ps`, `ops.docker.logs`, `ops.docker.inspect`, `ops.docker.stats` — all routed through tecnativa `synology-docker-proxy-ro` with `POST=0` (write-ops return 403). Triggers on container names (`modulair-rag`, `modulair-pipeline`, `lightrag-modulair`, `tier1-converter`, `modulair-mcp`, `synology-ops-mcp`), on NAS-domain words ("на NAS", "Synology", "синолоджи", "Portainer-стек", "ops-mcp", "опс мсп", "opsmcp.kzntsv.site"), or on incident phrases ("падает", "restart-loop", "не стартует", "unhealthy", "посмотри логи") when NAS-context. Read-only by design — no per-session grant needed. Skip for non-incident mentions, "open Portainer GUI" requests, write-ops, and incident phrases on non-NAS hosts (`books-pipeline`, `vps-*` etc. — only the 6 listed above are NAS-hosted). |
using-synology-ops
Trigger-and-guidance skill для synology-ops-mcp — read-only HTTP MCP-сервера на NAS, дающего Claude'у видимость состояния docker-контейнеров без юзера-моста (без Portainer copy-paste).
When to use
Trigger — любой из трёх сигналов:
-
Контейнерные имена (явный NAS-signal):
modulair-rag,modulair-pipeline,lightrag-modulair,tier1-converter,modulair-mcp,synology-ops-mcp,synology-docker-proxy-ro
-
Доменные слова Synology:
- «на NAS», «Synology», «синолоджи», «Portainer-стек», «opsmcp.kzntsv.site», «ops-mcp», «опс мсп», «synology-ops»
-
Инцидент-фразы (в NAS-контексте):
- «падает», «restart-loop», «не стартует», «unhealthy», «медленно грузится», «не видит соседа», «посмотри логи», «что с контейнером X»
Skip: упоминание в неинцидент-контексте («modulair-rag deploy запланирован на завтра»), явный отказ («открой Portainer GUI»), инцидент-фразы для non-NAS хостов (books-pipeline, vps-* и т.д.).
Inputs
- Имя контейнера (если есть) — для скоупинга
logs/inspect/stats - Симптом — «падает», «медленно грузится», «не видит соседа» — определяет starting tool
- Scope — «один контейнер» vs «весь стек» vs «все на NAS»
Steps
Флекс-паттерны — рекомендации, не жёсткий чек-лист.
| Сценарий | Старт-тап | Последовательность |
|---|---|---|
| «Контейнер X падает» | ops.docker.ps({ name: "X", state: "all" }) → видит restart count |
logs({ name: "X", tail: 200, stream: "both" }) → если dependency error → ps({ name: "<dep>" }) → если нет соседа → inspect({ name: "X" }) |
| «Проверь стек целиком» | ops.docker.ps({ state: "all" }) |
Группировка по stack labels → если problem видны сразу — diagnosis, иначе → ask user |
| «Медленно грузится» | ops.docker.stats({ name: "X" }) |
Если CPU/Mem OK → logs({ name: "X", since: "5m" }) на стартап-фазу |
| «Не видит соседа в сети» | ops.docker.inspect({ name: "X" }) |
Достать NetworkSettings.Networks → сверить с inspect соседа |
Формат отдачи юзеру:
- Диагноз — одна строка («
modulair-pipelineв restart-loop, ECONNREFUSEDpostgres:5432, контейнераpostgresв сетиmodulairнет») - Evidence — 3-5 строк (релевантные логи / env / networks), hard cap 15 строк
- Гипотеза следующего шага — 1-2 строки
Юзер просит «покажи всё» → отдать всё, дефолт — выжимка.
Failure modes
| Сценарий | Симптом | Действие |
|---|---|---|
| Контейнер не существует | ops.docker.logs error «container not found» |
Подсказать доступные: ps({ state: "all" }) → список |
| Docker proxy недоступен | Timeout / connection refused | «synology-docker-proxy-ro unreachable — check stack health в Portainer» |
| 403 от docker-proxy | Попытка write-op (implicit) | «operation forbidden by tecnativa ACL — это read-only proxy, используй Portainer GUI для restart/exec» |
| Output > 1MB | Логи обрезаны | Вернуть первый MB + truncated: true, actualBytes: N |
| Bearer token невалидный | 401 на любой вызов | «check ~/.claude.json → mcpServers.synology-ops.headers.Authorization соответствует ли токену в Portainer stack env» |
Side effects
- Latency — HTTPS round-trip к NAS ~200ms, batch'ить вопросы, не дёргать в цикле
- Capping —
logscap 1MB,tailmax 5000 строк — если нужно больше, ask - Маскирование — env-vars с именами
/PASSWORD|TOKEN|SECRET|KEY|PASS|CREDS/iзаменены на***вinspect— regex может пропустить кастомные ключи, warning не certainty
What NOT to do
Common mistakes:
- ❌ Звонить
logsбез явногоtail(default 200, но явный = намеренный) - ❌ Звонить
logsдля всех контейнеров подряд («покажи всё» — сначалаps) - ❌ Интерпретировать
***в env как «вижу пароль» — это masked, может быть кастомный ключ - ❌ Пытаться write-ops (restart/exec/prune) через MCP — 403, направлять юзера в Portainer GUI
- ❌ Кэшировать
pslong-term — состояние NAS меняется, перезвонить
Red flags:
- 🔴 Дёргать в цикле — latency ~200ms через HTTPS, собрать вопросы в один batch
- 🔴 Проверять non-NAS контейнеры этим MCP (
books-pipeline,vps-*) — они не видны synology-ops-mcp - 🔴 Env-masked regex — не гарантия, могут быть кастомные ключи (
DB_URI,API_CREDENTIALSи т.п.)