marcus 036429e9bf feat: v0.6.0 — read build_stream log instead of dropping it (#2)
DSM emits a readable plaintext build log over the build_stream HTTP
body (one short status line per step) and closes the connection when
the build is done. The 0.2.5 implementation sent the request and
dropped the body unread, leaving users with nothing more than a
BUILD_FAILED polling status and no actionable diagnostic.

DsmClient.trigger_build_stream now consumes the body line-by-line and
returns the collected log as a string. Wall-clock budget of 210 s
(under the Claude Desktop ~4 min ceiling); on timeout the partial log
is returned with a "[build_stream: timeout — stream still open
server-side]" marker so callers know the build continues server-side.
Per-chunk ReadTimeout is treated the same way. JSON error envelope,
transport-error mapping (M-4), and SID-scrubbed HTTP-error formatting
are unchanged.

redeploy_project and create_project now parse the returned log via
_parse_build_stream_log (any line containing "Error response from
daemon:" or ending in " Error" counts as a failure). On a failed log
the tools abort immediately, surface the daemon line(s) in the result
(e.g. "Error response from daemon: manifest for nginx:9.9.9 not
found: manifest unknown"), and skip the polling step. The BUILD_FAILED
polling guard (M-5) stays as a second safety net for late failures
where the stream was clean but the container exited after start.

No new MCP tool: the build log is a live stream and cannot be
re-fetched after the build ends, so it is surfaced during
redeploy_project / create_project rather than exposed as a standalone
get_project_build_log call.

Minor version bump because redeploy_project and create_project return
materially different strings on a failed build and exit earlier in
the failure path. Signatures unchanged.

Tests: streamed-log collection, daemon-error log, header ReadTimeout
marker, per-chunk ReadTimeout partial log, wall-clock budget
truncation, _parse_build_stream_log unit tests, redeploy/create end-
to-end behavior with a failing log.

Closes #2

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 13:58:55 +02:00
2026-04-13 14:22:37 +02:00
2026-04-13 17:55:08 +02:00
2026-04-13 14:22:37 +02:00

mcp-synology-container

An MCP (Model Context Protocol) server for managing Docker on a Synology NAS via Container Manager. Enables Claude Desktop to inspect, start, stop, redeploy, and modify Docker Compose projects directly — including live resource stats, log tailing, network management, and disk usage.

Features

  • Project management: list, start, stop, redeploy Container Manager projects (status-aware)
  • Container inspection: status with IPs/ports/mounts, live resource stats, log tailing, exec
  • Compose file editing: read, replace, update image tags and env vars
  • Image management: list images with sizes, check for updates, delete unused images
  • Network management: list, create, and delete Docker networks
  • System overview: disk usage (images, containers), prune dangling resources
  • Hash-prefix handling: transparent resolution of DSM hash-prefixed container names
  • 2FA support: device token flow for Synology accounts with OTP enabled
  • OS keyring integration: credentials stored securely, never in config files
  • Confirmation required for all destructive operations

Requirements

  • Python 3.12+
  • Synology NAS with DSM 7.x and Container Manager installed
  • pip or uv for installation

Installation

pip install mcp-synology-container

Or with uv:

uv tool install mcp-synology-container

Setup

Run the interactive setup wizard:

mcp-synology-container setup

The wizard will:

  1. Ask for your NAS hostname/IP, port, and HTTPS settings
  2. Ask for your DSM username and password
  3. Handle 2FA if enabled (stores device token in OS keyring)
  4. Save the config to ~/.config/mcp-synology-container/config.yaml
  5. Print the Claude Desktop configuration snippet

Claude Desktop configuration

Add the snippet to claude_desktop_config.json:

{
  "mcpServers": {
    "synology-container": {
      "command": "mcp-synology-container",
      "args": ["serve"]
    }
  }
}

CLI Commands

mcp-synology-container setup

Interactive setup: configure connection and store credentials.

mcp-synology-container setup
mcp-synology-container setup --verbose

mcp-synology-container check

Test the connection and verify all required APIs are available.

mcp-synology-container check
mcp-synology-container check --config /path/to/config.yaml

Exit code 0 = OK, 1 = error.

mcp-synology-container serve

Start the MCP server (used by Claude Desktop).

mcp-synology-container serve
mcp-synology-container serve --config /path/to/config.yaml

Configuration

Config file: ~/.config/mcp-synology-container/config.yaml

schema_version: 1
alias: HomeNAS                        # Optional display name
connection:
  host: dsm.example.com
  port: 443
  https: true
  verify_ssl: true
compose_base_path: /volume1/docker   # Base path for compose projects on NAS

Environment variable overrides

Variable Description
SYNOLOGY_HOST NAS hostname or IP
SYNOLOGY_PORT DSM port
SYNOLOGY_HTTPS Use HTTPS (true/false)
SYNOLOGY_VERIFY_SSL Verify SSL cert (true/false)
SYNOLOGY_USERNAME DSM username
SYNOLOGY_PASSWORD DSM password

Credentials from environment variables take priority over the keyring.

MCP Tools

23 tools across 6 categories.

Projects

Tool Description Confirmation
list_projects List all Container Manager projects with status and container count
get_project_status Detailed status, path, services, and container IDs
start_project Start a stopped project
stop_project Stop a running project (halts all containers) required
redeploy_project Redeploy a project via DSM build_stream (equivalent to the DSM "Erstellen" button); pulls latest images and restarts; auto-detects current state (RUNNING/STOPPED/BUILD_FAILED) required

Containers

Tool Description Confirmation
list_containers List containers, optionally filtered by project
get_container_status Status, running state, image, IP addresses, port bindings, mounts
get_container_logs Fetch log output with optional keyword filter
exec_in_container Execute a shell command inside a running container required
container_stats Live CPU %, RAM used/limit, network I/O, block I/O
delete_container Delete a stopped container by name; refuses if container is still running required

Compose Files

Tool Description Confirmation
read_compose Read the compose file of a project
update_image_tag Update the image tag for a specific service required
update_env_var Add or update an environment variable for a service required
update_compose Replace the entire compose file required

Images

Tool Description Confirmation
list_images List local images sorted by size (largest first); marks images in use and available updates
delete_image Delete a local image by name:tag or hash; refuses if image is in use required
check_image_updates Check which images have updates available; optionally filter by project

System

Tool Description Confirmation
system_df Docker disk usage: image count/size, running/stopped containers, reclaimable space
system_prune Remove dangling images, stopped containers, and unused networks required

Networks

Tool Description Confirmation
list_networks List all Docker networks with driver, subnet, gateway, and attached containers
create_network Create a new Docker network (bridge or other driver) required
delete_network Delete a network; refuses if any container is attached required

Development

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
python -m pytest tests/ -v

# Lint
ruff check src/ tests/

# Format
ruff format src/ tests/

Security

  • Credentials are stored in the OS keyring only (never in config files)
  • All destructive operations require explicit confirmation (confirmed=True)
  • HTTPS with certificate verification is enabled by default
  • Session IDs and passwords are never written to stderr logs

License

MIT

S
Description
No description provided
Readme 1.6 MiB
Languages
Python 100%