Synology MCP Server
Gestiona archivos y descargas en dispositivos Synology NAS mediante un asistente de IA.
Documentación
💾 Synology MCP Server

Un servidor de Model Context Protocol (MCP) para dispositivos Synology NAS. Permite que los asistentes de IA gestionen archivos y descargas mediante autenticación segura y gestión de sesiones.
🌟 NUEVO: ¡El servidor unificado admite simultáneamente Claude/Cursor (stdio) y Xiaozhi (WebSocket)!
📦 Instalación desde PyPI
No es necesario clonar el repositorio: instala el paquete directamente desde PyPI:
# With pip
pip install mcp-server-synology
# Or with pipx (isolated environment)
pipx install mcp-server-synology
# Or with uv
uv tool install mcp-server-synology
Esto instala dos comandos equivalentes: synology-mcp y mcp-server-synology.
Para clientes MCP, uvx es la opción más sencilla: descarga y almacena en caché el paquete automáticamente, sin necesidad de instalación manual ni clonado local:
{
"mcpServers": {
"synology": {
"command": "uvx",
"args": ["mcp-server-synology"]
}
}
}
La configuración vive fuera del paquete, por lo que funciona igual que una copia del código fuente: crea ~/.config/synology-mcp/settings.json como se describe en Opciones de configuración.
🚀 Inicio rápido con Docker
1️⃣ Configurar el entorno
# Clone repository
git clone https://github.com/atom2ueki/mcp-server-synology.git
cd mcp-server-synology
# Create environment file
cp env.example .env
2️⃣ Configurar el archivo .env
Configuración básica (solo Claude/Cursor):
# Required: Synology NAS connection
SYNOLOGY_URL=http://192.168.1.100:5000
SYNOLOGY_USERNAME=your_username
SYNOLOGY_PASSWORD=your_password
# Optional: Auto-login on startup
AUTO_LOGIN=true
VERIFY_SSL=false
Configuración extendida (tanto Claude/Cursor como Xiaozhi):
# Required: Synology NAS connection
SYNOLOGY_URL=http://192.168.1.100:5000
SYNOLOGY_USERNAME=your_username
SYNOLOGY_PASSWORD=your_password
# Optional: Auto-login on startup
AUTO_LOGIN=true
VERIFY_SSL=false
# Enable Xiaozhi support
ENABLE_XIAOZHI=true
XIAOZHI_TOKEN=your_xiaozhi_token_here
XIAOZHI_MCP_ENDPOINT=wss://api.xiaozhi.me/mcp/
3️⃣ Ejecutar con Docker
Un solo comando simple admite ambos modos:
# Claude/Cursor only mode (default if ENABLE_XIAOZHI not set)
docker-compose up -d
# Both Claude/Cursor + Xiaozhi mode (if ENABLE_XIAOZHI=true in .env)
docker-compose up -d
# Build and run
docker-compose up -d --build
4️⃣ Alternativa: Python local
# Install the package and its dependencies (from PyPI, or from a clone with 'pip install .')
pip install mcp-server-synology
# Run with environment control
python main.py
🔌 Configuración del cliente
Los ejemplos siguientes usan Docker con una copia local de este repositorio. Si instalaste desde PyPI, usa la configuración uvx de Instalación desde PyPI en su lugar: funciona igual para Claude Desktop, Cursor, Continue y Codeium, sin necesidad de ajustar rutas locales.
🤖 Claude Desktop
Añade a tu archivo de configuración de Claude Desktop:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"synology": {
"command": "docker-compose",
"args": [
"-f", "/path/to/your/mcp-server-synology/docker-compose.yml",
"run", "--rm", "synology-mcp"
],
"cwd": "/path/to/your/mcp-server-synology"
}
}
}
↗️ Cursor
Añade a la configuración de MCP de Cursor:
{
"mcpServers": {
"synology": {
"command": "docker-compose",
"args": [
"-f", "/path/to/your/mcp-server-synology/docker-compose.yml",
"run", "--rm", "synology-mcp"
],
"cwd": "/path/to/your/mcp-server-synology"
}
}
}
🔄 Continue (Extensión de VS Code)
Añade a tu configuración de Continue (.continue/config.json):
{
"mcpServers": {
"synology": {
"command": "docker-compose",
"args": [
"-f", "/path/to/your/mcp-server-synology/docker-compose.yml",
"run", "--rm", "synology-mcp"
],
"cwd": "/path/to/your/mcp-server-synology"
}
}
}
💻 Codeium
Para el soporte MCP de Codeium:
{
"mcpServers": {
"synology": {
"command": "docker-compose",
"args": [
"-f", "/path/to/your/mcp-server-synology/docker-compose.yml",
"run", "--rm", "synology-mcp"
],
"cwd": "/path/to/your/mcp-server-synology"
}
}
}
🐍 Alternativa: Ejecución directa con Python
Si prefieres no usar Docker:
{
"mcpServers": {
"synology": {
"command": "python",
"args": ["main.py"],
"cwd": "/path/to/your/mcp-server-synology",
"env": {
"SYNOLOGY_URL": "http://192.168.1.100:5000",
"SYNOLOGY_USERNAME": "your_username",
"SYNOLOGY_PASSWORD": "your_password",
"AUTO_LOGIN": "true",
"ENABLE_XIAOZHI": "false"
}
}
}
}
🌐 Despliegue remoto con HTTP Streamable
Por defecto, el servidor usa stdio, lo que significa que el cliente MCP debe iniciar el proceso localmente (o mediante un puente como SSH o docker exec). Para configuraciones donde el NAS es remoto (en una máquina distinta de donde se ejecuta Claude/Cursor), establece MCP_HTTP=true y el servidor ofrecerá HTTP Streamable nativo desde uvicorn en el mismo proceso, sin sidecar mcp-proxy ni endpoint /sse separado. Esto lo hace consumible por cualquier cliente MCP que admita conectores basados en URL, exactamente igual que ha-mcp u otros servidores MCP "remotos".
Arquitectura
[Claude Desktop / Cursor / ...]
│
│ HTTPS (URL connector)
▼
[Reverse proxy: DSM / Nginx / Traefik / Caddy]
│ (TLS termination + auth)
│ HTTP localhost:8765
▼
[Docker container]
└─ python main.py
└─ uvicorn → Streamable HTTP at /mcp
Despliegue
- Todas las dependencias provienen de
pyproject.toml:mcp>=2.0.0incluye starlette, uvicorn y sse-starlette, por lo que la misma imagen sirve tanto para stdio como para HTTP Streamable, sin argumentos de compilación adicionales ni archivos de requisitos separados. - Usa el
docker-compose.http.ymlproporcionado:
# Edit credentials in docker-compose.http.yml first
docker compose -f docker-compose.http.yml up -d --build
docker logs -f synology-mcp-http
Deberías ver el registro del servidor Starting Streamable HTTP MCP server on http://0.0.0.0:8765/mcp y el inicio de sesión automático exitoso. El banner Uvicorn running on … propio de uvicorn no se imprime con los valores predeterminados del archivo compose: es INFO en el registrador uvicorn.error, que el servidor fija en warning a menos que se establezca DEBUG=true.
Proxy inverso
La mayoría de los clientes MCP requieren HTTPS, por lo que el endpoint HTTP debe estar respaldado por un proxy inverso que termine TLS. Para usuarios de DSM, el Portal de inicio de sesión → Proxy inverso integrado cumple esta función:
- Origen:
HTTPS, nombre de hostsynology-mcp.example.com, puerto443 - Destino:
HTTP,localhost, puerto8765 - Encabezados personalizados: no se requiere ninguno: HTTP Streamable es POST/GET simple en un único endpoint, no una actualización de WebSocket. El ajuste preestablecido Crear → WebSocket es inofensivo si ya lo aplicas en otro lugar (establece
Connection: upgradesolo para solicitudes de actualización reales), pero no es lo que mantiene un flujo abierto
Para Nginx, el equivalente es:
location / {
proxy_pass http://localhost:8765;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Responses may stream as long-lived text/event-stream
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 24h;
}
Configuración del cliente
En Claude Desktop (o cualquier cliente MCP que admita conectores remotos), añade un conector personalizado que apunte a:
https://synology-mcp.example.com/mcp
La ruta es la que sea que MCP_HTTP_PATH tenga configurado (por defecto /mcp). Sin command, sin args, sin Python local: solo una URL.
Seguridad
El servidor no implementa autenticación a nivel de aplicación: cualquier cosa que pueda alcanzar el endpoint HTTP puede llamar a todas las herramientas. Sí habilita la protección contra rebinding de DNS del SDK de MCP, que rechaza solicitudes cuyos encabezados Host/Origin no estén en una lista de permitidos (MCP_HTTP_ALLOWED_HOSTS / MCP_HTTP_ALLOWED_ORIGINS, con valor predeterminado de loopback). Detrás de un proxy inverso, establece ambos, teniendo en cuenta los formatos diferentes: los hosts son simples (synology-mcp.example.com), los orígenes están calificados por esquema (https://synology-mcp.example.com), como en los ejemplos comentados en docker-compose.http.yml. Eso protege a los navegadores contra ataques de rebinding; no es autenticación. Mitigaciones:
- Mantenlo en una red privada o detrás de una VPN
- Deja el puerto publicado en loopback (
docker-compose.http.ymlenlaza127.0.0.1:8765) para que solo un proxy inverso en el mismo host pueda alcanzarlo - Usa el proxy inverso para imponer una lista de permitidos por IP
- Añade autenticación básica / mTLS / proxy OAuth2 en la capa del proxy inverso
- Usa un usuario DSM dedicado con privilegios bajos (ya recomendado en la advertencia de seguridad anterior)
🌟 Integración con Xiaozhi
¡La nueva arquitectura unificada admite ambos clientes simultáneamente!
Cómo funciona
- ENABLE_XIAOZHI=false (predeterminado): servidor MCP estándar para Claude/Cursor mediante stdio
- ENABLE_XIAOZHI=true: puente multicliente que admite ambos:
- 📡 Xiaozhi: conexión WebSocket
- 💻 Claude/Cursor: conexión stdio
Pasos de configuración
- Añade a tu archivo .env:
ENABLE_XIAOZHI=true
XIAOZHI_TOKEN=your_xiaozhi_token_here
- Ejecuta normalmente:
# Same command, different behavior based on environment
python main.py
# OR
docker-compose up
Características clave
- ✅ Cero conflictos de configuración: un servidor, múltiples clientes
- ✅ Operación en paralelo: ambos clientes pueden trabajar simultáneamente
- ✅ Todas las herramientas disponibles: Xiaozhi obtiene acceso a todas las herramientas de Synology MCP
- ✅ Compatibilidad retroactiva: las configuraciones existentes funcionan sin cambios
- ✅ Reconexión automática: gestiona caídas de conexión WebSocket
- ✅ Controlado por entorno: indicador booleano simple para habilitar/deshabilitar
Mensajes de inicio
Modo solo Claude/Cursor:
🚀 Synology MCP Server
==============================
📌 Claude/Cursor only mode (ENABLE_XIAOZHI=false)
Modo ambos clientes:
🚀 Synology MCP Server with Xiaozhi Bridge
==================================================
🌟 Supports BOTH Xiaozhi and Claude/Cursor simultaneously!
🛠️ Herramientas MCP disponibles
🔐 Autenticación
synology_status- Comprueba el estado de autenticación y las sesiones activassynology_list_nas- Lista todas las unidades NAS configuradas desde settings.jsonsynology_login- Autentica con Synology NAS (condicional)synology_logout- Cierra sesión (condicional)
📁 Operaciones del sistema de archivos
list_shares- Lista todos los recursos compartidos NAS disponibleslist_directory- Lista el contenido de un directorio con metadatospath(obligatorio): ruta de directorio que comienza con/
get_file_info- Obtiene información detallada de archivos/directoriospath(obligatorio): ruta de archivo que comienza con/
get_file_content- Lee texto UTF-8 estricto o contenido base64 sin pérdidapath(obligatorio): ruta de archivo que comienza con/encoding(opcional):text(predeterminado) obase64max_bytes(opcional): bytes brutos máximos a leer (predeterminado 1 MiB, límite estricto 8 MiB)
search_files- Busca recursivamente archivos y carpetas por nombrepath(obligatorio): directorio de búsquedapattern(obligatorio): subcadena del nombre sin distinción de mayúsculas (p. ej.,invoice,.pdf). Los comodines no son especiales: DSM coincidereporty*report*de forma idéntica.
create_file- Crea nuevos archivos con contenidopath(obligatorio): ruta completa del archivo que comienza con/content(opcional): contenido del archivo (predeterminado: cadena vacía)overwrite(opcional): sobrescribir archivos existentes (predeterminado: false)encoding(opcional):text(predeterminado) obase64estricto; el contenido decodificado está limitado a 8 MiB
create_directory- Crea nuevos directoriosfolder_path(obligatorio): ruta del directorio principal que comienza con/name(obligatorio): nombre del nuevo directorioforce_parent(opcional): crear directorios principales si es necesario (predeterminado: false)
delete- Elimina archivos o directorios (detecta el tipo automáticamente)path(obligatorio): ruta de archivo/directorio que comienza con/
rename_file- Renombra archivos o directoriospath(obligatorio): ruta actual del archivonew_name(obligatorio): nuevo nombre de archivo
move_file- Mueve archivos a una nueva ubicaciónsource_path(obligatorio): ruta del archivo de origendestination_path(obligatorio): ruta de destinooverwrite(opcional): sobrescribir archivos existentes
copy_file- Copia un archivo normal dentro del NAS sin enviar sus bytes a través del cliente MCPsource_path(obligatorio): ruta del archivo de origendestination_folder(obligatorio): directorio de destino existente; se conserva el nombre del archivooverwrite(opcional): sobrescribir un archivo existente con el mismo nombre (predeterminado: false)
copy_file verifica la ruta de destino y el recuento de bytes. No es un método de copia de seguridad coherente para una base de datos SQLite en vivo; usa el mecanismo de copia de seguridad en línea de SQLite para bases de datos que puedan estar cambiando durante la copia.
📥 Gestión de Download Station
ds_get_info- Obtiene información de Download Stationds_list_tasks- Lista todas las tareas de descarga con estadooffset(opcional): desplazamiento de paginaciónlimit(opcional): máximo de tareas a devolver
ds_create_task- Crea una nueva tarea de descargauri(obligatorio): URL de descarga o enlace magnetdestination(opcional): ruta de la carpeta de descarga
ds_pause_tasks- Pausa tareas de descargatask_ids(obligatorio): matriz de ID de tareas
ds_resume_tasks- Reanuda tareas pausadastask_ids(obligatorio): matriz de ID de tareas
ds_delete_tasks- Elimina tareas de descargatask_ids(obligatorio): matriz de ID de tareasforce_complete(opcional): forzar eliminación de completadas
ds_get_statistics- Obtiene estadísticas de descarga/carga
🏥 Monitoreo de salud
synology_system_info- Obtiene modelo del sistema, número de serie, versión de DSM, tiempo de actividad, temperaturasynology_utilization- Obtiene utilización en tiempo real de CPU, memoria, swap y E/S de discosynology_disk_health- Lista todos los discos físicos con estado SMART, modelo, temperatura, tamañosynology_disk_smart- Obtiene atributos SMART detallados para un disco específicosynology_volume_status- Lista todos los volúmenes con estado, tamaño, uso, tipo de sistema de archivossynology_storage_pool- Lista grupos RAID/almacenamiento con nivel, estado, discos miembrossynology_lun_list- Lista todos los LUN iSCSI con nombre, UUID, tamaño, tipo, estado y volumen subyacente. Para ver a qué destino está conectado un LUN, usasynology_target_list: DSM no informa asignaciones en el lado del LUN.synology_lun_get- Obtiene detalles de un solo LUN iSCSIname(obligatorio): nombre del LUN o UUID de la salida desynology_lun_list
synology_network- Obtiene estado de la interfaz de red y tasas de transferencia
SAN Manager (aprovisionamiento iSCSI)
Envuelve SYNO.Core.ISCSI.LUN y SYNO.Core.ISCSI.Target. Verificado contra DSM 7.3.2-86009 Update 4 en un RS1221+; otras versiones de DSM pueden diferir, y la negativa del propio DSM se informa tal como se da, sin cuestionarla.
synology_lun_create- Crea un LUN en un volumen; devuelve suuuidylun_idname,location(p. ej.,/volume2),size(en bytes) son obligatoriostype(opcional):thin(predeterminado, DSMBLUN),advanced,file, o un nombre de tipo DSM sin procesar. Ten en cuenta quethinyTHINson diferentes: las minúsculas son el alias amigable paraBLUN, las mayúsculas son el tipo heredado distinto de DSM. Los tipos gruesos fueron rechazados en el volumen btrfs con el que se probó.description(opcional)
synology_lun_delete- DESTRUCTIVO. Elimina un LUN y todo lo que contieneuuidyconfirm: trueson obligatorios
synology_target_list- Lista los objetivos con IQN, tipo de autenticación y los LUN asignados a cada unosynology_target_get- Obtiene un objetivo portarget_idsynology_target_create- Crea un objetivo; devuelve sutarget_idnamees obligatorio;iqntiene como predeterminadoiqn.2000-01.com.synology:<name>chap_user+chap_passwordhabilitan CHAP. Proporciona ambos o ninguno: uno solo, o una cadena vacía, se rechaza en lugar de producir silenciosamente un objetivo sin autenticación. Con ninguno, el objetivo acepta cualquier iniciador que pueda alcanzarlo.max_sessions(opcional, 0 = predeterminado de DSM)
synology_target_map_lun- Asigna LUN a un objetivo (target_id,lun_uuids)synology_target_unmap_lun- DESTRUCTIVO. Desasigna LUN, desconectando cualquier iniciador que los use (target_id,lun_uuids,confirm: true)
Estas herramientas rechazan cualquier argumento que no declaran, en lugar de ignorarlo: un chap_user mal escrito crearía un objetivo sin autenticación, y un type mal escrito tomaría silenciosamente el valor predeterminado.
synology_ups- Obtiene el estado del SAI, nivel de batería, lecturas de energíasynology_services- Lista los paquetes instalados y su estado de ejecuciónsynology_system_log- Obtiene las entradas recientes del registro del sistemasynology_health_summary- Agrega información del sistema, utilización, salud del disco y estado del volumen
🐳 Container Manager
synology_container_list- Lista los contenedores de Container Manageroffset(opcional): Desplazamiento de paginaciónlimit(opcional): Máximo de contenedores a devolvercontainer_type(opcional): Filtro de contenedores (predeterminado:all)
synology_container_health_summary- Resume el estado del contenedor, salud, recuentos de reinicios e imágenessynology_container_disk_usage- Muestra el resumen de uso de disco de solo lectura disponible a través de las API de Container Managersynology_container_get- Obtiene un contenedor de Container Managername(obligatorio): Nombre del contenedor
synology_container_start- Inicia un contenedor de Container Managername(obligatorio): Nombre del contenedor
synology_container_stop- Detiene un contenedor de Container Managername(obligatorio): Nombre del contenedor
synology_container_restart- Reinicia un contenedor de Container Managername(obligatorio): Nombre del contenedor
synology_container_delete- Elimina un contenedor de Container Managername(obligatorio): Nombre del contenedorforce(opcional): Forzar eliminación (predeterminado: false)preserve_profile(opcional): Conservar el perfil de contenedor de Synology (predeterminado: true)
synology_container_logs- Obtiene los registros de un contenedor de Container Managername(obligatorio): Nombre del contenedorsince(opcional): Hora de inicio/filtro de registrosoffset(opcional): Desplazamiento de paginación (predeterminado: 0)limit(opcional): Máximo de líneas de registro a devolver (predeterminado: 1000)
synology_container_resource- Obtiene el uso de recursos en tiempo real de un contenedor de Container Managername(obligatorio): Nombre del contenedor
synology_container_project_list- Lista los proyectos de Container Managersynology_container_project_get- Obtiene un proyecto de Container Manager (los campos Compose, entorno y secreto se omiten)name(obligatorio): Nombre del proyecto
synology_container_project_create- Crea y guarda una definición de proyecto de Container Managername(obligatorio): Nombre del proyectoshare_path(obligatorio): Ruta de la carpeta del proyecto en el NAScontent(obligatorio): Contenido YAML de Docker Composeenable_service_portal(opcional): Habilitar el portal de servicios de Synology (predeterminado: false)service_portal_name(opcional): Nombre del portal de serviciosservice_portal_port(opcional): Puerto del portal de serviciosservice_portal_protocol(opcional): Protocolo del portal de servicios (predeterminado:http)- Guarda la definición de Compose; llama a
synology_container_project_buildpara materializarla.
synology_container_project_update- Actualiza un proyecto de Container Managername(obligatorio): Nombre del proyectocontent(obligatorio): Contenido YAML de Docker Composeenable_service_portal(opcional): Habilitar el portal de servicios de Synologyservice_portal_name(opcional): Nombre del portal de serviciosservice_portal_port(opcional): Puerto del portal de serviciosservice_portal_protocol(opcional): Protocolo del portal de servicios
synology_container_project_start- Inicia un proyecto de Container Managername(obligatorio): Nombre del proyecto
synology_container_project_stop- Detiene un proyecto de Container Managername(obligatorio): Nombre del proyecto
synology_container_project_restart- Reinicia un proyecto de Container Managername(obligatorio): Nombre del proyecto
synology_container_project_build- Materializa o reconstruye un proyecto guardado de Container Managername(obligatorio): Nombre del proyecto
synology_container_project_clean- Limpia un proyecto de Container Managername(obligatorio): Nombre del proyecto
synology_container_project_delete- Elimina un proyecto de Container Managername(obligatorio): Nombre del proyecto
synology_container_image_list- Lista las imágenes de Container Manageroffset(opcional): Desplazamiento de paginaciónlimit(opcional): Máximo de imágenes a devolvershow_dsm(opcional): Incluir imágenes de DSM (predeterminado: false)
synology_container_image_get- Obtiene una imagen de Container Managername(obligatorio): Nombre del repositorio de la imagentag(opcional): Etiqueta de la imagen (predeterminado:latest)
synology_container_image_delete- Elimina una imagen de Container Managername(obligatorio): Nombre del repositorio de la imagentag(opcional): Etiqueta de la imagen (predeterminado:latest)
synology_container_image_prune- Elimina imágenes no utilizadas por ningún contenedorsynology_container_image_prune_previewproporciona una lista de candidatos de solo lectura antes de la limpieza- Usa solo las API de Container Manager para eliminar de forma segura imágenes etiquetadas no utilizadas identificables y reporta imágenes colgantes que no puede eliminar a través de DSM
- No elimina contenedores, redes ni caché de compilación
synology_container_image_pull- Descarga una imagen de Container Managerrepository(obligatorio): Nombre del repositorio de la imagentag(opcional): Etiqueta de la imagen (predeterminado:latest)
synology_container_registry_list- Lista los registros de Container Managersynology_container_registry_search- Busca en los registros de Container Managerquery(obligatorio): Consulta de búsqueda de imágenesoffset(opcional): Desplazamiento de paginaciónlimit(opcional): Máximo de resultados a devolver
synology_container_registry_tags- Lista las etiquetas de una imagen de registrorepository(obligatorio): Nombre del repositorio de la imagenoffset(opcional): Desplazamiento de paginaciónlimit(opcional): Máximo de etiquetas a devolver
synology_container_registry_download- Descarga una imagen de registrorepository(obligatorio): Nombre del repositorio de la imagentag(opcional): Etiqueta de la imagen (predeterminado:latest)
synology_container_network_list- Lista las redes de Container Managersynology_container_network_get- Obtiene una red de Container Managername(obligatorio): Nombre de la red
synology_container_network_create- Crea una red de Container Managername(obligatorio): Nombre de la reddriver(opcional): Controlador de red (predeterminado:bridge)subnet(opcional): CIDR de subredgateway(opcional): IP de puerta de enlaceip_range(opcional): Rango de IP asignable CIDRenable_ipv6(opcional): Habilitar IPv6 (predeterminado: false)
synology_container_network_delete- Elimina una red de Container Managername(obligatorio): Nombre de la red
📦 Gestión de NFS
synology_nfs_status- Obtiene el estado y la configuración del servicio NFSsynology_nfs_enable- Habilita o deshabilita el servicio NFSsynology_nfs_list_shares- Lista todas las carpetas compartidas con sus permisos NFSsynology_nfs_set_permission- Establece permisos de acceso de clientes NFS en una carpeta compartida
🧠 Habilidad de Claude Code / Claude.ai
Para usuarios de Claude Code, Claude Desktop y claude.ai, este repositorio incluye una habilidad de agente de Anthropic que enseña a Claude cómo usar las herramientas MCP de manera efectiva: elegir la herramienta correcta, apuntar al NAS correcto en configuraciones de múltiples NAS, preferir verificaciones de salud agregadas sobre llamadas de expansión, y usar convenciones de ruta correctas.
La habilidad se encuentra en skills/synology-nas/ y usa divulgación progresiva en siete dominios (autenticación, archivos, descargas, salud, contenedores, recursos compartidos/NFS, gestión de usuarios).
Instalación:
- Claude Code: copia o enlaza simbólicamente la carpeta en
~/.claude/skills/synology-nas/ - Claude.ai / Claude Desktop: sube la carpeta
synology-nas/a través de la página de configuración de Skills
La habilidad es puramente aditiva: funciona junto con el MCP y solo se activa con indicaciones relacionadas con Synology/NAS.
⚙️ Opciones de Configuración
⚠️ Advertencia de Seguridad: Usa una Cuenta Dedicada
Para este servidor MCP, crea una cuenta de usuario de Synology dedicada con permisos apropiados. Esta cuenta debe:
- Tener solo los permisos mínimos requeridos (¡no administrador!)
- Usarse exclusivamente para la automatización del servidor MCP
- 2FA ahora es compatible — si tu cuenta DSM tiene 2FA habilitado, consulta la sección Cuentas 2FA / OTP a continuación para proporcionar un campo
otp_code(de un solo uso) odevice_id(persistente). La guía anterior de "sin 2FA" ya no es necesaria.
Uso de settings.json (Recomendado)
| Variable | Obligatoria | Predeterminado | Descripción |
|---|---|---|---|
SYNOLOGY_URL | Sí* | - | URL base del NAS (p. ej., http://192.168.1.100:5000) |
SYNOLOGY_USERNAME | Sí* | - | Nombre de usuario para autenticación |
SYNOLOGY_PASSWORD | Sí* | - | Contraseña para autenticación |
AUTO_LOGIN | No | true | Inicio de sesión automático al iniciar el servidor |
VERIFY_SSL | No | false | Verificar certificados SSL |
DEBUG | No | false | Habilitar registro de depuración |
ENABLE_XIAOZHI | No | false | Habilitar puente WebSocket de Xiaozhi |
XIAOZHI_TOKEN | Solo Xiaozhi | - | Token de autenticación para Xiaozhi |
XIAOZHI_MCP_ENDPOINT | No | wss://api.xiaozhi.me/mcp/ | Punto final WebSocket de Xiaozhi |
*Obligatorio para inicio de sesión automático y operaciones predeterminadas
Uso de settings.json (Soporte Multi-NAS)
Para gestionar múltiples dispositivos NAS de Synology, usa el directorio de configuración estándar XDG (~/.config/synology-mcp/settings.json):
mkdir -p ~/.config/synology-mcp
touch ~/.config/synology-mcp/settings.json
chmod 600 ~/.config/synology-mcp/settings.json # Important: secure permissions!
Nota: Esto sigue la Especificación de Directorio Base XDG - ~/.config/ es la ubicación estándar para archivos de configuración de usuario en Linux/macOS. Puedes personalizar la ubicación configurando la variable de entorno XDG_CONFIG_HOME.
Con Docker:
El archivo docker-compose.yml monta automáticamente tu directorio ~/.config/synology-mcp en el contenedor en /home/mcpuser/.config/synology-mcp, por lo que multi-NAS funciona de inmediato también con Docker.
Formato de settings.json:
{
"synology": {
"nas1": {
"host": "192.168.1.100",
"port": 5000,
"username": "admin",
"password": "your_password",
"note": "Primary NAS at home"
},
"nas2": {
"host": "192.168.1.200",
"port": 5001,
"username": "admin",
"password": "your_password",
"note": "Backup NAS"
},
"nas3": {
"url": "https://nas.example.com",
"username": "admin",
"password": "your_password",
"note": "NAS behind a reverse proxy"
}
},
"xiaozhi": {
"enabled": false,
"token": "your_xiaozhi_token",
"endpoint": "wss://api.xiaozhi.me/mcp/"
},
"server": {
"auto_login": true,
"verify_ssl": false,
"session_timeout": 3600,
"debug": false,
"log_level": "INFO"
}
}
Campos de configuración:
| Campo | Obligatorio | Descripción |
|---|---|---|
host | Sí* | Nombre de host o dirección IP del NAS |
port | No | Puerto de la API (predeterminado: 5000 para HTTP, 5001 para HTTPS) |
url | Sí* | URL base completa (p. ej., https://nas.example.com); tiene prioridad sobre host/port — úsalo para un NAS detrás de un proxy inverso |
username | Sí | Nombre de usuario del NAS |
password | Sí | Contraseña del NAS |
otp_code | No | Código 2FA de 6 dígitos de un solo uso (solo en el primer inicio de sesión, luego elimínalo) |
device_id | No | Token de dispositivo de confianza de larga duración de DSM (did); omite OTP en todos los futuros inicios de sesión |
note | No | Descripción opcional para tu referencia |
*Se requiere host o url por entrada de NAS.
Notas:
- El servidor usará el puerto 5001 (HTTPS) si el puerto es 5001; de lo contrario, usará HTTP (5000) por defecto
- El formato
host/portsiempre agrega un puerto y deriva el esquema de él, por lo que no puede expresarhttps://nas.example.comen el puerto 443 predeterminado — estableceurldirectamente para configuraciones con proxy inverso - Permisos de archivo: se requiere
chmod 600 ~/.config/synology-mcp/settings.jsonpor seguridad - El servidor se negará a cargar la configuración si los permisos son demasiado abiertos
- Tanto .env como settings.json se pueden usar juntos (settings.json tiene prioridad)
⚠️ Recomendaciones de seguridad
Permisos de archivo settings.json:
- Linux/macOS (POSIX): Se requiere
chmod 600 ~/.config/synology-mcp/settings.json. El servidor se niega a cargar el archivo si es legible/escribible por el grupo o por otros, o si pertenece a otro usuario. - Windows: El control de acceso se aplica mediante ACL de NTFS, no mediante bits de modo POSIX. El servidor audita el descriptor de seguridad del archivo y se niega a cargarlo a menos que se cumplan las tres condiciones: (1) el SID del propietario coincide con el usuario actual; (2) el DACL está presente (un DACL NULL — "acceso total para todos" — se rechaza); (3) ningún ACE de concesión otorga acceso a una entidad fuera de la lista de permitidos: el usuario actual,
NT AUTHORITY\SYSTEMyBUILTIN\Administrators. Cualquier concesión heredada deEveryone/BUILTIN\Users/Authenticated Usersfalla la verificación.-
Requiere el paquete opcional
pywin32:pip install pywin32. Si pywin32 no está instalado, el servidor falla de forma segura y se niega a cargarsettings.json. Los operadores que aceptan el riesgo de un archivo no verificado pueden volver a activarlo estableciendoSYNOLOGY_MCP_ALLOW_UNVERIFIED_WINDOWS_ACL=true. -
El servidor resuelve el archivo mediante
XDG_CONFIG_HOME(predeterminadoPath.home() / ".config"), por lo que en Windows se encuentra en%USERPROFILE%\.config\synology-mcp\settings.jsona menos que se establezcaXDG_CONFIG_HOME. -
Bloquea el archivo desde un símbolo del sistema de PowerShell elevado (usa la misma ruta que carga el servidor):
# Resolve the path the SAME way the server does: $XDG_CONFIG_HOME if set, # otherwise %USERPROFILE%\.config. This honors the override documented above. $cfg = if ($env:XDG_CONFIG_HOME) { $env:XDG_CONFIG_HOME } else { "$env:USERPROFILE\.config" } $f = "$cfg\synology-mcp\settings.json" # The server's ACL audit requires: owner == current user, no NULL DACL, and # no allow-ACE outside {current user, SYSTEM, Administrators}. The steps # below enforce all three. # # Use the *<SID> form for every built-in principal: account names like # "Administrators" / "Everyone" / "Users" are localized on non-English # Windows (e.g. German "Administratoren") and won't resolve. The # locale-independent SIDs: # *S-1-1-0 Everyone # *S-1-5-11 Authenticated Users # *S-1-5-32-545 BUILTIN\Users # *S-1-5-32-544 BUILTIN\Administrators # # 1. Ensure the file is owned by the current user (the audit rejects any # other owner). /setowner requires elevation. icacls $f /setowner "${env:USERNAME}" # 2. Drop inherited ACEs, then revoke the common foreign grants. /grant:r # only replaces the named principal, so revoke first. icacls $f /inheritance:r icacls $f /remove:g "*S-1-1-0" "*S-1-5-11" "*S-1-5-32-545" # Re-run `icacls $f` here; if any principal other than your user or # Administrators still appears, run: icacls $f /remove:g "<that principal>" # 3. Grant the current user and Administrators full control. icacls $f /grant:r "${env:USERNAME}:(F)" icacls $f /grant:r "*S-1-5-32-544:(F)" # BUILTIN\Administrators (locale-independent)Si el archivo es nuevo, el paso
/remove:ges un no-op inofensivo. -
Verifica:
icacls "$f"— solo tu usuario y*S-1-5-32-544(Administradores) deberían aparecer.
-
Verificación de certificado SSL (VERIFY_SSL):
- El valor predeterminado es
falsepara admitir certificados autofirmados en dispositivos NAS internos - Si tu NAS tiene un certificado SSL válido (p. ej., de Let's Encrypt o una CA corporativa), establece
VERIFY_SSL=true - Establecer
VERIFY_SSL=falsedeshabilita la verificación de certificados y hace que tu conexión sea vulnerable a ataques de intermediario (MITM) - Nunca deshabilites la verificación SSL en redes no confiables
Inicio de sesión automático (AUTO_LOGIN):
- El valor predeterminado es
truepor conveniencia con settings.json - Las credenciales se almacenan de forma segura en
~/.config/synology-mcp/settings.jsoncon permisos 0600 - Si prefieres el inicio de sesión manual, establece
AUTO_LOGIN=falsey usa la herramientasynology_login
Cuentas 2FA / OTP (opcional):
El servidor MCP admite cuentas DSM con 2FA habilitado. Hay dos formas de usarlo:
-
OTP de un solo uso mediante la herramienta
synology_login(interactivo):{ "base_url": "https://nas.lan:5001", "username": "alice", "password": "…", "otp_code": "123456" }DSM devolverá un
did(token de dispositivo) en la respuesta — copia ese valor ensettings.json(abajo) para omitir OTP en futuros reinicios del proceso. -
Token de dispositivo de confianza persistente (recomendado para
AUTO_LOGIN=true):Agrega los campos
otp_code(de un solo uso, solo en el primer inicio de sesión) y/odevice_id(de larga duración, continuo) por NAS ensettings.json:{ "synology": { "nas1": { "host": "192.168.1.100", "port": 5001, "username": "alice", "password": "…", "otp_code": "123456", "note": "primary — 2FA enabled" } } }Flujo de trabajo:
- Establece
otp_codea un código fresco de 6 dígitos de tu autenticador e inicia el servidor. - En el primer inicio de sesión exitoso, el servidor registra una línea de advertencia como:
nas1: 2FA bootstrap — copy this device_id into settings.json to skip OTP on future starts: <did>Copia el valor de<did>. - Pégalo en
device_idy eliminaotp_code. - De ahora en adelante, DSM trata este proceso como un dispositivo de confianza — los reinicios, los reinicios de sesión después del error 119 de DSM y las sesiones del administrador de contenedores omiten OTP.
Cuando
device_idestá presente, tiene prioridad sobreotp_code(ruta de dispositivo de confianza). Los usuarios de.envheredado pueden establecer la variable de entorno de un solo usoSYNOLOGY_OTP_CODE; paradevice_idpersistente, migra asettings.json(el token opaco largo no cabe limpiamente en una variable de entorno). - Establece
📖 Ejemplos de uso
📁 Operaciones de archivos
✅ Crear archivos y directorios

// List directory
{
"path": "/volume1/homes"
}
// Search for PDFs
{
"path": "/volume1/documents",
"pattern": ".pdf"
}
// Create new file
{
"path": "/volume1/documents/notes.txt",
"content": "My important notes\nLine 2 of notes",
"overwrite": false
}
🗑️ Eliminar archivos y directorios

// Delete file or directory (auto-detects type)
{
"path": "/volume1/temp/old-file.txt"
}
// Move file
{
"source_path": "/volume1/temp/file.txt",
"destination_path": "/volume1/archive/file.txt"
}
⬇️ Gestión de descargas
🛠️ Crear una tarea de descarga

// Create download task
{
"uri": "https://example.com/file.zip",
"destination": "/volume1/downloads"
}
// Pause tasks
{
"task_ids": ["dbid_123", "dbid_456"]
}
🦦 Resultados de descarga

✨ Características
- ✅ Punto de entrada unificado - Un solo
main.pyadmite clientes stdio y WebSocket - ✅ Controlado por entorno - Cambia de modo mediante la variable de entorno
ENABLE_XIAOZHI - ✅ Soporte multi-cliente - Acceso simultáneo de Claude/Cursor + Xiaozhi
- ✅ Autenticación segura - Transmisión de contraseña cifrada con RSA
- ✅ Gestión de sesiones - Sesiones persistentes en múltiples dispositivos NAS
- ✅ Operaciones de archivos completas - Crear, eliminar, listar, buscar, renombrar, mover archivos con metadatos detallados
- ✅ Gestión de directorios - Operaciones recursivas de directorios con comprobaciones de seguridad
- ✅ Download Station - Gestión completa de torrents y descargas
- ✅ Soporte Docker - Implementación fácil en contenedores
- ✅ Compatibilidad hacia atrás - Las configuraciones existentes funcionan sin cambios
- ✅ Manejo de errores - Informes de errores y recuperación integrales
🏗️ Arquitectura
Estructura de archivos
mcp-server-synology/
├── main.py # 🎯 Unified entry point
├── src/
│ ├── mcp_server.py # Standard MCP server
│ ├── multiclient_bridge.py # Multi-client bridge
│ ├── auth/ # Authentication modules
│ ├── filestation/ # File operations
│ └── downloadstation/ # Download management
├── docker-compose.yml # Single service, environment-controlled
├── Dockerfile
├── pyproject.toml # Dependencies (single source of truth)
└── .env # Configuration
Selección de modo
ENABLE_XIAOZHI=false→main.py→mcp_server.py(solo stdio)ENABLE_XIAOZHI=true→main.py→multiclient_bridge.py→mcp_server.py(ambos clientes)
¡Perfecto para cualquier flujo de trabajo, desde el uso simple de Claude/Cursor hasta configuraciones avanzadas de múltiples clientes! 🚀