Files
mcp-synology-container/CLAUDE.md
T
marcus 801dbe15dc feat: v0.3.1 — create_project tool
Adds `create_project` for registering a new Container Manager project
from a compose YAML string. Three-step flow that mirrors the DSM
"Create Project" wizard:

  1. SYNO.FileStation.CreateFolder with force_parent=true (idempotent
     — does not fail if the folder already exists, and creates missing
     intermediate directories). Without this step, Docker.Project/create
     fails with DSM error 2100.
  2. SYNO.Docker.Project/create (form-encoded POST; JSON-encoded string
     parameters per DSM convention) returns the new project UUID.
  3. trigger_build_stream + _wait_for_project_running, reusing the
     existing image-pull / start / poll machinery (including the
     BUILD_FAILED early-exit from welle 2).

Safety:
- Project-name validation (Welle-1 regex) runs before any I/O.
- Compose content is YAML-parsed and must contain a top-level
  `services` key before any side effects.
- A pre-flight list_projects check rejects duplicate names with a
  clear message rather than leaving an orphaned folder on the NAS.
- share_path defaults to compose_base_path + project_name (e.g.
  /volume1/docker + myapp → /docker/myapp); a caller-supplied value
  overrides it.
- Requires confirmed=True; the preview shows the resolved share path
  and the service count parsed from the compose content.
- DSM error 2100 surfaces as "target folder issue" with the attempted
  path. A build_stream failure after a successful Project/create tells
  the user the project is registered-but-not-started and points at
  redeploy_project for recovery.

Tests cover preview-only, already-exists, happy path (with parameter
JSON-encoding assertions), explicit share_path, malformed YAML,
missing services key, invalid project name, error 2100, and
build_stream failure after registration.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 11:13:18 +02:00

4.0 KiB

mcp-synology-container

Project

mcp-synology-container is an MCP server for managing Docker projects on a Synology DiskStation via Container Manager. It exposes tools for projects, containers, images, compose files, networks, and system housekeeping.


Tech stack

Language Python 3.12+, uv
Key deps MCP SDK, httpx, keyring, click, rich
Compose paths /volume1/docker/<project>/ (default Synology layout)

Deploy workflow (after every code change)

1. Claude Code commits and pushes
2. uv tool install --reinstall git+<repo-url>
3. Restart Claude Desktop (tray icon → Quit → relaunch)

Push retry: the Gitea remote (gitea.gecheckt.de) occasionally returns Unauthorized on the first push attempt. If git push fails with an auth error, wait 1 s and retry once before reporting back. Only a second consecutive failure is treated as a real auth problem.


Implemented tools (24)

Category Tools
Projects list_projects, get_project_status, start_project, stop_project, redeploy_project, create_project
Containers list_containers, get_container_status, get_container_logs, exec_in_container, container_stats, delete_container
Compose read_compose, update_compose, update_image_tag, update_env_var
Images check_image_updates, list_images, delete_image
Networks list_networks, create_network, delete_network
System system_df, system_prune

DSM API quirks

  • Hash-prefixed container names — DSM sometimes returns names like a1b2c3d4e5f6_myservice when the compose service name differs from container_name. All container tools strip this prefix transparently via _strip_hash_prefix / _resolve_container_name.
  • Async project startSYNO.Docker.Project/start returns immediately while containers are still initialising. redeploy_project polls SYNO.Docker.Project/list every 2 s for up to 30 s after issuing start.
  • Image delete — requires a form-encoded POST with a JSON images array (confirmed via browser DevTools); uses DsmClient.post_request().
  • SYNO.Docker.Image/pull — API method exists but behaviour varies by DSM version; not exposed as a standalone tool.
  • SYNO.Docker.Volume — endpoint does not exist; volume management is not available via the DSM WebAPI.
  • SYNO.Docker.Registry/get — does not behave as documented; registry listing omitted.

Implementation rules

  • Confirmation required before destructive operations: stop_project, redeploy_project, create_project, exec_in_container, update_image_tag, update_env_var, update_compose, delete_container
  • After compose changes: suggest redeploy_project
  • DSM errors → human-readable message, no stack traces
  • No secrets in stderr output
  • Type hints and docstrings everywhere
  • Formatter: ruff format · Linter: ruff check · Tests: pytest
  • All text (docstrings, comments, README): English
  • CHANGELOG.md: every user-visible change (bug fix, new/changed tool, behavior change, security fix, dependency bump) gets a CHANGELOG.md entry in the same commit — under a ## [Unreleased] heading between releases, which becomes ## [X.Y.Z] - YYYY-MM-DD on version bump. Pure internal cleanup (renames without external callers, comment-only edits, ruff autofix) needs no entry. Don't ship a release with a stale changelog (this was the C-2 gap that caused 0.2.7 and 0.2.8 to ship undocumented).
  • Version consistency: the package version lives in pyproject.toml and must stay in sync with uv.lock and the [X.Y.Z] heading in CHANGELOG.md. src/mcp_synology_container/__init__.py derives __version__ from importlib.metadata and is never hand-edited. Every version bump touches all three files in the same commit.

DSM API reference

  • cmeans/mcp-synology (GitHub) — auth, keyring, CLI structure
  • N4S4/synology-api docker_api.py (GitHub) — SYNO.Docker.* calls