内容
# dsmctl
`dsmctl` 是一个用于管理一个或多个 Synology DSM 系统的 Go 客户端。一个存储库生成了三个前端,每个前端都由同一个类型的 DSM WebAPI 客户端支持:
- `dsmctl`:管理员的命令行界面。
- `dsmctl-mcp`: 一个用于 AI 客户端的标准输入输出 MCP 服务器。
- `dsmctl-gateway`: 一个可移植的 amd64 流式 HTTP MCP 网关;其当前开发模式为只读。
第一个里程碑实现了一个完整的连接切片:配置多个 NAS 配置文件,使用密码和 DSM 双因素身份验证进行身份验证,维护独立的会话,并读取基本系统信息。管理模块现在涵盖存储和 SAN 库存,受保护的存储池,卷和 SAN 生命周期,本地用户/组/共享管理,有效访问解释,一个专注的只读控制面板时间模块,受保护的全局 SMB/NFS 文件服务,以及通过相同的 CLI/MCP/应用程序堆栈的包中心库存,设置和受保护的包生命周期。已安装包提供的功能通过包范围的操作进行管理,这些操作在每个命令之前都会重新检查已安装的包版本;只读 Synology Drive 管理员模块是第一个使用者。
## 架构
```text
CLI ---------+
+--> 应用程序 --> 运行时/会话管理器 --> Synology 客户端外观
MCP 服务器 --+ | |
+--> 操作系统凭证存储 +--> 兼容性路由器
|
+--> 操作变体 --> WebAPI 执行器 --> DSM
```
CLI 和 MCP 永远不会构造原始的 DSM 请求或选择 DSM 版本。每个操作都会从 NAS 广告的 API 和版本中选择一个后端,并在行为实际不同的情况下使用狭义的 DSM 版本覆盖。请参阅[兼容性架构](docs/compatibility.md)。
计划中的工作和多代理协调位于[规格索引](spec/README.md)。规格描述了未完成的工作;`docs/` 描述了已实现的行为。
聚焦的控制面板模块约定在[控制面板指南](docs/control-panel.md)中记录。
## 构建
需要 Go 1.25 或更高版本。
```console
go test ./...
go build -o bin/dsmctl ./cmd/dsmctl
go build -o bin/dsmctl-mcp ./cmd/dsmctl-mcp
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/dsmctl-gateway ./cmd/dsmctl-gateway
```
在 Windows 上,使用 `bin/dsmctl.exe` 和 `bin/dsmctl-mcp.exe`。
## 快速入门
添加一个 NAS 配置文件:
```console
dsmctl nas add office --url https://nas.example.com:5001 --username automation --default
```
交互式身份验证:
```console
dsmctl auth login --nas office
```
`auth login` 在您的网页浏览器中打开 NAS 的登录页面;密码 - 以及任何双因素,通行码或批准登录步骤 - 仅在那里输入,绝不会通过 dsmctl 传递。生成的 DSM 会话(SID,SynoToken 及其续期密钥)存储在操作系统的凭证存储中,而不是存储在 `config.json` 中,并被后续的 CLI 和 MCP 进程重用。
检查或删除存储的会话而不泄露任何机密值:
```console
dsmctl auth status
dsmctl auth logout --nas office
```
`auth status` 完全离线。`auth logout` 签出:它要求 DSM 撤销会话(尽力而为;无法访问的 NAS 只会跳过撤销),然后删除存储的副本。`nas remove` 也会清理删除的配置文件的存储会话,除非传递 `--keep-credentials`。详细信息和跨进程注意事项在[凭证生命周期指南](docs/credentials.md)中。
读取系统信息:
```console
dsmctl system info
dsmctl system info --nas office --json
dsmctl nas capabilities --nas office
dsmctl storage capabilities --nas office
dsmctl storage inventory --nas office
dsmctl storage inventory --nas office --json
dsmctl san capabilities --nas office
dsmctl san inventory --nas office --json
dsmctl san plan --nas office --file lun-change.json --output lun-change.plan.json
dsmctl san apply --file lun-change.plan.json --approve <plan-sha256>
dsmctl control-panel time state --nas office --json
dsmctl control-panel file-services capabilities --nas office
dsmctl control-panel file-services smb state --nas office --json
dsmctl control-panel file-services nfs state --nas office --json
dsmctl account capabilities --nas office
dsmctl account inventory --nas office --json
dsmctl account inventory --nas office --memberships --json
dsmctl account inventory --nas office --quotas --application-privileges --principal-type user --principal automation --json
dsmctl share capabilities --nas office
dsmctl share inventory --nas office
dsmctl share inventory --nas office --include-permissions --json
dsmctl access explain --nas office --principal-type user --principal automation --resource-type share --resource team-data --json
dsmctl log capabilities --nas office
dsmctl log list --nas office
dsmctl log list --nas office --type connection --limit 50
dsmctl log list --nas office --from "2026-07-01" --to "2026-07-08"
dsmctl log list --nas office --keyword cache --level error --json
dsmctl package capabilities --nas office
dsmctl package inventory --nas office --json
dsmctl package settings --nas office --json
dsmctl resource-monitor capabilities --nas office
dsmctl resource-monitor current --nas office --json
dsmctl resource-monitor history --nas office --period week --dimension cpu --dimension memory
dsmctl resource-monitor setting --nas office
dsmctl drive admin capabilities --nas office
dsmctl drive admin status --nas office
dsmctl drive admin connections --nas office --json
dsmctl drive admin team-folders --nas office
dsmctl drive admin log list --nas office --username alice --limit 50
```
帐户和共享文件夹写入使用两步计划/应用合同。将所需更改放入 JSON 中,创建绑定到当前 DSM 资源 ID/状态的计划,审查它,然后使用其哈希应用确切的计划:
```console
dsmctl account plan --nas office --file create-user.json --output create-user.plan.json
dsmctl account apply --file create-user.plan.json --approve <hash-from-plan>
dsmctl share plan --nas office --file create-share.json --output create-share.plan.json
dsmctl share apply --file create-share.plan.json --approve <hash-from-plan>
dsmctl control-panel file-services plan --nas office --file smb-change.json --output smb-change.plan.json
dsmctl control-panel file-services apply --file smb-change.plan.json --approve <hash-from-plan>
dsmctl control-panel time plan --nas office --file time-change.json --output time-change.plan.json
dsmctl control-panel time apply --file time-change.plan.json --approve <hash-from-plan>
dsmctl package plan --nas office --file package-change.json --output package-change.plan.json
dsmctl package apply --file package-change.plan.json --approve <hash-from-plan>
dsmctl resource-monitor plan-recording --nas office --enable --output recording.plan.json
dsmctl resource-monitor apply-recording --file recording.plan.json --approve <hash-from-plan>
```
包中心更改使用相同的计划/应用合同:一个生命周期操作(`start`,`stop` 或 `uninstall`)在一个已安装的包上,或对自动更新策略的设置更改。发布者信任级别是只读的(无 DSM 写入端点)。请参阅[包中心指南](docs/package-center.md)。
用户密码从不会包含在请求或计划中。用户创建/更改引用了一个应用时间环境变量,例如 `"credential_ref":"env:DSMCTL_NEW_USER_PASSWORD"`。请求格式和示例在[帐户和共享文件夹管理](docs/account-share-management.md)中。
管理多个 NAS:
```console
dsmctl nas add lab --url https://192.168.10.20:5001 --username automation
dsmctl nas list
dsmctl auth login --nas lab
dsmctl system info --nas lab
dsmctl nas use lab
```
默认配置路径是平台用户配置目录,例如 Windows 上的 `%AppData%\dsmctl\config.json`。使用 `--config` 或 `DSMCTL_CONFIG` 重写它。
示例配置(无机密值):
```json
{
"default_nas": "office",
"nas": {
"office": {
"url": "https://nas.example.com:5001",
"username": "automation",
"password_env": "DSMCTL_PASSWORD_OFFICE",
"timeout_seconds": 30
}
}
}
```
`password_env` 仍然作为非交互式密码备用方案用于自动化;只有在配置文件中没有存储 Web 登录会话时,才会使用它:
```powershell
$env:DSMCTL_PASSWORD_OFFICE = "your-password"
```
双因素身份验证不需要特殊处理:挑战在 `dsmctl auth login` 期间在浏览器中完成,存储的会话是后续进程重用的。
仅在测试 NAS 上使用 `--insecure-skip-tls-verify`,该 NAS 的证书无法信任。默认启用 TLS 验证。
## MCP 服务器
运行_stdio服务器:
```console
dsmctl-mcp --config C:\path\to\config.json
```
可移植的HTTP开发者网关、仅限环回的Compose项目及其只读安全边界在[网关指南](docs/gateway.md)中有详细说明。
可用工具:
- `list_nas`:列出安全配置文件元数据;永远不会返回机密。
- `get_auth_status`:报告每个NAS的凭证存在情况、密码环境变量名称和设置状态,以及此进程的会话状态;完全离线且永远不会返回机密值。
- `get_system_info`:通过身份验证到选定的配置文件并返回规范化的DSM系统信息。
- `get_capabilities`:报告发现的API、DSM版本、兼容性怪癖和为每个操作选择的后端。
- `get_storage_capabilities`:报告当前为选定的NAS和选定的DSM后端公开的存储操作。
- `get_storage_state`:在不更改NAS的情况下,返回规范化的磁盘、存储池、RAID、卷、SSD缓存、容量和健康状态。
- `plan_storage_change`:验证存储池、卷或SSD缓存意图并返回一个绑定到拓扑、容量和安全状态的批准计划,而不修改DSM。
- `apply_storage_plan`:应用已批准的、未更改的存储池、卷或SSD缓存计划,并验证后置条件。
- `get_san_capabilities`:报告SAN管理器库存和受保护的变异支持,以及选定的后端。
- `get_san_state`:使用批量读取返回规范化的iSCSI目标、LUN和它们的稳定ID映射图。
- `plan_san_change`:验证目标、LUN或映射意图并返回一个绑定到状态的批准计划,而不修改DSM。
- `apply_san_plan`:应用已批准的、未更改的SAN计划,并验证稳定ID和映射图后置条件。
- `get_control_panel_time_capabilities`:报告读和受保护的设置支持,以及用于聚焦时间和NTP模块的选定后端。
- `get_control_panel_time_state`:返回规范化的时区、显示格式、同步模式和NTP服务器。
- `plan_control_panel_time_change`:验证补丁时间和NTP请求并返回一个绑定到完整状态的批准计划;手动模式和时钟更改被拒绝。
- `apply_control_panel_time_plan`:应用已批准的、未更改的时间计划,并验证配置而不声称NTP可达性。
- `get_file_service_capabilities`:报告独立的SMB/NFS读和受保护的设置后端。
- `get_smb_state`:返回规范化的全局SMB服务、工作组、协议、加密和签名设置。
- `get_nfs_state`:返回规范化的全局NFS服务、协议和NFSv4域设置。
- `plan_file_service_change`:验证补丁SMB/NFS请求并返回一个绑定到完整状态的批准计划。
- `apply_file_service_plan`:应用已批准的、未更改的SMB/NFS计划,并验证后置条件。
- `get_account_capabilities`:报告本地用户、组、成员资格、配额和应用程序特权操作,以及它们选定的DSM后端。
- `get_account_state`:返回规范化的本地用户和组;成员资格、配额和显式应用程序特权扩展是可选的,并且可能过滤到一个主体。
- `plan_account_change`:验证用户、组、成员资格、配额或应用程序特权更改并返回一个绑定到当前状态的批准计划,而不修改DSM。
- `apply_account_plan`:应用已批准的、未更改的帐户计划,并验证后置条件。
- `get_share_capabilities`:报告共享文件夹和权限能力,以及它们选定的DSM后端。
- `get_share_state`:返回规范化的共享文件夹;仅在需要用户/组权限矩阵时设置`include_permissions`。
- `plan_share_change`:验证共享文件夹或权限更改并返回一个批准计划,而不修改DSM。
- `apply_share_plan`:应用已批准的、未更改的共享文件夹计划,并验证后置条件。
- `explain_effective_access`:使用直接/组证据和保守的不确定结果解释一个主体的共享或应用程序访问。
- `get_log_capabilities`:报告DSM系统日志读取是否可用以及选定的后端。
- `get_logs`:读取规范化的DSM系统日志条目,可选的关键字、日志类型、严重性和分页过滤器;永远不会修改或清除日志。
- `get_package_capabilities`:报告支持的Package Center库存、设置和生命周期操作,以及选定的DSM后端;安装和更新报告不支持。
- `get_package_state`:返回规范化的已安装软件包库存,运行状态和启动/停止/卸载资格,而不更改软件包。
- `get_package_settings`:返回规范化的全局Package Center设置(发布者信任级别和自动更新策略);只读。
- `get_drive_admin_capabilities`:报告支持的Drive Admin操作、选定的后端和已安装的SynologyDrive软件包版本/运行状态。
- `get_drive_admin_status`:返回Drive服务状态,带有已安装软件包的证据;只读。
- `get_drive_admin_connections`:列出活动的Drive客户端连接;只读。
- `get_drive_admin_team_folders`:从管理员的角度列出Drive团队文件夹;只读。
- `get_drive_admin_logs`:读取Drive服务器日志,带有关键字/用户名/目标/时间范围过滤器;只读。
- `plan_package_change`:验证启动/停止/卸载生命周期操作或自动更新设置更改并返回一个绑定到状态的批准计划,而不修改DSM;安装、更新和信任级别更改被拒绝。
- `apply_package_plan`:应用已批准的、未更改的Package Center计划(生命周期或设置)并验证终端软件包状态或设置后置条件。
存储池创建、添加磁盘扩展和删除,以及卷创建、扩展和删除,需要独立选择的后端和受保护的计划/应用;存储池RAID迁移保持故障关闭。SSD缓存创建和删除(只读或读写)也是受保护的计划/应用,针对`cache`资源;SSD缓存扩展和只读/读写转换在DSM的flashcache API仅公开创建和删除时被建模但故障关闭。本地用户/组CRUD、成员资格、每个用户/组配额、显式应用程序访问、共享文件夹CRUD、规范化的`none`/`read`/`write`/`deny`共享权限和受保护的SAN目标/LUN/映射生命周期也仅通过计划/应用可用。SAN删除拒绝活动会话或映射,映射永远不会级联删除端点,并且LUN容量针对选定的后端卷进行检查。受保护的时间模块更改永远不会写入时钟值或切换到手动同步,并且NTP服务器在语法上进行验证而没有任何可达性声明。Package Center公开已安装的软件包库存、全局设置(发布者信任级别和自动更新策略)、受保护的自动更新设置更改和已安装软件包的受保护启动/停止/卸载;卸载因DSM报告为不可删除的软件包而被拒绝,并且启动/停止/卸载验证终端软件包状态。发布者信任级别是只读的(无DSM写入端点)。软件包从存储库安装和更新在建模但故障关闭,因为它们联系在线存储库,异步运行,并下载和运行远程代码。信任级别、测试通道和默认卷写入、在线目录浏览和每个软件包的应用程序特定设置也被推迟。 Drive Admin模块在此切片中是只读的(服务状态、连接、团队文件夹、日志);它从已安装的SynologyDrive软件包版本中选择操作,在每个命令之前重新检查该版本,并在Drive版本低于验证的3.0基线或软件包丢失时故障关闭。团队文件夹更改在建模但故障关闭。加密共享、WORM、自定义Windows ACL、IP特定应用程序规则和SAN快照/克隆仍然超出范围。
帐户扩展是可选的,因为DSM为每个主体公开配额和应用程序规则。对于大型系统,请使用`principal_type`和`principal`过滤`get_account_state`或帐户库存,而不是读取每个本地主体。成员资格扩展随本地组而不是用户缩放。
由于DSM按用户和组公开权限,因此权限扩展是可选的。`get_share_state {"include_permissions":true}`和匹配的CLI标志为每个本地用户和组执行额外的只读调用,然后按共享文件夹聚合结果。
MCP故意没有接受密码或OTP的工具。如果需要交互式身份验证,它会返回一个可行的错误,要求用户首先运行`dsmctl auth login --nas <name>`。
一个可选的实时烟雾测试验证实际_stdio进程边界:
```powershell
$env:DSMCTL_MCP_BINARY = (Resolve-Path .\bin\dsmctl-mcp.exe).Path
$env:DSMCTL_LIVE_NAS = "office"
go test ./integration -run TestMCPGetSystemInfoLive -v
```
## 安全模型
- 密码、OTP值、DSM设备ID、SID和SynoToken永远不会存储在配置文件中或由CLI/MCP显示模型返回。
- 帐户库存永远不会返回密码、哈希、恢复代码或其他身份验证材料。
- 用户创建/密码更新仅接受`env:NAME`引用;机密在应用时解析,并且在请求、计划、哈希、结果和日志中不存在。
- 每个帐户/共享变更在应用之前都会重新读取DSM状态。删除绑定到计划的UID/GID或共享文件夹UUID以及状态指纹。
- 内置的`admin`、`guest`、`root`、`administrators`、`users`、`http`、`home`和`homes`资源无法通过变更命令管理。
- 登录参数使用HTTPS POST表单,而不是URL查询参数。
- OTP值是短暂的,永远不会持久化。
- 网络登录会话(SID、SynoToken和续期密钥)使用Windows凭证管理器、macOS密钥链或Linux秘密服务;dsmctl不会添加自己的加密层,因为操作系统存储已经提供静态加密,在没有存储的主机上(无头Linux)它在不将机密写入磁盘的情况下故障关闭。
- 密码永远不会被dsmctl存储:网络登录将它们保存在浏览器中,可选的自动化回落读取登录时的环境变量。
- 凭证状态报告布尔值、元数据和环境变量名称;会话ID、令牌、密钥和密码值永远不会显示。
- `auth logout`和`nas remove`在删除存储的副本之前撤销DSM会话服务端(尽力而为,带有有限等待);签出的会话无法重放;当NAS无法访问时,本地副本仍然被删除,会话在其自己的过期时间后失效。
- 关闭进程永远不会使存储的网络登录会话失效;只有显式注销才会这样做。
- 每个NAS配置文件拥有一个单独的存储会话。
- DSM会话错误106和119在客户端使用密码登录时触发一次自动重新登录和重试;使用存储的网络登录会话的客户端则无需密码恢复 - 它重新读取存储(获取来自另一个进程的新`auth login`)或使用存储的Noise恢复密钥续期会话 - 并且在需要新的`auth login`时报告错误。
## 添加命令
通常,管理功能会添加:
1. 一个稳定的结果模型和`internal/synology/operations/<operation>`下的一个或多个变体。
2. 共享后端和仅版本特定覆盖的的能力匹配器。
3. `internal/application`下的用例和策略。
4. 薄CLI和MCP适配器。
原始的通用DSM调用不会作为MCP工具公开。变更操作在项目扩展到控制面板和SAN管理时使用受保护的计划/应用语义。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器