Initial implementation

This commit is contained in:
2026-04-13 14:22:37 +02:00
commit a0c1b6ed93
26 changed files with 4125 additions and 0 deletions
+242
View File
@@ -0,0 +1,242 @@
# 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.*) |