Skip to main content
Glama
01men

synology-filestation-mcp

by 01men

synology-filestation-mcp

基于 Synology File Station Web API 封装的 MCP (Model Context Protocol) 服务,让 AI Agent 可以直接管理群晖 NAS 上的文件:浏览目录、搜索、上传下载、创建/重命名/复制/移动/删除、压缩/解压等。

支持两种运行模式:

  • stdio 本地模式src/index.js):在个人电脑上跑,凭据放本地环境变量

  • Streamable HTTP 远程模式src/http.js):集中部署到服务器,多人共用,各自的 NAS 凭据通过请求头传入

环境要求

  • Node.js >= 18(开发使用 Node 24 验证;低版本 glibc 服务器可用 unofficial-builds 的 glibc-217 构建)

  • DSM 7.x(已在 DSM 7.2 上实测通过)

安装

npm install

模式一:stdio 本地模式

通过环境变量提供 NAS 连接信息(也可复制 .env.example.env 填写,服务启动时自动加载):

变量

说明

SYNOLOGY_HOST

DSM 地址,如 http://192.168.1.1:5000(不带末尾斜杠)

SYNOLOGY_USER

DSM 账号

SYNOLOGY_PASSWORD

DSM 密码

SYNOLOGY_DOWNLOAD_DIR

可选,fs_download 默认本地保存目录

以 Claude Desktop 为例,配置 claude_desktop_config.json

{
  "mcpServers": {
    "synology-filestation": {
      "command": "node",
      "args": ["D:/path/to/synology-filestation-mcp/src/index.js"],
      "env": {
        "SYNOLOGY_HOST": "http://192.168.1.1:5000",
        "SYNOLOGY_USER": "your_username",
        "SYNOLOGY_PASSWORD": "your_password"
      }
    }
  }
}

模式二:HTTP 远程模式(多人共用)

服务端启动:

# .env 或环境变量
SYNOLOGY_HOST=http://192.168.1.1:5000   # 默认 NAS 地址(客户端可用 X-NAS-Host 覆盖)
PORT=3000
MCP_AUTH_TOKEN=<随机令牌>                # 设置后客户端必须带 Bearer token

npm run start:http

特性:

  • 多用户:每个 MCP 会话独立持有 NAS 登录态(sid 池),互不串号

  • 多 NAS 路由:客户端通过请求头 X-NAS-IP 指定目标 NAS 的 IP(或设备名),服务端在注册表 nas-registry.json(路径可用 NAS_REGISTRY_FILE 覆盖,格式见 nas-registry.example.json,含各设备的地址与凭据,已加入 .gitignore)中查找并路由;查不到返回 400 并列出可用设备。优先级:X-NAS-IP 注册表 > X-NAS-Host 头 > 服务端 SYNOLOGY_HOST 默认

  • 凭据传递:客户端通过请求头提供自己的 NAS 账号 X-NAS-User / X-NAS-Password,可选 X-NAS-Host 覆盖服务端默认;缺省回落到注册表条目或服务端环境变量(支持服务端统一托管账号)

  • 鉴权/mcp 请求必须带 Authorization: Bearer <token>;有效令牌 = 环境变量 MCP_AUTH_TOKEN(内置兜底)∪ nas-tokens.json 中的令牌(管理界面维护)。两者都未配置时不鉴权

  • 令牌管理界面:设置 ADMIN_TOKEN 后,浏览器访问 http://<服务器>:3000/admin,输入 ADMIN_TOKEN 登录,可为成员/部门生成或删除访问令牌(持久化在 nas-tokens.json,路径可用 NAS_TOKENS_FILE 覆盖,已加入 .gitignore)。生成令牌时可选择绑定 NAS:绑定后持该令牌的会话强制路由到这台 NAS(忽略客户端 X-NAS-IP),实现部门级隔离;不绑定则成员可用 X-NAS-IP 自选

  • 会话管理:空闲 30 分钟自动清理并登出 NAS(SESSION_IDLE_TTL_MS 可调)

  • 健康检查GET /health(含 nas_devices 已注册设备清单)

客户端配置(支持远程 MCP 的客户端,url 方式):

{
  "mcpServers": {
    "synology-filestation": {
      "url": "http://<部署服务器>:3000/mcp",
      "headers": {
        "Authorization": "Bearer <MCP_AUTH_TOKEN>",
        "X-NAS-IP": "192.168.0.196"
      }
    }
  }
}

不配 X-NAS-IP 时也可继续用各自账号直连(保持向后兼容):

{
  "mcpServers": {
    "synology-filestation": {
      "url": "http://<部署服务器>:3000/mcp",
      "headers": {
        "Authorization": "Bearer <MCP_AUTH_TOKEN>",
        "X-NAS-User": "同事自己的 NAS 账号",
        "X-NAS-Password": "同事自己的 NAS 密码"
      }
    }
  }
}

systemd 部署示例:

[Unit]
Description=Synology FileStation MCP (HTTP)
After=network.target

[Service]
WorkingDirectory=/opt/synology-filestation-mcp
ExecStart=/usr/bin/node src/http.js
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

安全提示:生产环境建议用 HTTPS(反向代理)终止 TLS,避免 NAS 凭据在请求头中明文传输。

工具清单

工具

说明

底层 API

fs_list_shares

列出共享文件夹

SYNO.FileStation.List / list_share

fs_list

列出目录内容(支持分页、排序、通配符过滤)

SYNO.FileStation.List / list

fs_get_info

获取文件/目录详细信息

SYNO.FileStation.List / getinfo

fs_search

按模式搜索文件(自动轮询直到完成)

SYNO.FileStation.Search / start+list

fs_search_stop

停止搜索任务

SYNO.FileStation.Search / stop

fs_search_clean

清理所有搜索任务

SYNO.FileStation.Search / clean

fs_create_folder

创建文件夹

SYNO.FileStation.CreateFolder / create

fs_rename

重命名文件/文件夹

SYNO.FileStation.Rename / rename

fs_copy_move

复制/移动(异步任务,返回 taskid)

SYNO.FileStation.CopyMove / start

fs_task_status

查询后台任务进度

SYNO.FileStation.BackgroundTask / list

fs_delete

删除(异步任务,不可恢复)

SYNO.FileStation.Delete / start

fs_download

下载 NAS 文件到本机目录

SYNO.FileStation.Download / download

fs_upload

上传本机文件到 NAS

SYNO.FileStation.Upload / upload

fs_compress

NAS 端压缩为 zip/7z(异步任务)

SYNO.FileStation.Compress / start

fs_extract

NAS 端解压缩(异步任务,目标目录需已存在)

SYNO.FileStation.Extract / start

测试

SYNOLOGY_HOST=http://192.168.0.196:5000 SYNOLOGY_USER=xxx SYNOLOGY_PASSWORD=xxx npm test

冒烟测试会对 NAS 执行完整链路:登录 → 列出共享文件夹 → 建目录 → 上传 → 列表 → 查信息 → 重命名 → 复制 → 搜索 → 下载校验内容 → 删除清理 → 登出。测试会在某个可写共享文件夹下创建 mcp-smoke-test 临时目录,结束后自动删除。

另有扩展能力测试 test/extended.mjsnode test/extended.mjs,同样读取环境变量):覆盖 23 种文件格式(文档/图片/视频/音频/压缩包/数据库/虚拟机镜像)的上传下载逐字节校验、批量复制/移动/删除、NAS 端解压、回收站落点检查,以及权限与安全能力边界探测。

实现说明(DSM 7.x 兼容性)

  • 启动时先调 SYNO.API.Info 发现各 API 的 path 与版本,登录走 SYNO.API.Auth(format=sid)。

  • SYNO.FileStation.List v2 的 additional 参数要求 JSON 数组格式(如 ["size","time"]),逗号分隔字符串会被静默忽略。

  • 文件信息查询使用 SYNO.FileStation.List / getinfoSYNO.FileStation.Info / get 返回的是 File Station 服务器配置,不是文件信息)。

  • 上传使用 API version 2:实测 v3 下 overwrite 参数不生效,同名文件返回 414。上传时 sid 通过表单字段和 Cookie: id=<sid> 双通道传递。

  • 复制/移动/删除为异步任务;DSM 7.x 的 SYNO.FileStation.BackgroundTask 只有 list 方法(无 status),按 taskid 过滤查询进度。

  • 搜索为异步任务,工具内部轮询 list 直至 finished

  • SYNO.FileStation.Extract 的目标目录必须预先存在,否则返回 408(No such file or directory)。

  • SYNO.FileStation.Compress 依赖账号在 DSM 中的应用权限;若返回 105(session does not have permission),需在 DSM 控制面板为账号授予相应权限。

能力边界(不属于 File Station API 范围)

以下能力在官方 File Station API 中不存在,本 MCP 无法提供:

  • ACL 权限管理:属 DSM 控制面板功能(SYNO.Core.* 私有接口,非公开 File Station API)。

  • 共享文件夹 AES 加密:属 DSM 存储管理功能(创建/挂载加密共享文件夹)。

  • 防篡改(只读/不可删除标记):File Station API 无设置入口;可通过共享文件夹只读挂载间接实现。

  • 网络回收站:删除行为自动遵循各共享文件夹的回收站设置(开启后删除的文件进入 <share>/#recycle),API 无需也无法单独控制。

目录结构

src/
  index.js    stdio 入口(本地模式)
  http.js     HTTP 入口(远程模式,Streamable HTTP + 多用户会话池 + NASIP 路由)
  admin.js    Token 管理界面与 API(/admin,需 ADMIN_TOKEN)
  tokens.js   MCP 访问令牌存储(nas-tokens.json 持久化)
  server.js   共享的 MCP Server 构建(注册全部工具)
  env.js      .env 加载
  client.js   Synology API 客户端:API 发现、认证、请求封装、错误码映射
  tools/      每个 File Station API 一个工具模块
test/
  smoke.mjs      对真实 NAS 的全链路冒烟测试(stdio 层逻辑)
  http-smoke.mjs HTTP 模式自测(鉴权、会话、工具调用、会话关闭)
  extended.mjs   扩展能力测试(多格式、批量、解压、回收站)

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/01men/synology-filestation-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server