# 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.*) |