Anpassungen
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
reference/
|
||||||
@@ -1,92 +1,246 @@
|
|||||||
# CLAUDE.md – Arbeitsanweisung für mcp-synology-container
|
# mcp-synology-container
|
||||||
|
|
||||||
## Deine Aufgabe
|
## Kontext
|
||||||
|
|
||||||
Implementiere das Projekt `mcp-synology-container` vollständig gemäß `SPEC.md`.
|
Dieses Projekt entwickelt und betreibt `mcp-synology-container` – einen MCP-Server
|
||||||
|
für die vollständige Verwaltung von Docker-Projekten auf einer Synology DiskStation
|
||||||
Lies `SPEC.md` jetzt vollständig, bevor du anfängst.
|
via Container Manager. Der MCP-Server ist in Claude Desktop aktiv verbunden.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Referenzmaterial
|
## Infrastruktur
|
||||||
|
|
||||||
Im Ordner `reference/` findest du zwei Referenzprojekte. Nutze sie aktiv:
|
| | |
|
||||||
|
|---|---|
|
||||||
### `reference/cmeans/`
|
| **NAS** | `https://dsm.gecheckt.de` (Split-DNS, intern direkt aufgelöst) |
|
||||||
Geklontes Repo von `cmeans/mcp-synology` (GitHub).
|
| **Compose-Pfade** | `/volume1/docker/<projektname>/` |
|
||||||
Übernimm daraus die Implementierungsmuster für:
|
| **Gitea** | `https://gitea.gecheckt.de/marcus/mcp-synology-container` |
|
||||||
- Auth-Flow und 2FA-Device-Token-Flow (`auth.py`)
|
| **Lokaler Code** | `D:\Dev\Projects\mcp-synology-container` |
|
||||||
- OS-Keyring-Integration (`keyring` library)
|
| **Sprache** | Python 3.12+, `uv`, MCP SDK, `httpx`, `keyring`, `click`, `rich` |
|
||||||
- CLI-Struktur mit `click` (`cli.py`)
|
|
||||||
- Config laden/speichern mit YAML (`config.py`)
|
|
||||||
- Credential-Auflösungsreihenfolge (env vars → config → keyring)
|
|
||||||
- `setup`-Wizard mit `rich` für formatierte Ausgabe
|
|
||||||
- Generierung des Claude-Desktop-Config-Snippets
|
|
||||||
|
|
||||||
Passe alle übernommenen Muster an unseren Use-Case an.
|
|
||||||
Kopiere keinen Code blind – verstehe ihn und adaptiere ihn.
|
|
||||||
|
|
||||||
### `reference/n4s4/docker_api.py`
|
|
||||||
Einzelne Datei aus `N4S4/synology-api` (GitHub).
|
|
||||||
Nutze sie als Referenz für die konkreten DSM API-Calls:
|
|
||||||
- Wie `SYNO.Docker.Project` aufgerufen wird (list, start, stop)
|
|
||||||
- Wie `SYNO.Docker.Container` aufgerufen wird (list, logs, exec)
|
|
||||||
- Wie `SYNO.Docker.Image` aufgerufen wird (list)
|
|
||||||
- Welche Parameter und Response-Strukturen die APIs erwarten
|
|
||||||
|
|
||||||
Implementiere **keinen** eigenen Wrapper um `synology-api` –
|
|
||||||
baue einen eigenen schlanken HTTP-Client in `dsm_client.py` mit `httpx`.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Reihenfolge der Implementierung
|
## Deploy-Workflow (nach jeder Code-Änderung)
|
||||||
|
|
||||||
Arbeite in dieser Reihenfolge. Schließe jeden Schritt vollständig ab bevor du weitermachst:
|
```
|
||||||
|
1. Claude Code committet und pusht
|
||||||
1. **Projektstruktur anlegen** – alle Ordner und leere `__init__.py`-Dateien, `pyproject.toml`
|
2. uv tool install --reinstall git+https://gitea.gecheckt.de/marcus/mcp-synology-container.git
|
||||||
2. **`config.py`** – Config laden, speichern, validieren
|
3. Claude Desktop neu starten (Tray-Icon → Quit → neu starten)
|
||||||
3. **`auth.py`** – Keyring-Integration, Login gegen DSM API, 2FA-Device-Token-Flow
|
```
|
||||||
4. **`dsm_client.py`** – HTTP-Client mit Session-Management, Auto-Re-Login
|
|
||||||
5. **`cli.py`** – `setup`, `check`, `serve` Befehle
|
|
||||||
6. **`modules/projects.py`** – SYNO.Docker.Project Tools
|
|
||||||
7. **`modules/containers.py`** – SYNO.Docker.Container Tools
|
|
||||||
8. **`modules/compose.py`** – Compose-Datei lesen/schreiben via FileStation API
|
|
||||||
9. **`modules/images.py`** – SYNO.Docker.Image Tools
|
|
||||||
10. **Tests** – für jeden Schritt
|
|
||||||
11. **`README.md`** – Installationsanleitung und Tool-Übersicht
|
|
||||||
12. **`docs/setup.md`** und **`docs/tools.md`**
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Wichtige Implementierungsregeln
|
## Aktueller Stand
|
||||||
|
|
||||||
- **Confirmation vor destruktiven Operationen:** `stop_project`, `redeploy_project`,
|
### Implementierte Tools (14)
|
||||||
`exec_in_container`, `update_image_tag`, `update_env_var`, `update_compose` müssen
|
|
||||||
eine Bestätigung vom Nutzer einholen bevor sie ausgeführt werden. Nutze dafür den
|
|
||||||
MCP-eigenen `confirm`-Mechanismus.
|
|
||||||
|
|
||||||
- **Nach Compose-Änderungen:** Immer automatisch `redeploy_project` vorschlagen.
|
| 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` |
|
||||||
|
|
||||||
- **Fehlerbehandlung:** Alle DSM API-Fehler sauber abfangen und als verständliche
|
### Bekannte Bugs
|
||||||
Fehlermeldung zurückgeben. Keine Python-Stacktraces zum Nutzer.
|
|
||||||
|
|
||||||
- **Keine Secrets in Logs:** Passwörter, Tokens und Session-IDs niemals in
|
- Container-Name wird manchmal mit Hash-Präfix zurückgegeben (z.B. `f93cb8b504f7_jenkins`)
|
||||||
stderr-Ausgaben schreiben.
|
→ Tritt auf wenn Service-Name in compose.yaml von `container_name` abweicht
|
||||||
|
- `redeploy_project` schlägt mit DSM 2101/1202 fehl bei falschem Projektstatus
|
||||||
- **HTTPS:** `verify_ssl: true` ist der Standard. Nur auf expliziten Wunsch deaktivierbar.
|
→ Workaround: `stop_project` + `start_project` separat oder `docker compose` per SSH
|
||||||
|
|
||||||
- **Compose-Pfade:** Beide Varianten erkennen – `docker-compose.yml` und `compose.yml`.
|
|
||||||
|
|
||||||
- **Type Hints:** Konsequent in allen Funktionen verwenden.
|
|
||||||
|
|
||||||
- **Docstrings:** Für alle öffentlichen Funktionen und Klassen.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Projekt-Konventionen
|
## Roadmap (geplante Erweiterungen)
|
||||||
|
|
||||||
- Sprache: Python 3.12+
|
### Images
|
||||||
- Formatter: `ruff format`
|
- `list_images` – alle lokalen Images mit Größe, Tag, Erstellungsdatum
|
||||||
- Linter: `ruff check`
|
- `delete_image` – nicht mehr benötigte Images löschen
|
||||||
- Tests: `pytest`
|
- `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
|
- 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`).
|
||||||
Reference in New Issue
Block a user