dsh-mcp 1.4.0 → 1.5.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/CHANGELOG.en.md CHANGED
@@ -7,6 +7,20 @@ All notable changes to this project are documented in this file.
7
7
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
8
8
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
9
9
 
10
+ ## [1.5.0] - 2026-08-17
11
+
12
+ ### Added
13
+
14
+ - **Process env vars now prefer process.env by name**: when a variable exists in process.env its value is used verbatim (name unchanged) and stored values act as fallback; the UI is unchanged (value input and secret retained), and non-secret variables display the process.env value
15
+
16
+ ### Fixed
17
+
18
+ - **OAuth authorization page rejected with `redirect_uri_mismatch`**: the loopback port used to be random per process while the persisted OAuth client's `redirect_uris` are fixed at registration — after a restart the new callback address no longer matched, so the CAS server refused authorization. Fixed by deriving a stable port from the server name and validating in `clientInformation()` that the persisted client's `redirect_uris` cover the current callback, dropping it (and re-registering) otherwise
19
+ - **OAuth silently failed to connect with an expired token** (no browser authorization): when the access token expired and the refresh token was also dead, the SDK threw `InvalidTokenError` without retrying, so the connection just failed. The provider's `tokens()` now reads the JWT `exp` claim and clears expired credentials, letting the SDK fall through to a fresh browser authorization flow
20
+ - **OAuth token exchange failed with `code, code_verifier, client_id, redirect_uri are required`**: when the client was loaded from persistence the in-memory closure was null, so the token request lacked `client_id`. The exchange now reads client info and code verifier through the provider accessors (memory first, persistence fallback)
21
+ - **OAuth concurrent authorization port collision**: with a stable callback port, a mount and a test connection authorizing at the same time collided on the port (EADDRINUSE). Authorization flows are now serialized per server
22
+ - **Env-variable secret values were not persisted**: the editor dropped the value for secret rows. Filled values are now submitted (secret values go to the credentials document); a blank value keeps the stored one
23
+
10
24
  ## [1.4.0] - 2026-08-16
11
25
 
12
26
  ### Added
package/CHANGELOG.md CHANGED
@@ -7,6 +7,20 @@
7
7
  格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
8
8
  版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
9
9
 
10
+ ## [1.5.0] - 2026-08-17
11
+
12
+ ### 新增
13
+
14
+ - **进程环境变量展示/取值 process.env 优先**:变量存在 process.env 时按同名取真实值(不改名),存储值作为兜底;界面功能不变(值输入、secret 保留),非 secret 变量展示 process.env 的值
15
+
16
+ ### 修复
17
+
18
+ - **OAuth 授权页报 `redirect_uri_mismatch`**:回调端口原先每次进程随机生成,而持久化的 OAuth client 的 `redirect_uris` 在注册时固定——重启后新回调地址与注册地址不一致,CAS 拒绝授权。修复:回调端口按 serverName 稳定派生;`clientInformation()` 校验持久化 client 的 `redirect_uris` 是否覆盖当前回调地址,不匹配则丢弃并重新注册
19
+ - **OAuth 过期 token 导致静默连接失败**(不弹浏览器):access_token 过期且 refresh_token 也失效时,SDK 抛 `InvalidTokenError` 且不做失效重试,直接连接失败。修复:provider 的 `tokens()` 解析 access_token 的 JWT `exp`,过期即清除凭据,SDK 自动转入新的浏览器授权流程
20
+ - **OAuth token 交换报 `code, code_verifier, client_id, redirect_uri are required`**:client 从持久化读取时内存闭包为 null,token 请求缺 `client_id`。修复:exchange 改用 provider 访问器(内存优先、持久化回退)
21
+ - **OAuth 并发授权端口冲突**:回调端口稳定后,挂载与测试连接同时授权会抢同一端口(EADDRINUSE)。修复:同服务器授权流程串行化
22
+ - **环境变量 secret 值未写入凭据**:编辑器保存 secret 行时丢弃了值。修复:填写值即提交(secret 写入凭据文档),留空保留原值
23
+
10
24
  ## [1.4.0] - 2026-08-16
11
25
 
12
26
  ### 新增
package/README.en.md CHANGED
@@ -118,13 +118,56 @@ Append to `$DSH_HOME/profiles/web/cordis.patch.yml` (`$DSH_HOME` defaults to `~/
118
118
  name: dsh-mcp
119
119
  ```
120
120
 
121
- Then **restart `dsh web`** (client roster changes require a restart); afterwards hard-refresh the browser
122
- (`Cmd/Ctrl + Shift + R`) to load the settings page.
121
+ > ⚠️ **This step is mandatory**: dsh-mcp does not declare `dsh.bundle`, so `dsh plugin add` only
122
+ > installs the package into the profile — **it does not activate the plugin**. Without the
123
+ > registration row the plugin never mounts.
124
+
125
+ Then **restart `dsh web`** and **hard-refresh the browser** (`Cmd/Ctrl + Shift + R`):
126
+
127
+ > ⚠️ **Both the restart and the hard refresh are required**:
128
+ > - The settings page (client half) needs the **client roster**, and roster changes only take
129
+ > effect after **restarting `dsh web`** (refreshing the browser alone is not enough);
130
+ > - After the restart you must **hard-refresh** (`Cmd/Ctrl + Shift + R`) — a normal reload may
131
+ > keep serving the cached old page.
123
132
 
124
133
  ### 3. Usage
125
134
 
126
135
  **Open the management page**: after restart, open DSH Web → **Settings → MCP**.
127
136
 
137
+ ### 4. Troubleshooting
138
+
139
+ **Q1: No "MCP" entry in Settings after installing?**
140
+
141
+ Check in order:
142
+
143
+ 1. **Is the plugin registered?** Confirm `$DSH_HOME/profiles/web/cordis.patch.yml` has the
144
+ `- insert: [{ id: dsh-mcp, name: dsh-mcp }]` row (`id`/`name` must exactly match the package
145
+ name `dsh-mcp`). `dsh plugin add` does not equal activation — **without the registration row
146
+ the plugin never mounts**.
147
+ 2. **Did you restart `dsh web`?** Refreshing the browser is not enough — the settings entry comes
148
+ from the client roster, and roster changes require **restarting the process**.
149
+ 3. **Did you hard-refresh the browser?** After the restart use `Cmd/Ctrl + Shift + R`
150
+ (Windows/Linux: `Ctrl + Shift + R`); a plain `F5` may load a cached old page.
151
+ 4. **Is it installed in the right profile?** Make sure both the install and the registration use
152
+ the `web` profile (`dsh plugin --profile web add dsh-mcp` +
153
+ `$DSH_HOME/profiles/web/cordis.patch.yml`); other profiles have their own settings pages.
154
+ 5. **Is it the latest version?** npm metadata caching can pin an old version; force the version
155
+ with `dsh plugin --profile web add dsh-mcp@latest` (or `@1.4.0`).
156
+
157
+ **Q2: "MCP" is visible but the server list is empty or errors?**
158
+
159
+ - Check the `dsh web` process log for `mcp-manager` initialization errors;
160
+ - After upgrading the plugin, restart and **hard-refresh** so the old client bundle does not
161
+ mix with the new host (typical symptom: `client api: ... 404` or `env is not iterable` — both
162
+ come from mixing versions).
163
+
164
+ **Q3: MCP tools do not show up in an agent session?**
165
+
166
+ - Make sure the server status is "Connected" and its tools are checked (all checked by default);
167
+ - In "On-demand search" mode the model discovers tools via `mcp_tool_search` and hot-injects them,
168
+ so tools not searched are absent from the system prompt by design; switch to "Full injection"
169
+ to verify.
170
+
128
171
  **Add a server**:
129
172
 
130
173
  1. Click **Add server** (the form expands inline above the list).
@@ -136,6 +179,10 @@ Then **restart `dsh web`** (client roster changes require a restart); afterwards
136
179
 
137
180
  - Configure global key-value pairs referenced by every server's header substitution;
138
181
  secret values are stored in the credentials document, a blank value keeps the stored one
182
+ - **process.env wins**: if a variable already exists in the process environment (`process.env`)
183
+ under the same name, that value is used verbatim (name unchanged) at connect/display time and
184
+ stored values only act as fallback — export it in your startup script first
185
+ (e.g. `export ADA_TOKEN=...`) then restart `dsh web`
139
186
  - Batch-add (paste one `NAME=value` per line) or add rows one by one
140
187
  - A header value can reference a variable by **bare name** or **`${NAME}`** (e.g. `Authorization: Bearer ${GITLAB_TOKEN}`),
141
188
  substituted at connect time (priority: server env > process-level env > system environment)
package/README.md CHANGED
@@ -105,13 +105,50 @@ dsh plugin --profile web add link:<本仓库绝对路径>
105
105
  name: dsh-mcp
106
106
  ```
107
107
 
108
- 然后**重启 `dsh web`**(client roster 变更需重启);之后浏览器硬刷新(`Cmd/Ctrl + Shift + R`)
109
- 加载设置页。
108
+ > ⚠️ **这一步必须手动完成**:dsh-mcp 未声明 `dsh.bundle`,`dsh plugin add` 只负责把包装进
109
+ > profile,**不会自动进入运行组合**。漏掉注册行则插件完全不生效。
110
+
111
+ 然后**重启 `dsh web`**,并**硬刷新浏览器**(`Cmd/Ctrl + Shift + R`):
112
+
113
+ > ⚠️ **重启 + 硬刷新缺一不可**:
114
+ > - 设置页(client 半部)需要 **client roster** 生效,**插件集变更必须重启 `dsh web`**(刷新浏览器不够);
115
+ > - 重启后浏览器必须**硬刷新**(`Cmd/Ctrl + Shift + R`),普通刷新可能仍使用缓存的旧页面。
110
116
 
111
117
  ### 3. 使用
112
118
 
113
119
  **打开管理页**:重启后浏览器打开 DSH Web → **设置(Settings)→ MCP**。
114
120
 
121
+ ### 4. 常见问题排查
122
+
123
+ **Q1:安装后设置页看不到「MCP」?**
124
+
125
+ 按顺序检查:
126
+
127
+ 1. **是否已注册插件行**:确认 `$DSH_HOME/profiles/web/cordis.patch.yml` 已追加
128
+ `- insert: [{ id: dsh-mcp, name: dsh-mcp }]`(`id`/`name` 必须与插件包名 `dsh-mcp` 完全一致)。
129
+ `dsh plugin add` 不等于生效,**没有注册行插件不会挂载**。
130
+ 2. **是否重启了 `dsh web`**:仅刷新浏览器不够——设置页入口来自 client roster,
131
+ 插件集变更必须**重启进程**才进入 roster。
132
+ 3. **是否硬刷新了浏览器**:重启后用 `Cmd/Ctrl + Shift + R`(Windows/Linux:`Ctrl + Shift + R`)
133
+ 强制刷新;普通 `F5` 可能加载缓存的旧页面。
134
+ 4. **是否装到了正确的 profile**:确认安装与注册都在 `web` profile
135
+ (`dsh plugin --profile web add dsh-mcp` + `$DSH_HOME/profiles/web/cordis.patch.yml`);
136
+ 装到其他 profile 则在其他 profile 的设置页查看。
137
+ 5. **是否为最新版本**:npm 元数据缓存可能导致装到旧版,可强制指定版本
138
+ `dsh plugin --profile web add dsh-mcp@latest`(或 `@1.4.0`)。
139
+
140
+ **Q2:设置页能看到「MCP」,但服务器列表为空/报错?**
141
+
142
+ - 确认 `dsh web` 进程日志中 `mcp-manager` 没有初始化错误;
143
+ - 若升级过插件,请重启后**硬刷新**,避免旧 client bundle 与新版 host 不匹配
144
+ (典型现象:操作报 `client api: ... 404` 或 `env is not iterable`,都是新旧版本混用所致)。
145
+
146
+ **Q3:MCP 工具没有出现在 agent 会话里?**
147
+
148
+ - 确认对应服务器状态为「已连接」且工具已勾选(默认全选);
149
+ - 注入模式为「按需检索」时,模型会通过 `mcp_tool_search` 检索后热注入,未检索到的工具不在
150
+ 系统提示词中属正常现象;可切换到「全量注入」验证。
151
+
115
152
  **添加服务器**:
116
153
 
117
154
  1. 点击「添加服务器」(表单在列表上方就地展开)
@@ -122,6 +159,8 @@ dsh plugin --profile web add link:<本仓库绝对路径>
122
159
  **进程环境变量**(注入模式下方,默认展开):
123
160
 
124
161
  - 配置全局键值对,供所有服务器的请求头替换引用;secret 值写入凭据文档,留空保留原值
162
+ - **process.env 优先**:若变量在进程环境变量(`process.env`)中已存在同名值,连接/展示时直接采用该值(不改名),
163
+ 存储值仅作为兜底——请先在启动脚本里 `export ADA_TOKEN=...` 再重启 `dsh web`
125
164
  - 支持「批量添加」(粘贴多行 `NAME=value`)与「添加变量」逐行添加
126
165
  - 服务器请求头 value 可直接写**变量名**或 **`${变量名}`**(如 `Authorization: Bearer ${GITLAB_TOKEN}`),
127
166
  连接时自动替换(优先级:服务器 env > 进程级 env > 系统环境变量)