Initial implementation
This commit is contained in:
+196
@@ -0,0 +1,196 @@
|
||||
# Setup Guide
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Python 3.12 or higher
|
||||
- A Synology NAS running DSM 7.x with **Container Manager** installed
|
||||
- Network access to the NAS from the machine running Claude Desktop
|
||||
|
||||
## Installation
|
||||
|
||||
### With pip
|
||||
|
||||
```bash
|
||||
pip install mcp-synology-container
|
||||
```
|
||||
|
||||
### With uv
|
||||
|
||||
```bash
|
||||
uv tool install mcp-synology-container
|
||||
```
|
||||
|
||||
Verify installation:
|
||||
|
||||
```bash
|
||||
mcp-synology-container --help
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Running Setup
|
||||
|
||||
```bash
|
||||
mcp-synology-container setup
|
||||
```
|
||||
|
||||
The wizard will prompt you for:
|
||||
|
||||
| Prompt | Example | Notes |
|
||||
|---|---|---|
|
||||
| NAS hostname or IP | `192.168.1.100` or `nas.example.com` | |
|
||||
| Use HTTPS? | `y` | Recommended |
|
||||
| Port | `443` | Default for HTTPS |
|
||||
| Verify SSL certificate? | `y` | Disable only for self-signed certs |
|
||||
| Base path for compose projects | `/volume1/docker` | Where your compose projects live on the NAS |
|
||||
| Alias | `HomeNAS` | Optional friendly name |
|
||||
| DSM username | `admin` | DSM account with Container Manager access |
|
||||
| DSM password | | Hidden input |
|
||||
|
||||
### If 2FA is enabled
|
||||
|
||||
If your DSM account has OTP enabled, the setup wizard will ask for your OTP code and store a device token in the OS keyring. Subsequent logins will use the device token — no OTP prompts during normal operation.
|
||||
|
||||
If your device token is revoked, run `setup` again to re-bootstrap.
|
||||
|
||||
---
|
||||
|
||||
## Verifying the Connection
|
||||
|
||||
```bash
|
||||
mcp-synology-container check
|
||||
```
|
||||
|
||||
Example output:
|
||||
|
||||
```
|
||||
Host: nas.example.com:443
|
||||
HTTPS: True
|
||||
Verify SSL: True
|
||||
Compose: /volume1/docker
|
||||
|
||||
Credentials: found (user=admin, 2FA=yes)
|
||||
API info: fetched successfully
|
||||
Login: successful
|
||||
|
||||
Required APIs:
|
||||
SYNO.Docker.Container: v1-v1 ✓
|
||||
SYNO.Docker.Container.Log: v1-v1 ✓
|
||||
SYNO.Docker.Image: v1-v1 ✓
|
||||
SYNO.Docker.Project: v1-v1 ✓
|
||||
SYNO.FileStation.Download: v1-v2 ✓
|
||||
SYNO.FileStation.Upload: v1-v3 ✓
|
||||
|
||||
All checks passed.
|
||||
```
|
||||
|
||||
Exit code 0 means everything is working. Exit code 1 means a problem was detected.
|
||||
|
||||
---
|
||||
|
||||
## Configuring Claude Desktop
|
||||
|
||||
After running `setup`, the wizard prints a configuration snippet. Add it to your Claude Desktop config file:
|
||||
|
||||
**macOS/Linux**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
||||
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"synology-container": {
|
||||
"command": "mcp-synology-container",
|
||||
"args": ["serve"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Restart Claude Desktop after editing the config.
|
||||
|
||||
---
|
||||
|
||||
## Config File Location
|
||||
|
||||
The config is saved to:
|
||||
|
||||
```
|
||||
~/.config/mcp-synology-container/config.yaml
|
||||
```
|
||||
|
||||
Example config:
|
||||
|
||||
```yaml
|
||||
# Generated by mcp-synology-container setup
|
||||
schema_version: 1
|
||||
alias: HomeNAS
|
||||
connection:
|
||||
host: nas.example.com
|
||||
port: 443
|
||||
https: true
|
||||
verify_ssl: true
|
||||
compose_base_path: /volume1/docker
|
||||
```
|
||||
|
||||
**Credentials are NOT stored in this file.** They are stored in the OS keyring.
|
||||
|
||||
---
|
||||
|
||||
## Alternative: Environment Variables
|
||||
|
||||
If you prefer not to use the keyring (e.g. in Docker or CI environments), set these environment variables:
|
||||
|
||||
```bash
|
||||
export SYNOLOGY_HOST=192.168.1.100
|
||||
export SYNOLOGY_USERNAME=admin
|
||||
export SYNOLOGY_PASSWORD=yourpassword
|
||||
```
|
||||
|
||||
Environment variables take priority over the keyring.
|
||||
|
||||
You can also specify the config path:
|
||||
|
||||
```bash
|
||||
export MCP_SYNOLOGY_CONTAINER_CONFIG=/path/to/config.yaml
|
||||
```
|
||||
|
||||
Or pass it explicitly:
|
||||
|
||||
```bash
|
||||
mcp-synology-container serve --config /path/to/config.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## DSM User Permissions
|
||||
|
||||
The DSM account used by the MCP server needs:
|
||||
- Access to **Container Manager** (DSM > Control Panel > User > Applications)
|
||||
- **Read/Write** access to the shared folder where compose projects are stored
|
||||
|
||||
For read-only use (listing projects and viewing logs), read access is sufficient.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Connection refused / timeout**
|
||||
- Check NAS hostname and port
|
||||
- Verify the NAS is reachable from your machine
|
||||
- Try `mcp-synology-container check --verbose`
|
||||
|
||||
**Login failed**
|
||||
- Run `mcp-synology-container setup` to re-enter credentials
|
||||
- Check DSM > Control Panel > Security > Auto Block for IP blocks
|
||||
|
||||
**2FA fails**
|
||||
- Run `mcp-synology-container setup` again to get a fresh device token
|
||||
- If your account has app-specific 2FA enforcement, ensure the device token was saved
|
||||
|
||||
**Container Manager APIs not found**
|
||||
- Ensure Container Manager is installed and running in DSM Package Center
|
||||
- The package may appear as "Docker" in older DSM versions
|
||||
|
||||
**SSL certificate errors**
|
||||
- For self-signed certificates: run `setup` again and answer `n` to "Verify SSL certificate?"
|
||||
- Alternatively set `verify_ssl: false` in your config file
|
||||
+274
@@ -0,0 +1,274 @@
|
||||
# Tool Reference
|
||||
|
||||
This document describes all MCP tools provided by mcp-synology-container.
|
||||
|
||||
Tools marked **confirmation required** will return a description of the action and ask you to call the tool again with `confirmed=True` before executing. This prevents accidental destructive operations.
|
||||
|
||||
---
|
||||
|
||||
## Project Tools
|
||||
|
||||
### `list_projects`
|
||||
|
||||
List all Container Manager projects with their current status.
|
||||
|
||||
**Parameters:** none
|
||||
|
||||
**Returns:** Formatted table with project name, status, path, and container count.
|
||||
|
||||
**Example output:**
|
||||
```
|
||||
Projects:
|
||||
|
||||
myapp
|
||||
Status: RUNNING
|
||||
Path: /volume1/docker/myapp
|
||||
Containers: 2
|
||||
|
||||
database
|
||||
Status: STOPPED
|
||||
Path: /volume1/docker/database
|
||||
Containers: 0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `get_project_status`
|
||||
|
||||
Get detailed status of a specific project.
|
||||
|
||||
**Parameters:**
|
||||
- `project_name` (string, required): Name of the project
|
||||
|
||||
**Returns:** Detailed status including ID, path, timestamps, container IDs, and services.
|
||||
|
||||
---
|
||||
|
||||
### `start_project`
|
||||
|
||||
Start a stopped Container Manager project.
|
||||
|
||||
**Parameters:**
|
||||
- `project_name` (string, required): Name of the project to start
|
||||
|
||||
**Returns:** Success or error message.
|
||||
|
||||
---
|
||||
|
||||
### `stop_project`
|
||||
|
||||
Stop a running Container Manager project. Stops all containers in the project.
|
||||
|
||||
**Confirmation required.**
|
||||
|
||||
**Parameters:**
|
||||
- `project_name` (string, required): Name of the project to stop
|
||||
- `confirmed` (boolean, default `false`): Set to `true` to confirm
|
||||
|
||||
**Returns:** Confirmation prompt or success message.
|
||||
|
||||
---
|
||||
|
||||
### `redeploy_project`
|
||||
|
||||
Redeploy a project by pulling latest images, stopping, and restarting.
|
||||
|
||||
**Confirmation required.**
|
||||
|
||||
**Parameters:**
|
||||
- `project_name` (string, required): Name of the project to redeploy
|
||||
- `confirmed` (boolean, default `false`): Set to `true` to confirm
|
||||
|
||||
**Steps performed:**
|
||||
1. Pull latest images (`SYNO.Docker.Project` build)
|
||||
2. Stop all containers
|
||||
3. Start all containers
|
||||
|
||||
**Returns:** Confirmation prompt or step-by-step progress output.
|
||||
|
||||
---
|
||||
|
||||
## Container Tools
|
||||
|
||||
### `list_containers`
|
||||
|
||||
List containers, optionally filtered by project.
|
||||
|
||||
**Parameters:**
|
||||
- `project_name` (string, optional): Filter by project name. Lists all containers if omitted.
|
||||
|
||||
**Returns:** Formatted list with container name, status, and image.
|
||||
|
||||
---
|
||||
|
||||
### `get_container_status`
|
||||
|
||||
Get detailed status and resource information for a container.
|
||||
|
||||
**Parameters:**
|
||||
- `container_name` (string, required): Name of the container
|
||||
|
||||
**Returns:** Status, running state, image, start/stop times, memory limits, and environment variable count.
|
||||
|
||||
---
|
||||
|
||||
### `get_container_logs`
|
||||
|
||||
Fetch log output from a container.
|
||||
|
||||
**Parameters:**
|
||||
- `container_name` (string, required): Name of the container
|
||||
- `tail` (integer, default `100`): Number of recent log lines to return
|
||||
- `keyword` (string, optional): Filter logs to lines containing this keyword
|
||||
|
||||
**Returns:** Log lines with timestamps and stream tags (stdout/stderr).
|
||||
|
||||
**Example:**
|
||||
```
|
||||
Logs for myapp_web (showing 50 of 312):
|
||||
|
||||
2025-01-01T10:00:00Z [stdout] Server started on port 8080
|
||||
2025-01-01T10:00:01Z [stderr] Warning: deprecated config option
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `exec_in_container`
|
||||
|
||||
Execute a shell command in a running container.
|
||||
|
||||
**Confirmation required.**
|
||||
|
||||
**Parameters:**
|
||||
- `container_name` (string, required): Name of the container
|
||||
- `command` (string, required): Shell command to execute
|
||||
- `confirmed` (boolean, default `false`): Set to `true` to confirm
|
||||
|
||||
**Returns:** Confirmation prompt, or exit code and command output.
|
||||
|
||||
---
|
||||
|
||||
## Compose File Tools
|
||||
|
||||
Compose files are accessed via the Synology FileStation API. The server looks for the following filenames under `{compose_base_path}/{project_name}/`:
|
||||
|
||||
- `docker-compose.yml`
|
||||
- `docker-compose.yaml`
|
||||
- `compose.yml`
|
||||
- `compose.yaml`
|
||||
|
||||
### `read_compose`
|
||||
|
||||
Read the compose file of a project.
|
||||
|
||||
**Parameters:**
|
||||
- `project_name` (string, required): Name of the project
|
||||
|
||||
**Returns:** File path and full YAML content.
|
||||
|
||||
---
|
||||
|
||||
### `update_image_tag`
|
||||
|
||||
Update the image tag for a service in the compose file.
|
||||
|
||||
**Confirmation required.**
|
||||
|
||||
**Parameters:**
|
||||
- `project_name` (string, required): Name of the project
|
||||
- `service_name` (string, required): Name of the service in the compose file
|
||||
- `new_tag` (string, required): New image tag (e.g. `"latest"`, `"1.2.3"`)
|
||||
- `confirmed` (boolean, default `false`): Set to `true` to confirm
|
||||
|
||||
**Returns:** Confirmation prompt showing before/after, or success message with redeploy suggestion.
|
||||
|
||||
**Example confirmation prompt:**
|
||||
```
|
||||
About to update service 'web' in project 'myapp':
|
||||
Before: nginx:1.24
|
||||
After: nginx:1.25
|
||||
|
||||
Call this tool again with confirmed=True to apply the change.
|
||||
```
|
||||
|
||||
After applying: suggests running `redeploy_project`.
|
||||
|
||||
---
|
||||
|
||||
### `update_env_var`
|
||||
|
||||
Add or update an environment variable for a service.
|
||||
|
||||
**Confirmation required.**
|
||||
|
||||
**Parameters:**
|
||||
- `project_name` (string, required): Name of the project
|
||||
- `service_name` (string, required): Name of the service
|
||||
- `var_name` (string, required): Environment variable name
|
||||
- `var_value` (string, required): New value
|
||||
- `confirmed` (boolean, default `false`): Set to `true` to confirm
|
||||
|
||||
Supports both list format (`- KEY=VALUE`) and dict format (`KEY: VALUE`) in the compose file.
|
||||
|
||||
After applying: suggests running `redeploy_project`.
|
||||
|
||||
---
|
||||
|
||||
### `update_compose`
|
||||
|
||||
Replace the entire compose file with new content.
|
||||
|
||||
**Confirmation required.**
|
||||
|
||||
**Parameters:**
|
||||
- `project_name` (string, required): Name of the project
|
||||
- `new_content` (string, required): Complete new YAML content (must contain a `services` key)
|
||||
- `confirmed` (boolean, default `false`): Set to `true` to confirm
|
||||
|
||||
Validates that the content is valid YAML with a `services` key before writing.
|
||||
|
||||
After applying: suggests running `redeploy_project`.
|
||||
|
||||
---
|
||||
|
||||
## Image Tools
|
||||
|
||||
### `check_image_updates`
|
||||
|
||||
Check which images have updates available.
|
||||
|
||||
**Parameters:**
|
||||
- `project_name` (string, optional): Filter to images used by this project. Checks all images if omitted.
|
||||
|
||||
**Returns:** List of images with update status. Images with the `upgradable` flag from the NAS are highlighted.
|
||||
|
||||
**Example output:**
|
||||
```
|
||||
Image update status for project 'myapp':
|
||||
|
||||
Updates available (1):
|
||||
nginx:1.24 (50 MiB) ← UPDATE AVAILABLE
|
||||
|
||||
Up to date (1):
|
||||
postgres:15 (80 MiB)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Confirmation Pattern
|
||||
|
||||
Tools that modify state require confirmation to prevent accidents. The pattern is:
|
||||
|
||||
1. Call the tool without `confirmed`:
|
||||
```
|
||||
stop_project(project_name="myapp")
|
||||
```
|
||||
Returns a description of what will happen.
|
||||
|
||||
2. Call again with `confirmed=True`:
|
||||
```
|
||||
stop_project(project_name="myapp", confirmed=True)
|
||||
```
|
||||
Executes the operation.
|
||||
|
||||
This applies to: `stop_project`, `redeploy_project`, `exec_in_container`, `update_image_tag`, `update_env_var`, `update_compose`.
|
||||
Reference in New Issue
Block a user