4b8b1a0a6e
- Document that git push to gitea.gecheckt.de occasionally returns Unauthorized on the first attempt and must be retried once after a 1 s wait before reporting an auth failure. - Codify the version-consistency invariant: pyproject.toml, uv.lock, and the latest CHANGELOG heading must move together; src/mcp_synology_container/__init__.py reads __version__ from importlib.metadata and is never hand-edited. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
3.5 KiB
3.5 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 (23)
| Category | Tools |
|---|---|
| Projects | list_projects, get_project_status, start_project, stop_project, redeploy_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_myservicewhen the compose service name differs fromcontainer_name. All container tools strip this prefix transparently via_strip_hash_prefix/_resolve_container_name. - Async project start —
SYNO.Docker.Project/startreturns immediately while containers are still initialising.redeploy_projectpollsSYNO.Docker.Project/listevery 2 s for up to 30 s after issuing start. - Image delete — requires a form-encoded POST with a JSON
imagesarray (confirmed via browser DevTools); usesDsmClient.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,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
- Version consistency: the package version lives in
pyproject.tomland must stay in sync withuv.lockand the[X.Y.Z]heading inCHANGELOG.md.src/mcp_synology_container/__init__.pyderives__version__fromimportlib.metadataand 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 structureN4S4/synology-apidocker_api.py(GitHub) —SYNO.Docker.*calls