From ae36a9fbac67e1a594e290e58ec827b39187de07 Mon Sep 17 00:00:00 2001 From: Marcus van Elst Date: Tue, 21 Apr 2026 07:26:56 +0200 Subject: [PATCH] v0.2.3: scrub operator-specific details from CLAUDE.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove hostnames, concrete container names, image tags, personal notes, and the completed task backlog. Replace with generic DSM quirks reference, implementation rules, and tool inventory — suitable for a public connector. Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 8 ++ CLAUDE.md | 214 +++++++++++-------------------------------------- pyproject.toml | 2 +- 3 files changed, 58 insertions(+), 166 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08864b1..36da591 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. +## [0.2.3] - 2026-04-21 + +### Changed + +- `CLAUDE.md` rewritten: removed all operator-specific infrastructure details + (hostnames, container names, image tags, personal notes). Kept DSM API quirks, + implementation rules, and tool inventory. + ## [0.2.2] - 2026-04-21 ### Fixed diff --git a/CLAUDE.md b/CLAUDE.md index e1069a9..50a7a28 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,197 +1,81 @@ # mcp-synology-container -## Kontext +## Project -Dieses Projekt entwickelt und betreibt `mcp-synology-container` – einen MCP-Server -für die vollständige Verwaltung von Docker-Projekten auf einer Synology DiskStation -via Container Manager. Der MCP-Server ist in Claude Desktop aktiv verbunden. +`mcp-synology-container` is an MCP server for managing Docker projects on a +Synology DiskStation via Container Manager. It exposes tools for projects, +containers, images, compose files, networks, and system housekeeping. --- -## Infrastruktur +## Tech stack | | | |---|---| -| **NAS** | `https://dsm.gecheckt.de` (Split-DNS, intern direkt aufgelöst) | -| **Compose-Pfade** | `/volume1/docker//` | -| **Gitea** | `https://gitea.gecheckt.de/marcus/mcp-synology-container` | -| **Lokaler Code** | `D:\Dev\Projects\mcp-synology-container` | -| **Sprache** | Python 3.12+, `uv`, MCP SDK, `httpx`, `keyring`, `click`, `rich` | +| **Language** | Python 3.12+, `uv` | +| **Key deps** | MCP SDK, `httpx`, `keyring`, `click`, `rich` | +| **Compose paths** | `/volume1/docker//` (default Synology layout) | --- -## Deploy-Workflow (nach jeder Code-Änderung) +## Deploy workflow (after every code change) ``` -1. Claude Code committet und pusht -2. uv tool install --reinstall git+https://gitea.gecheckt.de/marcus/mcp-synology-container.git -3. Claude Desktop neu starten (Tray-Icon → Quit → neu starten) +1. Claude Code commits and pushes +2. uv tool install --reinstall git+ +3. Restart Claude Desktop (tray icon → Quit → relaunch) ``` --- -## Aktueller Stand +## Implemented tools (23) -### Implementierte Tools (22) - -| Kategorie | Tools | +| Category | Tools | |---|---| -| Projekte | `list_projects`, `get_project_status`, `start_project`, `stop_project`, `redeploy_project` | -| Container | `list_containers`, `get_container_status`, `get_container_logs`, `exec_in_container`, `container_stats` | -| Compose | `read_compose`, `update_compose`, `update_image_tag`, `update_env_var` | -| Images | `check_image_updates`, `list_images`, `delete_image` | -| Netzwerke | `list_networks`, `create_network`, `delete_network` | -| System | `system_df`, `system_prune` | - -### Bekannte Bugs - -~~- Container-Name mit Hash-Präfix (`f93cb8b504f7_jenkins`) → behoben: `_strip_hash_prefix` + `_resolve_container_name` in allen Container-Tools~~ -~~- `redeploy_project` DSM 2101/1202 bei falschem Status → behoben: status-aware Logik (RUNNING/STOPPED/BUILD_FAILED)~~ +| Projects | `list_projects`, `get_project_status`, `start_project`, `stop_project`, `redeploy_project` | +| Containers | `list_containers`, `get_container_status`, `get_container_logs`, `exec_in_container`, `container_stats`, `delete_container` | +| Compose | `read_compose`, `update_compose`, `update_image_tag`, `update_env_var` | +| Images | `check_image_updates`, `list_images`, `delete_image` | +| Networks | `list_networks`, `create_network`, `delete_network` | +| System | `system_df`, `system_prune` | --- -## Roadmap (geplante Erweiterungen) +## DSM API quirks -~~Alle geplanten Erweiterungen implementiert.~~ - -Volumes entfällt — SYNO.Docker.Volume existiert nicht (kein DSM-Endpunkt). +- **Hash-prefixed container names** — DSM sometimes returns names like + `a1b2c3d4e5f6_myservice` when the compose service name differs from + `container_name`. All container tools strip this prefix transparently via + `_strip_hash_prefix` / `_resolve_container_name`. +- **Async project start** — `SYNO.Docker.Project/start` returns immediately + while containers are still initialising. `redeploy_project` polls + `SYNO.Docker.Project/list` every 2 s for up to 30 s after issuing start. +- **Image delete** — requires a form-encoded POST with a JSON `images` array + (confirmed via browser DevTools); uses `DsmClient.post_request()`. +- **`SYNO.Docker.Image/pull`** — API method exists but behaviour varies by + DSM version; not exposed as a standalone tool. +- **`SYNO.Docker.Volume`** — endpoint does not exist; volume management is + not available via the DSM WebAPI. +- **`SYNO.Docker.Registry/get`** — does not behave as documented; registry + listing omitted. --- -## NAS – Laufende Container (Stand April 2026) +## Implementation rules -| Container | Image | Status | -|---|---|---| -| `jenkins` | `jenkins/jenkins:2.558-jdk21` | running | -| `openwebui` | `ghcr.io/open-webui/open-webui:v0.8.10` | running | -| `frostiq-gitea` | `gitea/gitea:1.25.4` | running | -| `frostiq-wildfly` | `frostiq/wildfly:39.0.0.Final-jdk21-pg` | running | -| `bookstack` | `linuxserver/bookstack:latest` | running | -| `bookstack-mariadb` | `mariadb:11.8` | running | -| `homeassistant` | `homeassistant/home-assistant:stable` | running | -| `pgadmin` | `dpage/pgadmin4:latest` | running | -| `postgres17` | `postgres:17.7` | running | -| `synology_docviewer_1` | `synology/docviewer:1.3.0.0126` | stopped | -| `synology_docviewer_2` | `synology/docviewer:1.3.0.0126` | stopped | +- Confirmation required before destructive operations: `stop_project`, + `redeploy_project`, `exec_in_container`, `update_image_tag`, + `update_env_var`, `update_compose`, `delete_container` +- After compose changes: suggest `redeploy_project` +- DSM errors → human-readable message, no stack traces +- No secrets in stderr output +- Type hints and docstrings everywhere +- Formatter: `ruff format` · Linter: `ruff check` · Tests: `pytest` +- All text (docstrings, comments, README): English --- -## Claude Code – Implementierungsregeln +## DSM API reference -- Confirmation vor destruktiven Operationen: `stop_project`, `redeploy_project`, - `exec_in_container`, `update_image_tag`, `update_env_var`, `update_compose` -- Nach Compose-Änderungen: `redeploy_project` vorschlagen -- Fehlerbehandlung: DSM-Fehler als verständliche Meldung zurückgeben, keine Stacktraces -- Keine Secrets in stderr-Ausgaben -- Type Hints und Docstrings konsequent verwenden -- Formatter: `ruff format`, Linter: `ruff check`, Tests: `pytest` -- Alle Texte (Docstrings, Kommentare, README): Englisch - ---- - -## Hintergrund - -Marcus ist Senior Software Engineer (Java, Jakarta EE). -FrostIQ ist eines seiner größeren Projekte (Jenkins, WildFly, Gitea). -Präferenz: State-of-the-Art, Best Practices, saubere Architektur. -Automatisierung spart Zeit für die Familie. 🌱 - ---- - -## Aktueller Auftrag (Stand April 2026) - -### Rollenteilung -- **Claude Code** – Implementierung + Unit Tests (pytest, gemockter DSM-Client) -- **Marcus** – Deploy-Workflow (commit → push → install → Desktop-Neustart) -- **Claude Chat** – Produkttest live gegen die NAS nach jedem Deploy - -### Implementierungsreihenfolge - -Implementiere **eine Gruppe nach der anderen**. Commit + Push nach jeder Gruppe, dann Marcus Bescheid geben. - ---- - -#### Gruppe 1 – Images `modules/images.py` ✦ Prio: hoch - -**`list_images`** -- DSM API: `SYNO.Docker.Image`, method `list` -- Ausgabe: Name:Tag, Größe (human-readable), Erstellungsdatum, ob aktuell von einem Container verwendet -- Sortierung: Größe absteigend -- Confirmation: nein - -**`delete_image`** -- Signatur: `delete_image(image_id: str, confirmed: bool = False) -> str` -- `image_id` akzeptiert `name:tag` und Image-Hash -- DSM API: `SYNO.Docker.Image`, method `delete` -- Ohne `confirmed=True`: nur Preview, nicht löschen -- Fehler wenn Image von laufendem Container verwendet → klare Meldung, kein Stacktrace -- Erfolg: `Deleted nouchka/sqlite3:latest – 76 MiB freed` -- Confirmation: **ja** - ---- - -#### Gruppe 2 – Container `modules/containers.py` ✦ Prio: mittel ✅ erledigt - -**`container_stats`** ✅ -- Signatur: `container_stats(container_name: str) -> str` -- Ausgabe: CPU %, RAM verwendet/limit, Netzwerk I/O, Block I/O -- Confirmation: nein - -**`rename_container`** – entfällt (DSM bietet kein Container-Umbenennen) - ---- - -#### Gruppe 3 – System `modules/system.py` (neu) ✦ Prio: hoch - -**`system_df`** -- DSM API: `SYNO.Docker.System` oder Docker Engine `/system/df` -- Ausgabe: Images (Anzahl, Gesamtgröße, reclaimable), Container, Volumes – tabellarisch -- Confirmation: nein - -**`system_prune`** -- Signatur: `system_prune(confirmed: bool = False) -> str` -- Löscht: dangling Images, gestoppte Container, ungenutzte Netzwerke -- Ohne `confirmed=True`: zeigt was gelöscht würde -- Ausgabe: freigegebener Speicher -- Confirmation: **ja** - ---- - -#### Gruppe 4 – Netzwerke `modules/networks.py` (neu) ✦ Prio: mittel - -**`list_networks`** -- DSM API: `SYNO.Docker.Network`, method `list` -- Ausgabe: Name, Driver, Subnet, angebundene Container -- Confirmation: nein - -**`create_network`** -- Signatur: `create_network(name: str, driver: str = "bridge", confirmed: bool = False) -> str` -- Confirmation: **ja** - -**`delete_network`** -- Signatur: `delete_network(name: str, confirmed: bool = False) -> str` -- Fehler wenn Container angebunden → klare Meldung -- Confirmation: **ja** - ---- - -#### Gruppe 6 – Images Ergänzung – entfällt - -`pull_image` entfällt — SYNO.Docker.Image/pull liefert keinen nutzbaren Endpunkt -(DSM-Methode unbekannt / nicht über WebAPI erreichbar). - ---- - -#### Gruppe 7 – Registries – entfällt - -`list_registries` entfällt — SYNO.Docker.Registry/get funktioniert nicht wie erwartet -(DSM-Methode unbekannt / Produkttest fehlgeschlagen). - ---- - -### Referenz für DSM API-Calls -- `cmeans/mcp-synology` (GitHub) – Auth, Keyring, CLI-Struktur -- `N4S4/synology-api` `docker_api.py` (GitHub) – SYNO.Docker.* API-Calls - -### Start -Beginne mit **Gruppe 1** (`list_images` + `delete_image`). \ No newline at end of file +- `cmeans/mcp-synology` (GitHub) — auth, keyring, CLI structure +- `N4S4/synology-api` `docker_api.py` (GitHub) — `SYNO.Docker.*` calls diff --git a/pyproject.toml b/pyproject.toml index 9857ca4..1883bb9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "mcp-synology-container" -version = "0.2.2" +version = "0.2.3" description = "MCP server for Synology Container Manager" requires-python = ">=3.12" dependencies = [