@xxxyz/dsh-mcp-manager 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 god2
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # dsh-mcp-manager
2
+
3
+ [English](README.md) · [中文](README.zh-CN.md)
4
+
5
+ ![dsh-mcp-manager MCP Manager settings page](show.png)
6
+
7
+ Durable MCP server manager for DeepSeek Harness (DSH) — a **composed loader plugin** (not a dynamic session plugin), so it survives DSH restarts and upgrades.
8
+
9
+ Built to the DSH plugin development standard (see the official docs: [第一个插件](https://deepseek-harness.github.io/deepseek-harness/develop/basic/), [开发一个工具](https://deepseek-harness.github.io/deepseek-harness/develop/basic/tool)):
10
+
11
+ - **object-form Cordis plugin** (`export default { name, inject, apply }`)
12
+ - required services declared in `inject` — the framework guarantees they are ready before `apply` runs, and reloads the plugin if one disappears (this is what keeps the plugin alive across DSH upgrades)
13
+ - agent-facing capabilities exposed as **registered model tools** via `ctx.tools.register(defineTool(...))`: `mcp_manager_list`, `mcp_manager_set_enabled`, `mcp_manager_restart`, `mcp_manager_add`
14
+ - UI-facing capability via a `webServer` exact route (`POST /dsh-mcp-manager/api`), consumed by the client half
15
+
16
+ Features:
17
+
18
+ - **Settings → MCP 管理** page (added by the client half)
19
+ - Host half manages `@deepseek-ai/dsh-mcp-client` rows in the real patch files:
20
+ - **项目级** → `~/.dsh/profiles/<profile>/cordis.patch.yml`
21
+ - **全局** → `~/.dsh/cordis.patch.yml`
22
+ - add / edit / enable / disable / restart / delete, live tool-count health, JSON export/import, per-file write lock
23
+
24
+ ## How it works
25
+
26
+ | Piece | File | Role |
27
+ |---|---|---|
28
+ | Host plugin source | `src/index.ts` | TypeScript source (the documented plugin shape); **build with `npm run build`** (tsc) |
29
+ | Host plugin (compiled) | `lib/index.js` (`main`) | Cordis object-form plugin: patch-file CRUD + 4 model tools + `webServer` exact route `/dsh-mcp-manager/api` (JSON `{op, args}` → `{ok, ...}`) |
30
+ | Client bundle | `lib/client.js` (`exports["./client"]` + `dsh.client`) | Browser module: registers the settings page; calls the host via `fetch('/dsh-mcp-manager/api')` |
31
+ | Loader row | added to the profile's `cordis.patch.yml` | composes the host entry; the client-modules service scans enabled entries and serves the client bundle |
32
+
33
+ The loader entry is the single composition point for both halves — no changes to any shipped DSH package. The package itself is **platform-neutral** (pure JS; path separators detected at runtime), so it works on Windows, macOS and Linux. Building (`npm run build`) requires the devDependencies (`typescript`, `@deepseek-ai/cordis`, `@deepseek-ai/dsh-tools`, `@types/node`); the shipped/installed package needs none of them.
34
+
35
+ ## Install (any platform)
36
+
37
+ **Quickest — one npx command (requires Node.js >= 18):**
38
+ ```bash
39
+ # from npm (recommended)
40
+ npx -y @xxxyz/dsh-mcp-manager
41
+
42
+ # or directly from GitHub (no npm account needed)
43
+ npx -y github:xxxyz/DeepSeekHarness-MCP-Manager
44
+ ```
45
+ All flags pass through: `npx -y @xxxyz/dsh-mcp-manager --dsh-home /path/.dsh --profile web --repair --port 3080`.
46
+
47
+ > npm package name: `@xxxyz/dsh-mcp-manager` (the bare name `dsh-mcp-manager` is taken on npm by an unrelated package). The deployed plugin name is still `dsh-mcp-manager` — npx is only the delivery channel; the installer copies the files to the same fixed locations below.
48
+
49
+ **Alternative — run the installer scripts from a source checkout** (all installers share one cross-platform logic file, `install.mjs`). Install steps:
50
+
51
+ 1. copy the package to `<dshHome>/local-packages/dsh-mcp-manager` (a true source kept outside `node_modules`, so DSH upgrades never touch it)
52
+ 2. copy it into `<dshHome>/profiles/node_modules/dsh-mcp-manager` (a plain copy on purpose — a symlink would make Node ESM resolve the plugin's realpath where `@deepseek-ai/dsh-tools` cannot be found)
53
+ 3. append the loader row to `profiles/<profile>/cordis.patch.yml` (idempotent; keeps the patch a valid top-level array)
54
+
55
+ **Windows (PowerShell):**
56
+ ```powershell
57
+ .\dsh-mcp-manager\install.ps1 # default: ~/.dsh, web profile
58
+ # or: .\install.ps1 -DshHome D:\path\.dsh -Profile web
59
+ ```
60
+
61
+ **macOS / Linux:**
62
+ ```bash
63
+ ./dsh-mcp-manager/install.sh # default: ~/.dsh, web profile
64
+ # or: ./install.sh --dsh-home /path/.dsh --profile web
65
+ ```
66
+
67
+ **Any platform (direct):**
68
+ ```bash
69
+ node dsh-mcp-manager/install.mjs [--dsh-home <path>] [--profile <name>] [--port <n>] [--repair] [--skip-patch]
70
+ ```
71
+
72
+ Then **restart DSH** and open **Settings → MCP 管理**. The four `mcp_manager_*` tools become callable by the model after that restart.
73
+
74
+ Uninstall (same three ways):
75
+ ```powershell
76
+ .\dsh-mcp-manager\uninstall.ps1 # or: ./uninstall.sh or: node uninstall.mjs [--dsh-home <path>] [--profile <name>]
77
+ ```
78
+ then restart DSH. Uninstall removes the deployed copy, the `local-packages` true source, and the loader row.
79
+
80
+ ## After a DSH upgrade: `--repair`
81
+
82
+ A DSH upgrade (or a broken HMR state) can leave the plugin's host half unloaded while the files are still in place. One command fixes it — re-copies the package from the source of record, bumps the loader row's `config.version` to force an HMR re-apply, then polls the API until it answers:
83
+
84
+ ```bash
85
+ node dsh-mcp-manager/install.mjs --repair # default ~/.dsh, web, port 3080
86
+ node dsh-mcp-manager/install.mjs --repair --port 3080
87
+ # PowerShell: .\install.ps1 -Repair -Port 3080 bash: ./install.sh --repair --port 3080
88
+ ```
89
+
90
+ `--repair` returns success only when `POST /dsh-mcp-manager/api` answers `{ok:true}` again. If the API still does not answer after 30s, restart DSH once (the loader always re-imports fresh at boot).
91
+
92
+ ## API reference
93
+
94
+ All ops are `POST /dsh-mcp-manager/api` with `{"op": "<op>", "args": {...}}`, same-origin.
95
+
96
+ | op | args | result |
97
+ |---|---|---|
98
+ | `mcpm-list` | `{}` | `{ok, rows[], paths, errors[]}` |
99
+ | `mcpm-add` | `{serverName, transport, url|command, args?, headers?, env?, level, enabled?}` | `{ok, row}` |
100
+ | `mcpm-edit` | `{id, level, ...fields}` | `{ok}` |
101
+ | `mcpm-set-enabled` | `{id, level, enabled}` | `{ok}` |
102
+ | `mcpm-restart` | `{id, level}` | `{ok}` |
103
+ | `mcpm-remove` | `{id, level}` | `{ok}` |
104
+ | `mcpm-export` | `{}` | `{ok, json, savedTo}` |
105
+ | `mcpm-import` | `{json}` | `{ok, added[], skipped[]}` |
106
+
107
+ ## Model tools
108
+
109
+ Registered on the host with `ctx.tools.register(defineTool(...))` (standard `@deepseek-ai/dsh-tools`):
110
+
111
+ | tool | description |
112
+ |---|---|
113
+ | `mcp_manager_list` | list all configured MCP servers (level, enabled state, live loader status, tool count) |
114
+ | `mcp_manager_set_enabled` | enable / disable one server (id, level, enabled) |
115
+ | `mcp_manager_restart` | restart one server (id, level) |
116
+ | `mcp_manager_add` | add a server (serverName, transport, url|command, …, level) |
117
+
118
+ ## Notes / limitations
119
+
120
+ - The HTTP route is unauthenticated on the local web server — fine for a local single-user machine; do not expose the DSH web port publicly.
121
+ - Managed rows carry `# dsh-mcp-manager:server:<id>` markers; the loader row is an `insert` block adding `id: mcp-manager, name: dsh-mcp-manager` — DSH's patch dialect treats a plain `- id:` row as an override of an existing entry (silently skipped when absent), so **adding** a plugin requires the `insert` form.
122
+ - If the running web page predates the install, a page refresh or DSH restart is needed for the client module (the boot graph is built at page load).
@@ -0,0 +1,173 @@
1
+ # dsh-mcp-manager(DSH MCP 服务管理器)
2
+
3
+ [中文](README.zh-CN.md) · [English](README.md)
4
+
5
+ ![dsh-mcp-manager 设置页图例](show.png)
6
+
7
+ 一个给 DeepSeek Harness (DSH) 用的**常驻 MCP 服务管理插件**——**loader 插件**(不是动态会话插件),安装后 DSH 重启、升级依然存在。
8
+
9
+ 按 DSH 官方插件开发标准实现(参考官方文档:[第一个插件](https://deepseek-harness.github.io/deepseek-harness/develop/basic/)、[开发一个工具](https://deepseek-harness.github.io/deepseek-harness/develop/basic/tool)):
10
+
11
+ - **对象形态 Cordis 插件**(`export default { name, inject, apply }`)
12
+ - 必需服务在 `inject` 中声明——框架保证 `apply` 前已就绪,服务消失会自动重载插件(这是插件跨 DSH 升级存活的机制)
13
+ - 面向模型的能力用 **`ctx.tools.register(defineTool(...))`** 注册:`mcp_manager_list`、`mcp_manager_set_enabled`、`mcp_manager_restart`、`mcp_manager_add`
14
+ - 面向 UI 的能力用 **`webServer` 精确路由**(`POST /dsh-mcp-manager/api`),由客户端半区消费
15
+
16
+ 功能入口:**设置 → MCP 管理**。
17
+
18
+ 功能:
19
+
20
+ - 宿主半区管理 `@deepseek-ai/dsh-mcp-client` 行:
21
+ - **项目级** → `~/.dsh/profiles/<profile>/cordis.patch.yml`
22
+ - **全局** → `~/.dsh/cordis.patch.yml`
23
+ - 新增 / 编辑 / 启用 / 禁用 / 重启 / 删除,工具数健康检查,JSON 导出/导入,按文件写锁
24
+ - 修改经 HMR 实时生效;重启 DSH 后由 Loader 自动加载
25
+
26
+ ## 工作原理
27
+
28
+ | 部分 | 文件 | 作用 |
29
+ |---|---|---|
30
+ | 宿主插件源码 | `src/index.ts` | TypeScript 源码(官方文档的插件形态);**`npm run build`**(tsc)编译 |
31
+ | 宿主插件(编译产物) | `lib/index.js`(`main`) | Cordis 对象插件:patch 文件 CRUD + 4 个模型工具 + `webServer` 精确路由 `/dsh-mcp-manager/api`(JSON `{op, args}` → `{ok, ...}`) |
32
+ | 客户端 bundle | `lib/client.js`(`exports["./client"]` + `dsh.client`) | 浏览器模块:注册设置页;通过 `fetch('/dsh-mcp-manager/api')` 调用宿主 |
33
+ | loader 行 | 追加到 profile 的 `cordis.patch.yml` | 组合宿主条目;client-modules 服务扫描启用的条目并下发客户端 bundle |
34
+
35
+ > **loader 行必须是 `insert` 块形式**:DSH 的 patch 方言(`applyEntryPatches`)把普通 `- id: x` 行当作"对已存在条目的配置覆盖",目标不存在时会**静默跳过**——新增插件必须用 `- insert:` 形式(与插件自身管理 MCP 服务行一致)。
36
+
37
+ 包本身**纯 JS、零依赖、跨平台**(路径分隔符运行时检测),Windows / macOS / Linux 均支持。构建(`npm run build`)需要 devDependencies(typescript、`@deepseek-ai/cordis`、`@deepseek-ai/dsh-tools`、`@types/node`);发布/安装的包**不需要**任何依赖。
38
+
39
+ ## 安装(任选一种方式)
40
+
41
+ ### 方式 0:npx 一条命令(最快捷,需要 Node.js >= 18)
42
+
43
+ ```bash
44
+ # 从 npm 安装(推荐)
45
+ npx -y @xxxyz/dsh-mcp-manager
46
+
47
+ # 或直接从 GitHub 安装(无需 npm 账号)
48
+ npx -y github:xxxyz/DeepSeekHarness-MCP-Manager
49
+ ```
50
+
51
+ 所有参数照常透传:`npx -y @xxxyz/dsh-mcp-manager --dsh-home /path/.dsh --profile web --repair --port 3080`。
52
+
53
+ > npm 包名是 `@xxxyz/dsh-mcp-manager`(裸名 `dsh-mcp-manager` 在 npm 上已被无关插件占用)。插件部署名仍是 `dsh-mcp-manager`——npx 只是配送渠道,安装器会把文件复制到下方同样的固定位置。
54
+
55
+ 以上所有方式实际执行的是同样的三个步骤(幂等,可重复运行):
56
+
57
+ 1. 复制包到 `<DSH主目录>/local-packages/dsh-mcp-manager`(真源备份,DSH 升级不会动它);
58
+ 2. 复制到 `<DSH主目录>/profiles/node_modules/dsh-mcp-manager`(**普通复制而非软链接**——软链接会让 Node ESM 按真实路径解析时找不到 `@deepseek-ai/dsh-tools`);
59
+ 3. 在 `profiles/<profile>/cordis.patch.yml` 追加 loader 行(insert 块,**幂等**,重复运行不会重复添加)。
60
+
61
+ ### 方式 1:Windows(PowerShell)
62
+
63
+ ```powershell
64
+ # 默认使用 ~/.dsh 和 web profile
65
+ .\dsh-mcp-manager\install.ps1
66
+
67
+ # 指定 DSH 主目录 / profile
68
+ .\dsh-mcp-manager\install.ps1 -DshHome D:\path\.dsh -Profile web
69
+
70
+ # 修复模式(见"DSH 升级后:--repair")
71
+ .\dsh-mcp-manager\install.ps1 -Repair -Port 3080
72
+ ```
73
+
74
+ ### 方式 2:macOS / Linux(bash)
75
+
76
+ ```bash
77
+ # 默认使用 ~/.dsh 和 web profile
78
+ ./dsh-mcp-manager/install.sh
79
+
80
+ # 指定 DSH 主目录 / profile
81
+ ./dsh-mcp-manager/install.sh --dsh-home /path/.dsh --profile web
82
+
83
+ # 修复模式
84
+ ./dsh-mcp-manager/install.sh --repair --port 3080
85
+ ```
86
+
87
+ > 若 `install.sh` 没有执行权限,先运行:`chmod +x dsh-mcp-manager/install.sh`
88
+
89
+ ### 方式 3:任何平台直接运行(推荐,最通用)
90
+
91
+ ```bash
92
+ node dsh-mcp-manager/install.mjs # 默认 ~/.dsh + web
93
+ node dsh-mcp-manager/install.mjs --dsh-home /path/.dsh --profile web
94
+ node dsh-mcp-manager/install.mjs --repair --port 3080 # 修复模式
95
+ ```
96
+
97
+ ### 参数说明
98
+
99
+ | 参数 | 说明 | 默认值 |
100
+ |---|---|---|
101
+ | `--dsh-home` / `-DshHome` | DSH 主目录(含 `profiles`、`settings.yaml` 的目录) | `$DSH_HOME` 环境变量,否则 `~/.dsh` |
102
+ | `--profile` / `-Profile` | 要安装到的 profile 名 | `web` |
103
+ | `--port` / `-Port` | 修复模式下探测 API 的端口(= DSH Web 端口) | `3080` |
104
+ | `--repair` / `-Repair` | 修复模式:重新部署 + 递增 loader 行 `config.version` 触发 HMR 重应用 + 轮询 API 直到恢复 | 无 |
105
+ | `--skip-patch` | 只复制包、不修改补丁文件 | 无 |
106
+
107
+ ### 安装后验证
108
+
109
+ 1. **重启 DSH**(宿主插件与客户端模块在启动时加载;`mcp_manager_*` 4 个工具也在重启后注册)。
110
+ 2. 打开 **设置 → MCP 管理**,应能看到页面并管理现有 MCP 服务(如 stepfun)。
111
+
112
+ > 如果页面在安装前就已打开,先刷新浏览器(启动载荷在页面加载时构建);仍不出现则重启 DSH。
113
+
114
+ ## 卸载
115
+
116
+ ```powershell
117
+ # Windows
118
+ .\dsh-mcp-manager\uninstall.ps1 [-DshHome <路径>] [-Profile <名>]
119
+
120
+ # macOS / Linux
121
+ ./dsh-mcp-manager/uninstall.sh [--dsh-home <路径>] [--profile <名>]
122
+
123
+ # 任何平台
124
+ node dsh-mcp-manager/uninstall.mjs [--dsh-home <路径>] [--profile <名>]
125
+ ```
126
+
127
+ 然后重启 DSH。卸载会删除部署副本、`local-packages` 真源目录,并清理补丁里的 loader 行(补丁保持合法的顶层数组)。
128
+
129
+ ## DSH 升级后:--repair
130
+
131
+ DSH 升级(或 HMR 状态异常)后若发现 **设置里没有"MCP 管理"** 或 **`mcp_manager_*` 工具消失**,运行一次修复命令即可:重新复制包、把 loader 行的 `config.version` 加一(触发 HMR 重新应用)、然后轮询 API 直到 `POST /dsh-mcp-manager/api` 返回 `{ok:true}`(默认等 30 秒)。
132
+
133
+ ```bash
134
+ node dsh-mcp-manager/install.mjs --repair --port 3080
135
+ ```
136
+
137
+ > 如果 30 秒后 API 仍未恢复,重启一次 DSH——loader 在启动时会重新导入最新代码。
138
+
139
+ ## API 参考
140
+
141
+ 所有操作均为 `POST /dsh-mcp-manager/api`,请求体 `{"op": "<op>", "args": {...}}`,同源。
142
+
143
+ | op | args | 结果 |
144
+ |---|---|---|
145
+ | `mcpm-list` | `{}` | `{ok, rows[], paths, errors[]}` |
146
+ | `mcpm-add` | `{serverName, transport, url\|command, args?, headers?, env?, level, enabled?}` | `{ok, row}` |
147
+ | `mcpm-edit` | `{id, level, ...fields}` | `{ok}` |
148
+ | `mcpm-set-enabled` | `{id, level, enabled}` | `{ok}` |
149
+ | `mcpm-restart` | `{id, level}` | `{ok}` |
150
+ | `mcpm-remove` | `{id, level}` | `{ok}` |
151
+ | `mcpm-export` | `{}` | `{ok, json, savedTo}` |
152
+ | `mcpm-import` | `{json}` | `{ok, added[], skipped[]}` |
153
+
154
+ ## 模型工具
155
+
156
+ 宿主上用 `ctx.tools.register(defineTool(...))` 注册(标准 `@deepseek-ai/dsh-tools`):
157
+
158
+ | 工具 | 说明 |
159
+ |---|---|
160
+ | `mcp_manager_list` | 列出所有已配置的 MCP 服务(级别、启用状态、loader 实时状态、工具数) |
161
+ | `mcp_manager_set_enabled` | 启用 / 禁用某个服务(id, level, enabled) |
162
+ | `mcp_manager_restart` | 重启某个服务(id, level) |
163
+ | `mcp_manager_add` | 新增服务(serverName, transport, url\|command, …, level) |
164
+
165
+ ## 注意事项 / 限制
166
+
167
+ - HTTP 路由在本机 Web 服务上**无鉴权**——仅适合本机单人使用,不要把 DSH 的 Web 端口暴露到公网。
168
+ - 托管行带 `# dsh-mcp-manager:server:<id>` 标记;loader 行是 `insert` 块添加的 `id: mcp-manager, name: dsh-mcp-manager`(普通 `- id:` 行在 DSH patch 方言里只是覆盖,不能新增条目)。
169
+ - 如果打开中的页面先于安装存在,需要刷新页面或重启 DSH(启动图在页面加载时构建)。
170
+
171
+ ## 许可
172
+
173
+ [MIT](LICENSE)