@xxxyz/dsh-mcp-manager 2.0.2 → 2.0.4

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/README.md CHANGED
@@ -1,133 +1,193 @@
1
1
  # dsh-mcp-manager
2
2
 
3
- [English](README.md) · [中文](README.zh-CN.md)
3
+ <!-- Hero -->
4
+ <div align="center">
5
+ <b style="font-size: 1.15em;">Manage every MCP server in DeepSeek Harness from one settings page — install, configure, monitor.</b><br /><br />
6
+ <code>server list</code> <code>add / edit / delete</code> <code>enable / disable</code> <code>restart</code> <code>tool-count health</code> <code>JSON export / import</code><br />
7
+ <code>4 model tools</code> <code>HTTP API</code> <code>npx / npm / dsh plugin / scripts</code><br /><br />
8
+ <b>Settings → MCP 管理</b> manages <code>@deepseek-ai/dsh-mcp-client</code> rows in your project-level and
9
+ global <code>cordis.patch.yml</code> — no hand-editing, every change applies live via HMR, survives restarts and upgrades.
10
+ </div>
4
11
 
5
- ![dsh-mcp-manager MCP Manager settings page](show.png)
12
+ <div align="center">
6
13
 
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.
14
+ [![npm version](https://img.shields.io/npm/v/@xxxyz/dsh-mcp-manager?logo=npm&color=cb3837)](https://www.npmjs.com/package/@xxxyz/dsh-mcp-manager)
15
+ [![License](https://img.shields.io/github/license/xxxyz/DeepSeekHarness-MCP-Manager?color=blue)](LICENSE)
16
+ [![Node](https://img.shields.io/badge/node-%3E%3D18-339933?logo=node.js)](package.json)
17
+ [![GitHub](https://img.shields.io/badge/GitHub-xxxyz%2FDeepSeekHarness--MCP--Manager-181717?logo=github)](https://github.com/xxxyz/DeepSeekHarness-MCP-Manager)
8
18
 
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)):
19
+ </div>
10
20
 
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
21
+ <div align="center">
22
+ 🌏 <a href="./README.md"><b>English</b></a> · <a href="./README.zh-CN.md">中文</a>
23
+ </div>
15
24
 
16
- Features:
25
+ <br />
17
26
 
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
27
+ <p align="center"><img src="show.png" alt="dsh-mcp-manager Settings → MCP 管理" /></p>
23
28
 
24
- ## How it works
29
+ ## 功能一览
25
30
 
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 |
31
+ - **📋 服务器列表**:列出所有已配置的 MCP 服务器(`@deepseek-ai/dsh-mcp-client` 实例)——`serverName`、传输方式(`stdio` / `streamable-http`)、URL / 命令、启用状态、loader 实时加载阶段、已注册工具数
32
+ - **➕ 新增 / ➖ 删除**:表单添加 MCP 服务器(支持 env / headers / args),带格式与重名校验;一键删除
33
+ - **🔌 启用 / 停用**:随时切换,工具随之热连接 / 热断开
34
+ - **🔄 重启**:disable + re-enable,自动重连并重新同步工具
35
+ - **💾 持久化**:写入**项目级**(`profiles/<profile>/cordis.patch.yml`)或**全局**(`~/.dsh/cordis.patch.yml`),重启后保留;页面底部显示文件路径
36
+ - **🩺 健康检查**:每台服务器实时工具数与 loader 阶段,异常一目了然
37
+ - **📦 备份 / 恢复**:JSON 导出 / 导入,合并新增、已存在自动跳过
38
+ - **🤖 模型工具**:宿主注册 4 个 `mcp_manager_*` 工具,模型可直接查询与操作 MCP 服务
39
+ - **🌐 HTTP API**:`POST /dsh-mcp-manager/api`(JSON `{op, args}` → `{ok, ...}`),供客户端与脚本调用
40
+ - **📦 跨平台安装**:Windows / macOS / Linux 一条命令(npx / npm / `dsh plugin` / 脚本)
32
41
 
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.
42
+ ## 🚀 安装
34
43
 
35
- ## Install (any platform)
44
+ **前置**:DSH 已装好(`dsh web` 能正常运行),Node.js ≥ 18。
36
45
 
37
- **Quickest one command, via npm (requires Node.js >= 18):**
46
+ ### 方式一 · npx 一条命令(推荐)
38
47
 
39
- ```bash
40
- # Option A — one-shot with npx, nothing to install
48
+ ```sh
41
49
  npx -y @xxxyz/dsh-mcp-manager
50
+ ```
51
+
52
+ 所有参数照常透传:`npx -y @xxxyz/dsh-mcp-manager --dsh-home /path/.dsh --profile web --repair --port 3080`。
42
53
 
43
- # Option B — global npm install, then run the command any time
54
+ ### 方式二 · npm 全局安装(适合经常使用)
55
+
56
+ ```sh
44
57
  npm i -g @xxxyz/dsh-mcp-manager
45
- dsh-mcp-manager # install the plugin
46
- dsh-mcp-manager-uninstall # uninstall the plugin
47
- npm i -g @xxxyz/dsh-mcp-manager@latest # upgrade
58
+ dsh-mcp-manager # 安装插件
59
+ dsh-mcp-manager-uninstall # 卸载插件
60
+ npm i -g @xxxyz/dsh-mcp-manager@latest # 升级
48
61
  ```
49
62
 
50
- All flags pass through in both options: `npx -y @xxxyz/dsh-mcp-manager --dsh-home /path/.dsh --profile web --repair --port 3080`.
63
+ ### 方式三 · dsh 命令安装(bundle 方式)
51
64
 
52
- > 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` — npm/npx is only the delivery channel; the installer copies the files to the same fixed locations below.
65
+ ```sh
66
+ dsh plugin --profile web add @xxxyz/dsh-mcp-manager
67
+ # 或 GitHub 源(构建产物 lib/ 已入库,无需本地构建)
68
+ dsh plugin --profile web add github:xxxyz/DeepSeekHarness-MCP-Manager
69
+ ```
53
70
 
54
- **No-npm alternative directly from GitHub:**
55
- ```bash
71
+ ### 方式四 · npm 账号:GitHub 直拉
72
+
73
+ ```sh
56
74
  npx -y github:xxxyz/DeepSeekHarness-MCP-Manager
57
75
  ```
58
76
 
59
- **Alternative — run the installer scripts from a source checkout** (all installers share one cross-platform logic file, `install.mjs`). Install steps:
77
+ <details>
78
+ <summary><b>脚本安装</b>(源码方式:下载仓库后执行,幂等)</summary>
60
79
 
61
- 1. copy the package to `<dshHome>/local-packages/dsh-mcp-manager` (a true source kept outside `node_modules`, so DSH upgrades never touch it)
62
- 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)
63
- 3. append the loader row to `profiles/<profile>/cordis.patch.yml` (idempotent; keeps the patch a valid top-level array)
80
+ **Windows(PowerShell)**:
64
81
 
65
- **Windows (PowerShell):**
66
82
  ```powershell
67
- .\dsh-mcp-manager\install.ps1 # default: ~/.dsh, web profile
68
- # or: .\install.ps1 -DshHome D:\path\.dsh -Profile web
83
+ .\dsh-mcp-manager\install.ps1 # 默认 ~/.dsh + web profile
84
+ .\dsh-mcp-manager\install.ps1 -DshHome D:\path\.dsh -Profile web
69
85
  ```
70
86
 
71
- **macOS / Linux:**
72
- ```bash
73
- ./dsh-mcp-manager/install.sh # default: ~/.dsh, web profile
74
- # or: ./install.sh --dsh-home /path/.dsh --profile web
87
+ **macOS / Linux(bash)**(无执行权限先 `chmod +x dsh-mcp-manager/install.sh`):
88
+
89
+ ```sh
90
+ ./dsh-mcp-manager/install.sh # 默认 ~/.dsh + web profile
91
+ ./dsh-mcp-manager/install.sh --dsh-home /path/.dsh --profile web
75
92
  ```
76
93
 
77
- **Any platform (direct):**
78
- ```bash
94
+ **任何平台直接运行**:
95
+
96
+ ```sh
79
97
  node dsh-mcp-manager/install.mjs [--dsh-home <path>] [--profile <name>] [--port <n>] [--repair] [--skip-patch]
80
98
  ```
81
99
 
82
- Then **restart DSH** and open **Settings MCP 管理**. The four `mcp_manager_*` tools become callable by the model after that restart.
100
+ 安装脚本会:① 复制到 `local-packages/`(真源备份,DSH 升级不动它)② 复制到 `profiles/node_modules/`(普通复制而非软链接,保证 ESM 能解析 `@deepseek-ai/dsh-tools`)③ 幂等追加 loader 行(insert 块)。
83
101
 
84
- Uninstall (any method):
85
- ```bash
86
- dsh-mcp-manager-uninstall # if installed via npm -g
87
- # or: .\dsh-mcp-manager\uninstall.ps1 | ./uninstall.sh | node uninstall.mjs [--dsh-home <path>] [--profile <name>]
102
+ </details>
103
+
104
+ 装完**硬刷新浏览器**(Cmd/Ctrl+Shift+R),打开 **设置 MCP 管理** 即可看到管理页。若未出现,重启一次 DSH(host 半首次挂载需要)。
105
+
106
+ <details>
107
+ <summary><b>卸载</b></summary>
108
+
109
+ ```sh
110
+ dsh-mcp-manager-uninstall # 若用 npm -g 安装
111
+ # 或:.\uninstall.ps1 | ./uninstall.sh | node uninstall.mjs [--dsh-home <path>] [--profile <name>]
88
112
  ```
89
- then restart DSH. Uninstall removes the deployed copy, the `local-packages` true source, and the loader row.
90
113
 
91
- ## After a DSH upgrade: `--repair`
114
+ 然后重启 DSH。卸载删除部署副本、`local-packages` 真源,并清理 loader 行(补丁保持合法)。
92
115
 
93
- 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:
116
+ </details>
94
117
 
95
- ```bash
96
- node dsh-mcp-manager/install.mjs --repair # default ~/.dsh, web, port 3080
118
+ <details>
119
+ <summary><b>DSH 升级后:--repair</b></summary>
120
+
121
+ DSH 升级(或 HMR 状态异常)后若 **设置里没有"MCP 管理"** 或 **`mcp_manager_*` 工具消失**,运行一次修复命令:重新部署 → 递增 loader 行 `config.version`(触发 HMR 重应用)→ 轮询 API 直到 `{ok:true}`(默认 30 秒)。
122
+
123
+ ```sh
97
124
  node dsh-mcp-manager/install.mjs --repair --port 3080
98
- # PowerShell: .\install.ps1 -Repair -Port 3080 bash: ./install.sh --repair --port 3080
125
+ # PowerShell: .\install.ps1 -Repair -Port 3080 bash: ./install.sh --repair --port 3080
99
126
  ```
100
127
 
101
- `--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).
128
+ 仍不恢复则重启一次 DSHloader 启动时重新导入)。
129
+
130
+ </details>
131
+
132
+ <details>
133
+ <summary><b>常见问题</b></summary>
134
+
135
+ | 现象 | 原因与解决 |
136
+ |---|---|
137
+ | 装完设置里没有"MCP 管理" | 硬刷新(Cmd/Ctrl+Shift+R);仍没有就重启 DSH 一次。 |
138
+ | 页面出现**两个 MCP 页签 / 工具重复** | 双挂载:同时用了 install.mjs 与 `dsh plugin add` 两种方式。卸载其中一种(`dsh-mcp-manager-uninstall` 或删掉对应的 loader 行 / `dsh.profile.bundles` 条目)。 |
139
+ | DSH 升级后工具消失 | 跑一次 `--repair`(见上)。 |
140
+ | `npx` / `npm view` 报 404 | 国内镜像(npmmirror)同步有延迟:加 `--registry=https://registry.npmjs.org` 或稍等再试。 |
141
+ | 安装脚本报错 `EPERM` | DSH 正在运行占用了文件:先退出 DSH 再装。 |
142
+ | 修改配置后未生效 | 所有修改走 HMR 热应用,等 1–2 秒自动刷新;页面会自动轮询。 |
143
+
144
+ </details>
102
145
 
103
- ## API reference
146
+ ## 📖 使用说明
104
147
 
105
- All ops are `POST /dsh-mcp-manager/api` with `{"op": "<op>", "args": {...}}`, same-origin.
148
+ 打开 **设置 MCP 管理**:
106
149
 
107
- | op | args | result |
108
- |---|---|---|
109
- | `mcpm-list` | `{}` | `{ok, rows[], paths, errors[]}` |
110
- | `mcpm-add` | `{serverName, transport, url|command, args?, headers?, env?, level, enabled?}` | `{ok, row}` |
111
- | `mcpm-edit` | `{id, level, ...fields}` | `{ok}` |
112
- | `mcpm-set-enabled` | `{id, level, enabled}` | `{ok}` |
113
- | `mcpm-restart` | `{id, level}` | `{ok}` |
114
- | `mcpm-remove` | `{id, level}` | `{ok}` |
115
- | `mcpm-export` | `{}` | `{ok, json, savedTo}` |
116
- | `mcpm-import` | `{json}` | `{ok, added[], skipped[]}` |
150
+ - **添加服务器**:填写 `serverName`(唯一,1–32 位 `[A-Za-z0-9_-]`)、传输方式及对应字段(`streamable-http` 填 URL / headers;`stdio` 填 command / args / env),选择级别(项目级 / 全局)。面板做格式与重名校验。
151
+ - 每张卡片显示实时状态、连接目标与工具数;可 **启用 / 停用**、**重启**、**编辑**、**删除**。
152
+ - **备份 / 恢复**:一键导出 JSON,或粘贴 JSON 导入(合并新增,已存在自动跳过)。
153
+ - 页面底部显示正在编辑的补丁文件路径。
117
154
 
118
- ## Model tools
155
+ ## ⚙️ 配置
119
156
 
120
- Registered on the host with `ctx.tools.register(defineTool(...))` (standard `@deepseek-ai/dsh-tools`):
157
+ 插件自身在 loader 行中的配置:
121
158
 
122
- | tool | description |
159
+ | 字段 | 说明 |
123
160
  |---|---|
124
- | `mcp_manager_list` | list all configured MCP servers (level, enabled state, live loader status, tool count) |
125
- | `mcp_manager_set_enabled` | enable / disable one server (id, level, enabled) |
126
- | `mcp_manager_restart` | restart one server (id, level) |
127
- | `mcp_manager_add` | add a server (serverName, transport, url|command, …, level) |
161
+ | `version` | loader `config.version`。`--repair` 会将其递增以强制 HMR 重应用,无需手动修改。 |
162
+
163
+ loader 行必须为 **`insert` 块**形式(DSH patch 方言中普通 `- id:` 行只是对已存在条目的覆盖,无法新增插件):
164
+
165
+ ```yaml
166
+ - insert:
167
+ - id: dsh-mcp-manager
168
+ name: dsh-mcp-manager
169
+ config:
170
+ version: 1
171
+ ```
172
+
173
+ ## 🏗️ 架构
174
+
175
+ - **宿主端**(`src/index.ts` → `lib/index.js`,对象形态 Cordis 插件 `{name, inject, apply}`):`inject` 声明 `timer/fs/settings/sandboxPolicy/webServer/tools`,框架保证就绪并在依赖消失时自动重载——这是插件跨 DSH 升级存活的机制。注册 4 个模型工具(`ctx.tools.register(defineTool(...))`)与精确路由 `POST /dsh-mcp-manager/api`(`ctx.effect` 作用域化清理);对 `cordis.patch.yml` 做行级 CRUD(迷你 YAML 解析 + 按文件写锁)。
176
+ - **浏览器端**(`lib/client.js`,ModuleLoader CJS bundle):注册 设置 → MCP 管理 页(`settings.section` 槽位,order 16),经同源 `fetch('/dsh-mcp-manager/api')` 与宿主通信,不直接访问文件系统。
177
+ - **loader 行**:写入 profile 的 `cordis.patch.yml`,client-modules 服务扫描启用的条目并下发客户端 bundle。
178
+ - **安装器**:`install.mjs`(跨平台核心)/ `install.ps1` / `install.sh` + 对应的 `uninstall.*`;npm 包 `@xxxyz/dsh-mcp-manager` 的 bin 直接执行安装器(`dsh-mcp-manager` / `dsh-mcp-manager-uninstall`)。
179
+
180
+ ## 🛠️ 开发
181
+
182
+ ```bash
183
+ npm install
184
+ npm run build # tsc -p tsconfig.json → lib/index.js(宿主端)
185
+ ```
186
+
187
+ - 宿主插件源码:`src/index.ts`;浏览器 bundle:`lib/client.js`(手写,无需构建)
188
+ - 包本身纯 JS、零依赖、跨平台;构建只需 devDependencies(typescript、`@deepseek-ai/cordis`、`@deepseek-ai/dsh-tools`、`@types/node`)
189
+ - 发布:`npm version patch && npm publish`(`prepublishOnly` 自动构建;scoped 包已配置 `publishConfig.access: public`)
128
190
 
129
- ## Notes / limitations
191
+ ## 许可证
130
192
 
131
- - 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.
132
- - 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.
133
- - 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).
193
+ MIT
package/README.zh-CN.md CHANGED
@@ -1,180 +1,193 @@
1
- # dsh-mcp-manager(DSH MCP 服务管理器)
1
+ # dsh-mcp-manager
2
2
 
3
- [中文](README.zh-CN.md) · [English](README.md)
3
+ <!-- Hero -->
4
+ <div align="center">
5
+ <b style="font-size: 1.15em;">DeepSeek Harness 的 MCP 服务管理器:装没装、连没连、一页管完。</b><br /><br />
6
+ <code>服务器列表</code> <code>新增 / 编辑 / 删除</code> <code>启用 / 停用</code> <code>重启</code> <code>工具数健康</code> <code>JSON 导出 / 导入</code><br />
7
+ <code>4 个模型工具</code> <code>HTTP API</code> <code>npx / npm / dsh plugin / 脚本</code><br /><br />
8
+ <b>设置 → MCP 管理</b> 管理项目级与全局 <code>cordis.patch.yml</code> 中的 <code>@deepseek-ai/dsh-mcp-client</code> 行——<br />
9
+ 无需再手改配置文件,所有修改即改即生效(HMR 热应用),重启、升级后依然存在。
10
+ </div>
4
11
 
5
- ![dsh-mcp-manager 设置页图例](show.png)
12
+ <div align="center">
6
13
 
7
- 一个给 DeepSeek Harness (DSH) 用的**常驻 MCP 服务管理插件**——**loader 插件**(不是动态会话插件),安装后 DSH 重启、升级依然存在。
14
+ [![npm version](https://img.shields.io/npm/v/@xxxyz/dsh-mcp-manager?logo=npm&color=cb3837)](https://www.npmjs.com/package/@xxxyz/dsh-mcp-manager)
15
+ [![License](https://img.shields.io/github/license/xxxyz/DeepSeekHarness-MCP-Manager?color=blue)](LICENSE)
16
+ [![Node](https://img.shields.io/badge/node-%3E%3D18-339933?logo=node.js)](package.json)
17
+ [![GitHub](https://img.shields.io/badge/GitHub-xxxyz%2FDeepSeekHarness--MCP--Manager-181717?logo=github)](https://github.com/xxxyz/DeepSeekHarness-MCP-Manager)
8
18
 
9
- 按 DSH 官方插件开发标准实现(参考官方文档:[第一个插件](https://deepseek-harness.github.io/deepseek-harness/develop/basic/)、[开发一个工具](https://deepseek-harness.github.io/deepseek-harness/develop/basic/tool)):
19
+ </div>
10
20
 
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`),由客户端半区消费
21
+ <div align="center">
22
+ 🌏 <a href="./README.zh-CN.md"><b>中文</b></a> · <a href="./README.md">English</a>
23
+ </div>
15
24
 
16
- 功能入口:**设置 → MCP 管理**。
25
+ <br />
17
26
 
18
- 功能:
27
+ <p align="center"><img src="show.png" alt="dsh-mcp-manager 设置 → MCP 管理 页面图例" /></p>
19
28
 
20
- - 宿主半区管理 `@deepseek-ai/dsh-mcp-client` 行:
21
- - **项目级** → `~/.dsh/profiles/<profile>/cordis.patch.yml`
22
- - **全局** → `~/.dsh/cordis.patch.yml`
23
- - 新增 / 编辑 / 启用 / 禁用 / 重启 / 删除,工具数健康检查,JSON 导出/导入,按文件写锁
24
- - 修改经 HMR 实时生效;重启 DSH 后由 Loader 自动加载
29
+ ## 功能一览
25
30
 
26
- ## 工作原理
31
+ - **📋 服务器列表**:列出所有已配置的 MCP 服务器(`@deepseek-ai/dsh-mcp-client` 实例)——`serverName`、传输方式(`stdio` / `streamable-http`)、URL / 命令、启用状态、loader 实时加载阶段、已注册工具数
32
+ - **➕ 新增 / ➖ 删除**:表单添加 MCP 服务器(支持 env / headers / args),带格式与重名校验;一键删除
33
+ - **🔌 启用 / 停用**:随时切换,工具随之热连接 / 热断开
34
+ - **🔄 重启**:disable + re-enable,自动重连并重新同步工具
35
+ - **💾 持久化**:写入**项目级**(`profiles/<profile>/cordis.patch.yml`)或**全局**(`~/.dsh/cordis.patch.yml`),重启后保留;页面底部显示文件路径
36
+ - **🩺 健康检查**:每台服务器实时工具数与 loader 阶段,异常一目了然
37
+ - **📦 备份 / 恢复**:JSON 导出 / 导入,合并新增、已存在自动跳过
38
+ - **🤖 模型工具**:宿主注册 4 个 `mcp_manager_*` 工具,模型可直接查询与操作 MCP 服务
39
+ - **🌐 HTTP API**:`POST /dsh-mcp-manager/api`(JSON `{op, args}` → `{ok, ...}`),供客户端与脚本调用
40
+ - **📦 跨平台安装**:Windows / macOS / Linux 一条命令(npx / npm / `dsh plugin` / 脚本)
27
41
 
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 |
42
+ ## 🚀 安装
34
43
 
35
- > **loader 行必须是 `insert` 块形式**:DSH patch 方言(`applyEntryPatches`)把普通 `- id: x` 行当作"对已存在条目的配置覆盖",目标不存在时会**静默跳过**——新增插件必须用 `- insert:` 形式(与插件自身管理 MCP 服务行一致)。
44
+ **前置**:DSH 已装好(`dsh web` 能正常运行),Node.js 18。
36
45
 
37
- 包本身**纯 JS、零依赖、跨平台**(路径分隔符运行时检测),Windows / macOS / Linux 均支持。构建(`npm run build`)需要 devDependencies(typescript、`@deepseek-ai/cordis`、`@deepseek-ai/dsh-tools`、`@types/node`);发布/安装的包**不需要**任何依赖。
46
+ ### 方式一 · npx 一条命令(推荐)
38
47
 
39
- ## 安装(任选一种方式)
40
-
41
- ### 方式 0:npx 一条命令(免安装,最快捷,需要 Node.js >= 18)
42
-
43
- ```bash
44
- # 从 npm 临时运行(推荐,无需安装)
48
+ ```sh
45
49
  npx -y @xxxyz/dsh-mcp-manager
46
-
47
- # 或直接从 GitHub 运行(无需 npm 账号)
48
- npx -y github:xxxyz/DeepSeekHarness-MCP-Manager
49
50
  ```
50
51
 
51
52
  所有参数照常透传:`npx -y @xxxyz/dsh-mcp-manager --dsh-home /path/.dsh --profile web --repair --port 3080`。
52
53
 
53
- > npm 包名是 `@xxxyz/dsh-mcp-manager`(裸名 `dsh-mcp-manager` 在 npm 上已被无关插件占用)。插件部署名仍是 `dsh-mcp-manager`——npx 只是配送渠道,安装器会把文件复制到下方同样的固定位置。
54
+ ### 方式二 · npm 全局安装(适合经常使用)
54
55
 
55
- ### 方式 1:npm 全局安装(适合经常使用)
56
-
57
- ```bash
58
- # 安装插件
56
+ ```sh
59
57
  npm i -g @xxxyz/dsh-mcp-manager
60
- dsh-mcp-manager # 安装插件(参数同 npx)
58
+ dsh-mcp-manager # 安装插件
61
59
  dsh-mcp-manager-uninstall # 卸载插件
62
- # 升级插件
63
- npm i -g @xxxyz/dsh-mcp-manager@latest
60
+ npm i -g @xxxyz/dsh-mcp-manager@latest # 升级
64
61
  ```
65
62
 
66
- ### 方式 2:Windows(PowerShell)
63
+ ### 方式三 · dsh 命令安装(bundle 方式)
67
64
 
68
- ```powershell
69
- # 默认使用 ~/.dsh web profile
70
- .\dsh-mcp-manager\install.ps1
65
+ ```sh
66
+ dsh plugin --profile web add @xxxyz/dsh-mcp-manager
67
+ # 或 GitHub 源(构建产物 lib/ 已入库,无需本地构建)
68
+ dsh plugin --profile web add github:xxxyz/DeepSeekHarness-MCP-Manager
69
+ ```
71
70
 
72
- # 指定 DSH 主目录 / profile
73
- .\dsh-mcp-manager\install.ps1 -DshHome D:\path\.dsh -Profile web
71
+ ### 方式四 · npm 账号:GitHub 直拉
74
72
 
75
- # 修复模式(见"DSH 升级后:--repair")
76
- .\dsh-mcp-manager\install.ps1 -Repair -Port 3080
73
+ ```sh
74
+ npx -y github:xxxyz/DeepSeekHarness-MCP-Manager
77
75
  ```
78
76
 
79
- ### 方式 3:macOS / Linux(bash)
77
+ <details>
78
+ <summary><b>脚本安装</b>(源码方式:下载仓库后执行,幂等)</summary>
80
79
 
81
- ```bash
82
- # 默认使用 ~/.dsh 和 web profile
83
- ./dsh-mcp-manager/install.sh
84
-
85
- # 指定 DSH 主目录 / profile
86
- ./dsh-mcp-manager/install.sh --dsh-home /path/.dsh --profile web
80
+ **Windows(PowerShell)**:
87
81
 
88
- # 修复模式
89
- ./dsh-mcp-manager/install.sh --repair --port 3080
82
+ ```powershell
83
+ .\dsh-mcp-manager\install.ps1 # 默认 ~/.dsh + web profile
84
+ .\dsh-mcp-manager\install.ps1 -DshHome D:\path\.dsh -Profile web
90
85
  ```
91
86
 
92
- > `install.sh` 没有执行权限,先运行:`chmod +x dsh-mcp-manager/install.sh`
87
+ **macOS / Linux(bash)**(无执行权限先 `chmod +x dsh-mcp-manager/install.sh`):
93
88
 
94
- ### 方式 4:任何平台直接运行(推荐,最通用)
95
-
96
- ```bash
97
- node dsh-mcp-manager/install.mjs # 默认 ~/.dsh + web
98
- node dsh-mcp-manager/install.mjs --dsh-home /path/.dsh --profile web
99
- node dsh-mcp-manager/install.mjs --repair --port 3080 # 修复模式
89
+ ```sh
90
+ ./dsh-mcp-manager/install.sh # 默认 ~/.dsh + web profile
91
+ ./dsh-mcp-manager/install.sh --dsh-home /path/.dsh --profile web
100
92
  ```
101
93
 
102
- ### 参数说明
94
+ **任何平台直接运行**:
103
95
 
104
- | 参数 | 说明 | 默认值 |
105
- |---|---|---|
106
- | `--dsh-home` / `-DshHome` | DSH 主目录(含 `profiles`、`settings.yaml` 的目录) | `$DSH_HOME` 环境变量,否则 `~/.dsh` |
107
- | `--profile` / `-Profile` | 要安装到的 profile 名 | `web` |
108
- | `--port` / `-Port` | 修复模式下探测 API 的端口(= DSH Web 端口) | `3080` |
109
- | `--repair` / `-Repair` | 修复模式:重新部署 + 递增 loader 行 `config.version` 触发 HMR 重应用 + 轮询 API 直到恢复 | 无 |
110
- | `--skip-patch` | 只复制包、不修改补丁文件 | 无 |
96
+ ```sh
97
+ node dsh-mcp-manager/install.mjs [--dsh-home <path>] [--profile <name>] [--port <n>] [--repair] [--skip-patch]
98
+ ```
111
99
 
112
- ### 安装后验证
100
+ 安装脚本会:① 复制到 `local-packages/`(真源备份,DSH 升级不动它)② 复制到 `profiles/node_modules/`(普通复制而非软链接,保证 ESM 能解析 `@deepseek-ai/dsh-tools`)③ 幂等追加 loader 行(insert 块)。
113
101
 
114
- 1. **重启 DSH**(宿主插件与客户端模块在启动时加载;`mcp_manager_*` 4 个工具也在重启后注册)。
115
- 2. 打开 **设置 → MCP 管理**,应能看到页面并管理现有 MCP 服务(如 stepfun)。
102
+ </details>
116
103
 
117
- > 如果页面在安装前就已打开,先刷新浏览器(启动载荷在页面加载时构建);仍不出现则重启 DSH
104
+ 装完**硬刷新浏览器**(Cmd/Ctrl+Shift+R),打开 **设置 → MCP 管理** 即可看到管理页。若未出现,重启一次 DSH(host 半首次挂载需要)。
118
105
 
119
- ## 卸载
106
+ <details>
107
+ <summary><b>卸载</b></summary>
120
108
 
121
- ```bash
122
- # npm 全局安装时(推荐)
123
- dsh-mcp-manager-uninstall
124
-
125
- # 或使用脚本 / 直接运行
126
- # Windows
127
- .\dsh-mcp-manager\uninstall.ps1 [-DshHome <路径>] [-Profile <名>]
128
- # macOS / Linux
129
- ./dsh-mcp-manager/uninstall.sh [--dsh-home <路径>] [--profile <名>]
130
- # 任何平台
131
- node dsh-mcp-manager/uninstall.mjs [--dsh-home <路径>] [--profile <名>]
109
+ ```sh
110
+ dsh-mcp-manager-uninstall # 若用 npm -g 安装
111
+ # 或:.\uninstall.ps1 | ./uninstall.sh | node uninstall.mjs [--dsh-home <path>] [--profile <name>]
132
112
  ```
133
113
 
134
- 然后重启 DSH。卸载会删除部署副本、`local-packages` 真源目录,并清理补丁里的 loader 行(补丁保持合法的顶层数组)。
114
+ 然后重启 DSH。卸载删除部署副本、`local-packages` 真源,并清理 loader 行(补丁保持合法)。
135
115
 
136
- ## DSH 升级后:--repair
116
+ </details>
137
117
 
138
- DSH 升级(或 HMR 状态异常)后若发现 **设置里没有"MCP 管理"** 或 **`mcp_manager_*` 工具消失**,运行一次修复命令即可:重新复制包、把 loader 行的 `config.version` 加一(触发 HMR 重新应用)、然后轮询 API 直到 `POST /dsh-mcp-manager/api` 返回 `{ok:true}`(默认等 30 秒)。
118
+ <details>
119
+ <summary><b>DSH 升级后:--repair</b></summary>
139
120
 
140
- ```bash
121
+ DSH 升级(或 HMR 状态异常)后若 **设置里没有"MCP 管理"** 或 **`mcp_manager_*` 工具消失**,运行一次修复命令:重新部署 → 递增 loader 行 `config.version`(触发 HMR 重应用)→ 轮询 API 直到 `{ok:true}`(默认 30 秒)。
122
+
123
+ ```sh
141
124
  node dsh-mcp-manager/install.mjs --repair --port 3080
125
+ # PowerShell: .\install.ps1 -Repair -Port 3080 bash: ./install.sh --repair --port 3080
142
126
  ```
143
127
 
144
- > 如果 30 秒后 API 仍未恢复,重启一次 DSH——loader 在启动时会重新导入最新代码。
128
+ 仍不恢复则重启一次 DSHloader 启动时重新导入)。
129
+
130
+ </details>
131
+
132
+ <details>
133
+ <summary><b>常见问题</b></summary>
134
+
135
+ | 现象 | 原因与解决 |
136
+ |---|---|
137
+ | 装完设置里没有"MCP 管理" | 硬刷新(Cmd/Ctrl+Shift+R);仍没有就重启 DSH 一次。 |
138
+ | 页面出现**两个 MCP 页签 / 工具重复** | 双挂载:同时用了 install.mjs 与 `dsh plugin add` 两种方式。卸载其中一种(`dsh-mcp-manager-uninstall` 或删掉对应的 loader 行 / `dsh.profile.bundles` 条目)。 |
139
+ | DSH 升级后工具消失 | 跑一次 `--repair`(见上)。 |
140
+ | `npx` / `npm view` 报 404 | 国内镜像(npmmirror)同步有延迟:加 `--registry=https://registry.npmjs.org` 或稍等再试。 |
141
+ | 安装脚本报错 `EPERM` | DSH 正在运行占用了文件:先退出 DSH 再装。 |
142
+ | 修改配置后未生效 | 所有修改走 HMR 热应用,等 1–2 秒自动刷新;页面会自动轮询。 |
143
+
144
+ </details>
145
145
 
146
- ## API 参考
146
+ ## 📖 使用说明
147
147
 
148
- 所有操作均为 `POST /dsh-mcp-manager/api`,请求体 `{"op": "<op>", "args": {...}}`,同源。
148
+ 打开 **设置 MCP 管理**:
149
149
 
150
- | op | args | 结果 |
151
- |---|---|---|
152
- | `mcpm-list` | `{}` | `{ok, rows[], paths, errors[]}` |
153
- | `mcpm-add` | `{serverName, transport, url\|command, args?, headers?, env?, level, enabled?}` | `{ok, row}` |
154
- | `mcpm-edit` | `{id, level, ...fields}` | `{ok}` |
155
- | `mcpm-set-enabled` | `{id, level, enabled}` | `{ok}` |
156
- | `mcpm-restart` | `{id, level}` | `{ok}` |
157
- | `mcpm-remove` | `{id, level}` | `{ok}` |
158
- | `mcpm-export` | `{}` | `{ok, json, savedTo}` |
159
- | `mcpm-import` | `{json}` | `{ok, added[], skipped[]}` |
150
+ - **添加服务器**:填写 `serverName`(唯一,1–32 位 `[A-Za-z0-9_-]`)、传输方式及对应字段(`streamable-http` 填 URL / headers;`stdio` 填 command / args / env),选择级别(项目级 / 全局)。面板做格式与重名校验。
151
+ - 每张卡片显示实时状态、连接目标与工具数;可 **启用 / 停用**、**重启**、**编辑**、**删除**。
152
+ - **备份 / 恢复**:一键导出 JSON,或粘贴 JSON 导入(合并新增,已存在自动跳过)。
153
+ - 页面底部显示正在编辑的补丁文件路径。
160
154
 
161
- ## 模型工具
155
+ ## ⚙️ 配置
162
156
 
163
- 宿主上用 `ctx.tools.register(defineTool(...))` 注册(标准 `@deepseek-ai/dsh-tools`):
157
+ 插件自身在 loader 行中的配置:
164
158
 
165
- | 工具 | 说明 |
159
+ | 字段 | 说明 |
166
160
  |---|---|
167
- | `mcp_manager_list` | 列出所有已配置的 MCP 服务(级别、启用状态、loader 实时状态、工具数) |
168
- | `mcp_manager_set_enabled` | 启用 / 禁用某个服务(id, level, enabled) |
169
- | `mcp_manager_restart` | 重启某个服务(id, level) |
170
- | `mcp_manager_add` | 新增服务(serverName, transport, url\|command, …, level) |
161
+ | `version` | loader `config.version`。`--repair` 会将其递增以强制 HMR 重应用,无需手动修改。 |
162
+
163
+ loader 行必须为 **`insert` 块**形式(DSH patch 方言中普通 `- id:` 行只是对已存在条目的覆盖,无法新增插件):
164
+
165
+ ```yaml
166
+ - insert:
167
+ - id: dsh-mcp-manager
168
+ name: dsh-mcp-manager
169
+ config:
170
+ version: 1
171
+ ```
172
+
173
+ ## 🏗️ 架构
171
174
 
172
- ## 注意事项 / 限制
175
+ - **宿主端**(`src/index.ts` → `lib/index.js`,对象形态 Cordis 插件 `{name, inject, apply}`):`inject` 声明 `timer/fs/settings/sandboxPolicy/webServer/tools`,框架保证就绪并在依赖消失时自动重载——这是插件跨 DSH 升级存活的机制。注册 4 个模型工具(`ctx.tools.register(defineTool(...))`)与精确路由 `POST /dsh-mcp-manager/api`(`ctx.effect` 作用域化清理);对 `cordis.patch.yml` 做行级 CRUD(迷你 YAML 解析 + 按文件写锁)。
176
+ - **浏览器端**(`lib/client.js`,ModuleLoader CJS bundle):注册 设置 → MCP 管理 页(`settings.section` 槽位,order 16),经同源 `fetch('/dsh-mcp-manager/api')` 与宿主通信,不直接访问文件系统。
177
+ - **loader 行**:写入 profile 的 `cordis.patch.yml`,client-modules 服务扫描启用的条目并下发客户端 bundle。
178
+ - **安装器**:`install.mjs`(跨平台核心)/ `install.ps1` / `install.sh` + 对应的 `uninstall.*`;npm 包 `@xxxyz/dsh-mcp-manager` 的 bin 直接执行安装器(`dsh-mcp-manager` / `dsh-mcp-manager-uninstall`)。
179
+
180
+ ## 🛠️ 开发
181
+
182
+ ```bash
183
+ npm install
184
+ npm run build # tsc -p tsconfig.json → lib/index.js(宿主端)
185
+ ```
173
186
 
174
- - HTTP 路由在本机 Web 服务上**无鉴权**——仅适合本机单人使用,不要把 DSH 的 Web 端口暴露到公网。
175
- - 托管行带 `# dsh-mcp-manager:server:<id>` 标记;loader 行是 `insert` 块添加的 `id: mcp-manager, name: dsh-mcp-manager`(普通 `- id:` 行在 DSH patch 方言里只是覆盖,不能新增条目)。
176
- - 如果打开中的页面先于安装存在,需要刷新页面或重启 DSH(启动图在页面加载时构建)。
187
+ - 宿主插件源码:`src/index.ts`;浏览器 bundle:`lib/client.js`(手写,无需构建)
188
+ - 包本身纯 JS、零依赖、跨平台;构建只需 devDependencies(typescript、`@deepseek-ai/cordis`、`@deepseek-ai/dsh-tools`、`@types/node`)
189
+ - 发布:`npm version patch && npm publish`(`prepublishOnly` 自动构建;scoped 包已配置 `publishConfig.access: public`)
177
190
 
178
- ## 许可
191
+ ## 许可证
179
192
 
180
- [MIT](LICENSE)
193
+ MIT
@@ -0,0 +1,7 @@
1
+ # Bundle patch layer for `dsh plugin add` installs: pnpm installs the scoped
2
+ # package as @xxxyz/dsh-mcp-manager, so the insert row names the scoped
3
+ # package. The loader-entry installer (install.mjs) mounts the same plugin
4
+ # under `dsh-mcp-manager` — both names are registered by the client bundle.
5
+ - insert:
6
+ - id: dsh-mcp-manager
7
+ name: '@xxxyz/dsh-mcp-manager'
package/lib/client.js CHANGED
@@ -2,9 +2,7 @@
2
2
  // Registers the "MCP 管理" settings page. Talks to the host half through the
3
3
  // exact-path HTTP route /dsh-mcp-manager/api (same origin) instead of the
4
4
  // dynamic-only host.call channel.
5
- window.__ModuleLoader__.load({
6
- id: 'dsh-mcp-manager',
7
- factory: (require) => {
5
+ const factory = (require) => {
8
6
  var module = { exports: {} }
9
7
  var exports = module.exports
10
8
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
@@ -299,5 +297,12 @@ window.__ModuleLoader__.load({
299
297
  },
300
298
  }
301
299
  return module.exports
302
- },
303
- })
300
+ }
301
+
302
+ // Register the client bundle under both names: the loader-entry install
303
+ // (install.mjs) mounts it as `dsh-mcp-manager`, while `dsh plugin add`
304
+ // (via the dsh.bundle patch) installs the scoped npm package and mounts it
305
+ // as `@xxxyz/dsh-mcp-manager`. The boot graph row id must match the id the
306
+ // bundle registers, so both are registered — the unused one is inert.
307
+ window.__ModuleLoader__.load({ id: 'dsh-mcp-manager', factory })
308
+ window.__ModuleLoader__.load({ id: '@xxxyz/dsh-mcp-manager', factory })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xxxyz/dsh-mcp-manager",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "DSH-standard MCP manager plugin: Settings UI + HTTP API + model-facing mcp_manager_* tools. Composed as a loader entry, survives restarts. Install via npx, PowerShell, bash or node.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -15,6 +15,7 @@
15
15
  },
16
16
  "files": [
17
17
  "lib",
18
+ "cordis.patch.yml",
18
19
  "install.mjs",
19
20
  "uninstall.mjs",
20
21
  "install.ps1",
@@ -54,6 +55,9 @@
54
55
  "url": "https://github.com/xxxyz/DeepSeekHarness-MCP-Manager/issues"
55
56
  },
56
57
  "dsh": {
58
+ "bundle": {
59
+ "patch": "./cordis.patch.yml"
60
+ },
57
61
  "client": {
58
62
  "platform": "web",
59
63
  "inject": [