Files
mcp-synology-container/CLAUDE.md
T
2026-04-13 17:55:08 +02:00

246 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# mcp-synology-container
## Kontext
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.
---
## Infrastruktur
| | |
|---|---|
| **NAS** | `https://dsm.gecheckt.de` (Split-DNS, intern direkt aufgelöst) |
| **Compose-Pfade** | `/volume1/docker/<projektname>/` |
| **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` |
---
## Deploy-Workflow (nach jeder Code-Änderung)
```
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)
```
---
## Aktueller Stand
### Implementierte Tools (14)
| Kategorie | 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` |
| Compose | `read_compose`, `update_compose`, `update_image_tag`, `update_env_var` |
| Images | `check_image_updates` |
### Bekannte Bugs
- Container-Name wird manchmal mit Hash-Präfix zurückgegeben (z.B. `f93cb8b504f7_jenkins`)
→ Tritt auf wenn Service-Name in compose.yaml von `container_name` abweicht
- `redeploy_project` schlägt mit DSM 2101/1202 fehl bei falschem Projektstatus
→ Workaround: `stop_project` + `start_project` separat oder `docker compose` per SSH
---
## Roadmap (geplante Erweiterungen)
### Images
- `list_images` alle lokalen Images mit Größe, Tag, Erstellungsdatum
- `delete_image` nicht mehr benötigte Images löschen
- `pull_image` Image manuell aus Registry ziehen
### Container
- `container_stats` Live CPU/RAM-Verbrauch pro Container
- `rename_container` Container umbenennen
### Netzwerke
- `list_networks` alle Docker-Netzwerke auflisten
- `create_network` neues Netzwerk anlegen
- `delete_network` Netzwerk löschen
### Volumes
- `list_volumes` alle Docker-Volumes auflisten
- `delete_volume` verwaiste Volumes löschen
- `inspect_volume` Volume-Details anzeigen
### System
- `system_df` Docker Disk Usage (Images, Container, Volumes)
- `system_prune` Aufräumen (dangling Images, gestoppte Container)
### Registries
- `list_registries` konfigurierte Registries anzeigen
---
## NAS Laufende Container (Stand April 2026)
| 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 |
---
## Claude Code Implementierungsregeln
- 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
**`rename_container`**
- Signatur: `rename_container(container_name: str, new_name: str, confirmed: bool = False) -> str`
- DSM API: `SYNO.Docker.Container` rename (oder Docker Engine API direkt)
- Hinweis nach Erfolg: compose.yml ggf. manuell anpassen (`container_name`)
- Confirmation: **ja**
**`container_stats`**
- Signatur: `container_stats(container_name: str) -> str`
- Ausgabe: CPU %, RAM verwendet/limit, Netzwerk I/O, Block I/O
- Confirmation: nein
---
#### 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 5 Volumes `modules/volumes.py` (neu) ✦ Prio: niedrig
**`list_volumes`**
- DSM API: `SYNO.Docker.Volume`, method `list`
- Ausgabe: Name, Mountpoint, Größe, ob in Verwendung
- Confirmation: nein
**`inspect_volume`**
- Signatur: `inspect_volume(volume_name: str) -> str`
- Confirmation: nein
**`delete_volume`**
- Signatur: `delete_volume(volume_name: str, confirmed: bool = False) -> str`
- Fehler wenn Volume gemountet → klare Meldung
- Confirmation: **ja**
---
#### Gruppe 6 Images Ergänzung `modules/images.py` ✦ Prio: niedrig
**`pull_image`**
- Signatur: `pull_image(image: str) -> str` (z.B. `"postgres:17.8"`)
- DSM API: `SYNO.Docker.Image`, method `create` oder pull-Endpunkt
- Fortschritt streamen wenn möglich, sonst polling
- Confirmation: nein
---
#### Gruppe 7 Registries `modules/registries.py` (neu) ✦ Prio: niedrig
**`list_registries`**
- DSM API: `SYNO.Docker.Registry`, method `list`
- Ausgabe: Name, URL, ob authentifiziert
- Confirmation: nein
---
### 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`).