Synology MCP Server

Gestiona archivos y descargas en dispositivos Synology NAS mediante un asistente de IA.

Documentación

💾 Synology MCP Server

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

  1. Todas las dependencias provienen de pyproject.toml: mcp>=2.0.0 incluye 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.
  2. Usa el docker-compose.http.yml proporcionado:
# 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 host synology-mcp.example.com, puerto 443
  • Destino: HTTP, localhost, puerto 8765
  • 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: upgrade solo 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.yml enlaza 127.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

  1. Añade a tu archivo .env:
ENABLE_XIAOZHI=true
XIAOZHI_TOKEN=your_xiaozhi_token_here
  1. 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 activas
  • synology_list_nas - Lista todas las unidades NAS configuradas desde settings.json
  • synology_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 disponibles
  • list_directory - Lista el contenido de un directorio con metadatos
    • path (obligatorio): ruta de directorio que comienza con /
  • get_file_info - Obtiene información detallada de archivos/directorios
    • path (obligatorio): ruta de archivo que comienza con /
  • get_file_content - Lee texto UTF-8 estricto o contenido base64 sin pérdida
    • path (obligatorio): ruta de archivo que comienza con /
    • encoding (opcional): text (predeterminado) o base64
    • max_bytes (opcional): bytes brutos máximos a leer (predeterminado 1 MiB, límite estricto 8 MiB)
  • search_files - Busca recursivamente archivos y carpetas por nombre
    • path (obligatorio): directorio de búsqueda
    • pattern (obligatorio): subcadena del nombre sin distinción de mayúsculas (p. ej., invoice, .pdf). Los comodines no son especiales: DSM coincide report y *report* de forma idéntica.
  • create_file - Crea nuevos archivos con contenido
    • path (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) o base64 estricto; el contenido decodificado está limitado a 8 MiB
  • create_directory - Crea nuevos directorios
    • folder_path (obligatorio): ruta del directorio principal que comienza con /
    • name (obligatorio): nombre del nuevo directorio
    • force_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 directorios
    • path (obligatorio): ruta actual del archivo
    • new_name (obligatorio): nuevo nombre de archivo
  • move_file - Mueve archivos a una nueva ubicación
    • source_path (obligatorio): ruta del archivo de origen
    • destination_path (obligatorio): ruta de destino
    • overwrite (opcional): sobrescribir archivos existentes
  • copy_file - Copia un archivo normal dentro del NAS sin enviar sus bytes a través del cliente MCP
    • source_path (obligatorio): ruta del archivo de origen
    • destination_folder (obligatorio): directorio de destino existente; se conserva el nombre del archivo
    • overwrite (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 Station
  • ds_list_tasks - Lista todas las tareas de descarga con estado
    • offset (opcional): desplazamiento de paginación
    • limit (opcional): máximo de tareas a devolver
  • ds_create_task - Crea una nueva tarea de descarga
    • uri (obligatorio): URL de descarga o enlace magnet
    • destination (opcional): ruta de la carpeta de descarga
  • ds_pause_tasks - Pausa tareas de descarga
    • task_ids (obligatorio): matriz de ID de tareas
  • ds_resume_tasks - Reanuda tareas pausadas
    • task_ids (obligatorio): matriz de ID de tareas
  • ds_delete_tasks - Elimina tareas de descarga
    • task_ids (obligatorio): matriz de ID de tareas
    • force_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, temperatura
  • synology_utilization - Obtiene utilización en tiempo real de CPU, memoria, swap y E/S de disco
  • synology_disk_health - Lista todos los discos físicos con estado SMART, modelo, temperatura, tamaño
  • synology_disk_smart - Obtiene atributos SMART detallados para un disco específico
  • synology_volume_status - Lista todos los volúmenes con estado, tamaño, uso, tipo de sistema de archivos
  • synology_storage_pool - Lista grupos RAID/almacenamiento con nivel, estado, discos miembros
  • synology_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, usa synology_target_list: DSM no informa asignaciones en el lado del LUN.
  • synology_lun_get - Obtiene detalles de un solo LUN iSCSI
    • name (obligatorio): nombre del LUN o UUID de la salida de synology_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 su uuid y lun_id
    • name, location (p. ej., /volume2), size (en bytes) son obligatorios
    • type (opcional): thin (predeterminado, DSM BLUN), advanced, file, o un nombre de tipo DSM sin procesar. Ten en cuenta que thin y THIN son diferentes: las minúsculas son el alias amigable para BLUN, 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 contiene
    • uuid y confirm: true son obligatorios
  • synology_target_list - Lista los objetivos con IQN, tipo de autenticación y los LUN asignados a cada uno
  • synology_target_get - Obtiene un objetivo por target_id
  • synology_target_create - Crea un objetivo; devuelve su target_id
    • name es obligatorio; iqn tiene como predeterminado iqn.2000-01.com.synology:<name>
    • chap_user + chap_password habilitan 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ía
  • synology_services - Lista los paquetes instalados y su estado de ejecución
  • synology_system_log - Obtiene las entradas recientes del registro del sistema
  • synology_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 Manager
    • offset (opcional): Desplazamiento de paginación
    • limit (opcional): Máximo de contenedores a devolver
    • container_type (opcional): Filtro de contenedores (predeterminado: all)
  • synology_container_health_summary - Resume el estado del contenedor, salud, recuentos de reinicios e imágenes
  • synology_container_disk_usage - Muestra el resumen de uso de disco de solo lectura disponible a través de las API de Container Manager
  • synology_container_get - Obtiene un contenedor de Container Manager
    • name (obligatorio): Nombre del contenedor
  • synology_container_start - Inicia un contenedor de Container Manager
    • name (obligatorio): Nombre del contenedor
  • synology_container_stop - Detiene un contenedor de Container Manager
    • name (obligatorio): Nombre del contenedor
  • synology_container_restart - Reinicia un contenedor de Container Manager
    • name (obligatorio): Nombre del contenedor
  • synology_container_delete - Elimina un contenedor de Container Manager
    • name (obligatorio): Nombre del contenedor
    • force (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 Manager
    • name (obligatorio): Nombre del contenedor
    • since (opcional): Hora de inicio/filtro de registros
    • offset (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 Manager
    • name (obligatorio): Nombre del contenedor
  • synology_container_project_list - Lista los proyectos de Container Manager
  • synology_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 Manager
    • name (obligatorio): Nombre del proyecto
    • share_path (obligatorio): Ruta de la carpeta del proyecto en el NAS
    • content (obligatorio): Contenido YAML de Docker Compose
    • enable_service_portal (opcional): Habilitar el portal de servicios de Synology (predeterminado: false)
    • service_portal_name (opcional): Nombre del portal de servicios
    • service_portal_port (opcional): Puerto del portal de servicios
    • service_portal_protocol (opcional): Protocolo del portal de servicios (predeterminado: http)
    • Guarda la definición de Compose; llama a synology_container_project_build para materializarla.
  • synology_container_project_update - Actualiza un proyecto de Container Manager
    • name (obligatorio): Nombre del proyecto
    • content (obligatorio): Contenido YAML de Docker Compose
    • enable_service_portal (opcional): Habilitar el portal de servicios de Synology
    • service_portal_name (opcional): Nombre del portal de servicios
    • service_portal_port (opcional): Puerto del portal de servicios
    • service_portal_protocol (opcional): Protocolo del portal de servicios
  • synology_container_project_start - Inicia un proyecto de Container Manager
    • name (obligatorio): Nombre del proyecto
  • synology_container_project_stop - Detiene un proyecto de Container Manager
    • name (obligatorio): Nombre del proyecto
  • synology_container_project_restart - Reinicia un proyecto de Container Manager
    • name (obligatorio): Nombre del proyecto
  • synology_container_project_build - Materializa o reconstruye un proyecto guardado de Container Manager
    • name (obligatorio): Nombre del proyecto
  • synology_container_project_clean - Limpia un proyecto de Container Manager
    • name (obligatorio): Nombre del proyecto
  • synology_container_project_delete - Elimina un proyecto de Container Manager
    • name (obligatorio): Nombre del proyecto
  • synology_container_image_list - Lista las imágenes de Container Manager
    • offset (opcional): Desplazamiento de paginación
    • limit (opcional): Máximo de imágenes a devolver
    • show_dsm (opcional): Incluir imágenes de DSM (predeterminado: false)
  • synology_container_image_get - Obtiene una imagen de Container Manager
    • name (obligatorio): Nombre del repositorio de la imagen
    • tag (opcional): Etiqueta de la imagen (predeterminado: latest)
  • synology_container_image_delete - Elimina una imagen de Container Manager
    • name (obligatorio): Nombre del repositorio de la imagen
    • tag (opcional): Etiqueta de la imagen (predeterminado: latest)
  • synology_container_image_prune - Elimina imágenes no utilizadas por ningún contenedor
    • synology_container_image_prune_preview proporciona 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 Manager
    • repository (obligatorio): Nombre del repositorio de la imagen
    • tag (opcional): Etiqueta de la imagen (predeterminado: latest)
  • synology_container_registry_list - Lista los registros de Container Manager
  • synology_container_registry_search - Busca en los registros de Container Manager
    • query (obligatorio): Consulta de búsqueda de imágenes
    • offset (opcional): Desplazamiento de paginación
    • limit (opcional): Máximo de resultados a devolver
  • synology_container_registry_tags - Lista las etiquetas de una imagen de registro
    • repository (obligatorio): Nombre del repositorio de la imagen
    • offset (opcional): Desplazamiento de paginación
    • limit (opcional): Máximo de etiquetas a devolver
  • synology_container_registry_download - Descarga una imagen de registro
    • repository (obligatorio): Nombre del repositorio de la imagen
    • tag (opcional): Etiqueta de la imagen (predeterminado: latest)
  • synology_container_network_list - Lista las redes de Container Manager
  • synology_container_network_get - Obtiene una red de Container Manager
    • name (obligatorio): Nombre de la red
  • synology_container_network_create - Crea una red de Container Manager
    • name (obligatorio): Nombre de la red
    • driver (opcional): Controlador de red (predeterminado: bridge)
    • subnet (opcional): CIDR de subred
    • gateway (opcional): IP de puerta de enlace
    • ip_range (opcional): Rango de IP asignable CIDR
    • enable_ipv6 (opcional): Habilitar IPv6 (predeterminado: false)
  • synology_container_network_delete - Elimina una red de Container Manager
    • name (obligatorio): Nombre de la red

📦 Gestión de NFS

  • synology_nfs_status - Obtiene el estado y la configuración del servicio NFS
  • synology_nfs_enable - Habilita o deshabilita el servicio NFS
  • synology_nfs_list_shares - Lista todas las carpetas compartidas con sus permisos NFS
  • synology_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) o device_id (persistente). La guía anterior de "sin 2FA" ya no es necesaria.

Uso de settings.json (Recomendado)

VariableObligatoriaPredeterminadoDescripción
SYNOLOGY_URLSí*-URL base del NAS (p. ej., http://192.168.1.100:5000)
SYNOLOGY_USERNAMESí*-Nombre de usuario para autenticación
SYNOLOGY_PASSWORDSí*-Contraseña para autenticación
AUTO_LOGINNotrueInicio de sesión automático al iniciar el servidor
VERIFY_SSLNofalseVerificar certificados SSL
DEBUGNofalseHabilitar registro de depuración
ENABLE_XIAOZHINofalseHabilitar puente WebSocket de Xiaozhi
XIAOZHI_TOKENSolo Xiaozhi-Token de autenticación para Xiaozhi
XIAOZHI_MCP_ENDPOINTNowss://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:

CampoObligatorioDescripción
hostSí*Nombre de host o dirección IP del NAS
portNoPuerto de la API (predeterminado: 5000 para HTTP, 5001 para HTTPS)
urlSí*URL base completa (p. ej., https://nas.example.com); tiene prioridad sobre host/port — úsalo para un NAS detrás de un proxy inverso
usernameSíNombre de usuario del NAS
passwordSíContraseña del NAS
otp_codeNoCódigo 2FA de 6 dígitos de un solo uso (solo en el primer inicio de sesión, luego elimínalo)
device_idNoToken de dispositivo de confianza de larga duración de DSM (did); omite OTP en todos los futuros inicios de sesión
noteNoDescripció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/port siempre agrega un puerto y deriva el esquema de él, por lo que no puede expresar https://nas.example.com en el puerto 443 predeterminado — establece url directamente para configuraciones con proxy inverso
  • Permisos de archivo: se requiere chmod 600 ~/.config/synology-mcp/settings.json por 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\SYSTEM y BUILTIN\Administrators. Cualquier concesión heredada de Everyone / BUILTIN\Users / Authenticated Users falla 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 cargar settings.json. Los operadores que aceptan el riesgo de un archivo no verificado pueden volver a activarlo estableciendo SYNOLOGY_MCP_ALLOW_UNVERIFIED_WINDOWS_ACL=true.

    • El servidor resuelve el archivo mediante XDG_CONFIG_HOME (predeterminado Path.home() / ".config"), por lo que en Windows se encuentra en %USERPROFILE%\.config\synology-mcp\settings.json a menos que se establezca XDG_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:g es 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 false para 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=false deshabilita 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 true por conveniencia con settings.json
  • Las credenciales se almacenan de forma segura en ~/.config/synology-mcp/settings.json con permisos 0600
  • Si prefieres el inicio de sesión manual, establece AUTO_LOGIN=false y usa la herramienta synology_login

Cuentas 2FA / OTP (opcional):

El servidor MCP admite cuentas DSM con 2FA habilitado. Hay dos formas de usarlo:

  1. 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 en settings.json (abajo) para omitir OTP en futuros reinicios del proceso.

  2. 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/o device_id (de larga duración, continuo) por NAS en settings.json:

    {
      "synology": {
        "nas1": {
          "host": "192.168.1.100", "port": 5001,
          "username": "alice", "password": "…",
          "otp_code": "123456",
          "note": "primary — 2FA enabled"
        }
      }
    }
    

    Flujo de trabajo:

    1. Establece otp_code a un código fresco de 6 dígitos de tu autenticador e inicia el servidor.
    2. 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>.
    3. Pégalo en device_id y elimina otp_code.
    4. 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_id está presente, tiene prioridad sobre otp_code (ruta de dispositivo de confianza). Los usuarios de .env heredado pueden establecer la variable de entorno de un solo uso SYNOLOGY_OTP_CODE; para device_id persistente, migra a settings.json (el token opaco largo no cabe limpiamente en una variable de entorno).

📖 Ejemplos de uso

📁 Operaciones de archivos

✅ Crear archivos y directorios

File Creation

// 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

File Deletion

// 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

Download Sample

// Create download task
{
  "uri": "https://example.com/file.zip",
  "destination": "/volume1/downloads"
}

// Pause tasks
{
  "task_ids": ["dbid_123", "dbid_456"]
}

🦦 Resultados de descarga

Download Result

✨ Características

  • ✅ Punto de entrada unificado - Un solo main.py admite 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! 🚀