Files
mcp-synology-container/SPEC.md
T
2026-04-13 14:22:37 +02:00

243 lines
7.1 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.
# Projektspezifikation: mcp-synology-container
## Ziel
Ein MCP-Server (Model Context Protocol) für die Verwaltung von Docker-Projekten auf einer
Synology DiskStation via Container Manager. Der Server ermöglicht es Claude Desktop,
Container-Projekte direkt zu verwalten inklusive Lesen und Bearbeiten von
`docker-compose.yml`-Dateien sowie Lifecycle-Management der Projekte und Container.
---
## Technologie-Stack
| Komponente | Entscheidung |
|---|---|
| Sprache | Python 3.12+ |
| Package Manager | `uv` |
| MCP Framework | `mcp` (Anthropic MCP SDK) |
| HTTP-Client | `httpx` |
| Credential Storage | OS-Keyring (`keyring` library) |
| Config Format | YAML |
| Logging | stderr only (kein File-Logging) |
---
## Projektstruktur
```
mcp-synology-container/
├── src/
│ └── mcp_synology_container/
│ ├── __init__.py
│ ├── cli.py # CLI-Einstiegspunkt: setup, check, serve
│ ├── config.py # Config laden/speichern (YAML)
│ ├── auth.py # Keyring-Integration, 2FA-Device-Token-Flow
│ ├── dsm_client.py # HTTP-Client gegen Synology DSM API
│ └── modules/
│ ├── __init__.py
│ ├── projects.py # SYNO.Docker.Project
│ ├── containers.py # SYNO.Docker.Container
│ ├── compose.py # Compose-Datei lesen/schreiben via FileStation API
│ └── images.py # SYNO.Docker.Image
├── tests/
│ ├── __init__.py
│ ├── test_config.py
│ ├── test_auth.py
│ └── test_modules/
│ ├── test_projects.py
│ ├── test_containers.py
│ ├── test_compose.py
│ └── test_images.py
├── docs/
│ ├── setup.md
│ └── tools.md
├── pyproject.toml
├── README.md
└── CHANGELOG.md
```
---
## pyproject.toml
```toml
[project]
name = "mcp-synology-container"
version = "0.1.0"
description = "MCP server for Synology Container Manager"
requires-python = ">=3.12"
dependencies = [
"mcp>=1.0.0",
"httpx>=0.27.0",
"pyyaml>=6.0",
"keyring>=25.0.0",
"click>=8.1.0",
"rich>=13.0.0",
]
[project.scripts]
mcp-synology-container = "mcp_synology_container.cli:main"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
```
---
## Konfigurationsdatei
Pfad: `~/.config/mcp-synology-container/config.yaml`
```yaml
schema_version: 1
alias: HomeNAS # optionaler Anzeigename in Claude Desktop
connection:
host: dsm.gecheckt.de
port: 443
https: true
verify_ssl: true
compose_base_path: /volume1/docker # Basis-Pfad für alle Compose-Projekte auf der NAS
```
Credentials (Host, Username, Password, optional Device-Token für 2FA) werden
**nicht** in der Config-Datei gespeichert, sondern ausschließlich im OS-Keyring.
**Credential-Auflösungsreihenfolge:**
1. Umgebungsvariablen (`SYNOLOGY_HOST`, `SYNOLOGY_USERNAME`, `SYNOLOGY_PASSWORD`)
2. Config-Datei (nur nicht-sensitive Werte)
3. OS-Keyring (Credentials)
---
## CLI-Befehle
### `mcp-synology-container setup`
Interaktiver Setup-Wizard:
1. Fragt Host, Port, HTTPS, Benutzername, Passwort ab
2. Prüft ob 2FA aktiv ist wenn ja: OTP abfragen, Device-Token speichern
3. Speichert Credentials im OS-Keyring
4. Schreibt `config.yaml`
5. Gibt fertiges Claude-Desktop-Config-Snippet aus:
```json
{
"mcpServers": {
"synology-container": {
"command": "mcp-synology-container",
"args": ["serve"]
}
}
}
```
### `mcp-synology-container check`
- Lädt Config und Credentials
- Stellt Testverbindung zur DSM API her
- Gibt Verbindungsstatus, DSM-Version und verfügbare APIs aus
- Exit-Code 0 = OK, 1 = Fehler
### `mcp-synology-container serve`
- Startet den MCP-Server im stdio-Modus
- Registriert alle Tools
- Läuft bis SIGTERM/SIGINT
---
## MCP-Tools
### Projekte (`projects.py`)
| Tool | Beschreibung | Confirmation required |
|---|---|---|
| `list_projects` | Alle Container-Manager-Projekte mit Status auflisten | nein |
| `get_project_status` | Detaillierten Status eines Projekts abrufen | nein |
| `start_project` | Projekt starten | nein |
| `stop_project` | Projekt stoppen | **ja** |
| `redeploy_project` | Projekt neu deployen (pull + down + up) | **ja** |
**Redeploy-Ablauf:**
1. Compose-Datei lesen
2. `docker compose pull` (neues Image ziehen)
3. `docker compose down`
4. `docker compose up -d`
5. Deploy-Output streamen und zurückgeben
### Container (`containers.py`)
| Tool | Beschreibung | Confirmation required |
|---|---|---|
| `list_containers` | Alle Container eines Projekts auflisten | nein |
| `get_container_status` | Status, Uptime, Ressourcennutzung eines Containers | nein |
| `get_container_logs` | Log-Ausgabe abrufen (mit optionalem `tail`-Parameter) | nein |
| `exec_in_container` | Befehl in laufendem Container ausführen | **ja** |
### Compose-Datei (`compose.py`)
Compose-Dateien liegen unter `{compose_base_path}/{projektname}/docker-compose.yml`
(oder `compose.yml` beide Varianten werden erkannt).
| Tool | Beschreibung | Confirmation required |
|---|---|---|
| `read_compose` | Compose-Datei eines Projekts lesen | nein |
| `update_image_tag` | Image-Tag eines Services aktualisieren | **ja** |
| `update_env_var` | Umgebungsvariable eines Services hinzufügen oder ändern | **ja** |
| `update_compose` | Beliebige Änderung an der Compose-Datei (vollständiger neuer Inhalt) | **ja** |
**Wichtig:** Nach Änderungen an der Compose-Datei schlägt der Server automatisch vor,
das Projekt neu zu deployen (`redeploy_project`).
### Images (`images.py`)
| Tool | Beschreibung | Confirmation required |
|---|---|---|
| `check_image_updates` | Verfügbare Updates für alle Images eines Projekts prüfen | nein |
---
## Authentifizierung & Session-Management
- Login via `SYNO.API.Auth` (DSM Web API)
- Session-Token wird in-memory gehalten (kein persistentes Speichern)
- Automatischer Re-Login bei abgelaufener Session (401-Response)
- 2FA: Device-Token-Flow
- Device-Token wird im OS-Keyring gespeichert
- Kein OTP-Prompt im laufenden Betrieb
- Re-Bootstrap via `setup` wenn Token revoked
---
## DSM API-Endpunkte
| Funktion | API |
|---|---|
| Auth | `SYNO.API.Auth` |
| Projekte | `SYNO.Docker.Project` (list, start, stop, start_stream) |
| Container | `SYNO.Docker.Container` (list, start, stop, logs) |
| Container exec | `SYNO.Docker.Container` (exec) |
| Images | `SYNO.Docker.Image` (list) |
| Compose-Dateien lesen | `SYNO.FileStation.Download` |
| Compose-Dateien schreiben | `SYNO.FileStation.Upload` |
---
## Sicherheitsregeln
- Credentials niemals in Config-Datei, nur im OS-Keyring
- Confirmation-Pflicht für alle destruktiven Operationen (stop, redeploy, exec, compose-update)
- HTTPS mit Zertifikatsvalidierung standardmäßig aktiv (`verify_ssl: true`)
- Keine Secrets in stderr-Ausgaben
---
## Referenzprojekte (zur Orientierung bei der Implementierung)
| Projekt | Zweck |
|---|---|
| `cmeans/mcp-synology` (GitHub) | Referenz für Auth-Flow, Keyring-Integration, CLI-Struktur, Config-System |
| `N4S4/synology-api` `docker_api.py` (GitHub) | Referenz für DSM API-Calls (SYNO.Docker.*) |