Initial implementation
This commit is contained in:
@@ -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.*) |
|
||||
Reference in New Issue
Block a user