dsh-mcp-connector 0.2.54 → 0.2.56
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.md +13 -0
- package/README.en.md +1 -1
- package/README.md +1 -1
- package/docs/CLI-PROVIDERS.md +5 -1
- package/docs/USER-GUIDE.md +65 -0
- package/lib/cli-providers.js +50 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.2.56] - 2026-09-22
|
|
8
|
+
|
|
9
|
+
### Documentation
|
|
10
|
+
|
|
11
|
+
- 补充 macOS/Linux 与 Windows PowerShell 的 stdio 启动排查示例,说明 PATH、command/args、cwd、退出码及无 shell 启动的安全边界(#29)。
|
|
12
|
+
|
|
13
|
+
## [0.2.55] - 2026-09-22
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Windows 钉钉 CLI 桥接解析官方 npm 包内原生 `dws.exe`,覆盖全局与 npx 布局,不执行 cmd shim,保持 shell:false;允许带空格的显式绝对路径并提供安装/原生文件缺失诊断(#91)。
|
|
18
|
+
- 精确迁移标准受管钉钉 0.2.48/0.2.49 桥接到 0.2.55,保留自定义命令、参数、环境和授权配置。
|
|
19
|
+
|
|
7
20
|
## [0.2.54] - 2026-09-21
|
|
8
21
|
|
|
9
22
|
### Fixed
|
package/README.en.md
CHANGED
|
@@ -190,7 +190,7 @@ npm run dev:ui
|
|
|
190
190
|
|
|
191
191
|
Every Registry merge regenerates `catalog-stats.json`; an hourly workflow in this repository synchronizes the Chinese and English product copy plus a local stats snapshot. The static npm README updates with package releases, while the live badges above read the Registry directly and therefore stay current without another npm release.
|
|
192
192
|
|
|
193
|
-
The current public version is [`dsh-mcp-connector@0.2.
|
|
193
|
+
The current public version is [`dsh-mcp-connector@0.2.56`](https://www.npmjs.com/package/dsh-mcp-connector), with [GitHub Release v0.2.56](https://github.com/duhu2000/dsh-mcp-connector/releases/tag/v0.2.56).
|
|
194
194
|
|
|
195
195
|
See [CHANGELOG.md](CHANGELOG.md) for version history and [docs/DESKTOP-E2E.md](docs/DESKTOP-E2E.md) for the Desktop release checklist.
|
|
196
196
|
|
package/README.md
CHANGED
|
@@ -185,7 +185,7 @@ npm run dev:ui
|
|
|
185
185
|
|
|
186
186
|
公共 Registry 每次合并后会生成 `catalog-stats.json`;本仓库的定时工作流每小时同步中英文介绍和统计快照。npm 页面中的静态正文随版本发布更新,上方动态统计徽标则直接读取 Registry,可在不发布新 npm 版本时保持实时数量一致。
|
|
187
187
|
|
|
188
|
-
当前公开版本为 [`dsh-mcp-connector@0.2.
|
|
188
|
+
当前公开版本为 [`dsh-mcp-connector@0.2.56`](https://www.npmjs.com/package/dsh-mcp-connector),对应 [GitHub Release v0.2.56](https://github.com/duhu2000/dsh-mcp-connector/releases/tag/v0.2.56)。
|
|
189
189
|
|
|
190
190
|
版本能力与变更记录见 [CHANGELOG.md](CHANGELOG.md)。
|
|
191
191
|
Desktop 发版回归见 [docs/DESKTOP-E2E.md](docs/DESKTOP-E2E.md)。
|
package/docs/CLI-PROVIDERS.md
CHANGED
|
@@ -34,7 +34,7 @@ MCP 连接器原生支持 Streamable HTTP 和 stdio MCP。对于钉钉 `dws` 这
|
|
|
34
34
|
"-y",
|
|
35
35
|
"--legacy-peer-deps",
|
|
36
36
|
"--package",
|
|
37
|
-
"dsh-mcp-connector@0.2.
|
|
37
|
+
"dsh-mcp-connector@0.2.55",
|
|
38
38
|
"--package",
|
|
39
39
|
"dingtalk-workspace-cli@1.0.61",
|
|
40
40
|
"dsh-mcp-cli-bridge",
|
|
@@ -48,6 +48,10 @@ MCP 连接器原生支持 Streamable HTTP 和 stdio MCP。对于钉钉 `dws` 这
|
|
|
48
48
|
|
|
49
49
|
## 首批只读能力
|
|
50
50
|
|
|
51
|
+
Windows 从 DSH 进程 PATH 中的全局 npm 或 npx `.bin` 位置查找官方包,直接运行包内 `vendor/dws.exe`;不执行 `.cmd`/`.bat`/`.ps1`,不启用 shell。也可在启动 DSH 的环境中设置 `DSH_MCP_DINGTALK_DWS_BIN` 为原生 exe 的绝对路径(允许空格),随后重启 DSH。无需复制 exe 到 npm 前缀;复制品可能在 CLI 升级后过期。缺失程序不等于 OAuth 未登录。
|
|
52
|
+
|
|
53
|
+
升级主插件并重启后,标准受管钉钉 0.2.48/0.2.49 桥接参数会在加载时迁移到 0.2.55;自定义命令和参数不自动修改,需自行更新固定桥接版本。授权信息和环境配置保持不变。
|
|
54
|
+
|
|
51
55
|
- 当前用户、通讯录搜索与用户详情
|
|
52
56
|
- 日程列表与日程详情
|
|
53
57
|
- 待办列表与待办详情
|
package/docs/USER-GUIDE.md
CHANGED
|
@@ -297,6 +297,71 @@ OAuth 断开时,插件会尽力调用服务商的撤销端点;无撤销端
|
|
|
297
297
|
|
|
298
298
|
页面会在有限时间内结束等待,并区分命令不存在、进程退出、初始化失败或启动超时。先在终端确认命令本身可执行、软件包可信、Node/运行时版本满足要求,并检查 `cwd`、参数和环境变量;随后查看 Host 日志并点击“重新检查”。不要把本机凭据写入公开 Registry descriptor。
|
|
299
299
|
|
|
300
|
+
#### 1. 确认命令与运行环境
|
|
301
|
+
|
|
302
|
+
stdio 会以当前用户权限在 DSH 所在机器上启动进程,只运行你信任的软件包和命令。先从连接配置记录 `command`、每个 `args` 元素、`cwd` 和所需环境变量名称;不要复制或公开凭据值。以下使用 Node 演示,其他运行时请替换为实际命令。
|
|
303
|
+
|
|
304
|
+
macOS / Linux(终端):
|
|
305
|
+
|
|
306
|
+
```sh
|
|
307
|
+
command -v node
|
|
308
|
+
node --version
|
|
309
|
+
pwd
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Windows(PowerShell):
|
|
313
|
+
|
|
314
|
+
```powershell
|
|
315
|
+
Get-Command node -All | Select-Object CommandType, Source
|
|
316
|
+
node --version
|
|
317
|
+
Get-Location
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
若找不到命令,先按可信软件的官方安装说明配置运行时,再重新打开终端和 DSH。核对服务要求的运行时版本。终端能找到命令,不代表桌面启动的 DSH 具有相同的 `PATH`;版本管理器、别名或 shell 函数也不一定对 DSH 可见。此时可将 `command` 改为本机实际可执行文件的绝对路径,不要填终端别名。
|
|
321
|
+
|
|
322
|
+
#### 2. 在相同目录复现同一 command + args
|
|
323
|
+
|
|
324
|
+
以下路径是占位符,必须替换为本机已安装、可信服务的实际路径;示例不下载软件、不需要账号或凭据。假设配置的 `command` 是 Node 的绝对路径,`args` 仅包含服务入口文件的绝对路径:
|
|
325
|
+
|
|
326
|
+
macOS / Linux:
|
|
327
|
+
|
|
328
|
+
```sh
|
|
329
|
+
(
|
|
330
|
+
cd '/absolute/path/to/trusted-server' || exit 1
|
|
331
|
+
'/absolute/path/to/node' '/absolute/path/to/trusted-server/server.js'
|
|
332
|
+
result=$?
|
|
333
|
+
printf 'exit code: %s\n' "$result"
|
|
334
|
+
)
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Windows PowerShell:
|
|
338
|
+
|
|
339
|
+
```powershell
|
|
340
|
+
Push-Location -LiteralPath 'C:\path\to\trusted-server' -ErrorAction Stop
|
|
341
|
+
try {
|
|
342
|
+
& 'C:\path\to\node.exe' 'C:\path\to\trusted-server\server.js'
|
|
343
|
+
Write-Output "exit code: $LASTEXITCODE"
|
|
344
|
+
} finally {
|
|
345
|
+
Pop-Location
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
按自己的配置逐项替换参数,不要把整条终端命令塞进 `command`,也不要把所有参数合并成一个字符串。带空格的路径在终端中需要引用;在配置的 `command` 或 `args` 字符串值中保留路径本身,不额外添加 shell 引号。只有服务依赖相对路径时,才需特别核对配置中的 `cwd` 是否存在、可访问且符合服务要求。所需环境变量应在本机安全配置,不要在反馈中粘贴完整 `env` 或包含密钥的命令行。
|
|
350
|
+
|
|
351
|
+
Windows 下 `.cmd` / `.bat` 是脚本包装器,不等同于可直接启动的 `.exe`;PowerShell 中能运行包装器,不代表无 shell 的进程启动也能运行它。若诊断指向包装器,按该服务文档选择原生可执行文件,或用 Node 运行其可信 JavaScript 入口。不要通过设置 `shell: true`、关闭安全检查或执行策略绕过来解决。
|
|
352
|
+
|
|
353
|
+
#### 3. 根据结果定位,再回到页面复查
|
|
354
|
+
|
|
355
|
+
| 观察结果 | 排查方法 |
|
|
356
|
+
|---|---|
|
|
357
|
+
| 命令不存在 / 路径不存在 | 核对运行时安装、绝对路径及 DSH 进程的 `PATH`;同时确认 `cwd` 存在 |
|
|
358
|
+
| 进程立即非零退出 | 查看本地标准错误输出和退出码,核对参数、依赖、运行时版本、文件权限及所需环境变量 |
|
|
359
|
+
| 进程退出码为 0,但没有工具 | 确认启动的是 MCP stdio 服务,不是版本查询、安装器或一次性命令;退出成功不代表 MCP 初始化成功 |
|
|
360
|
+
| 进程一直等待、没有输出 | stdio 服务可能正在等待客户端输入,这是正常可能性;终端启动只能验证进程,不证明 MCP 握手成功。可按 Ctrl+C 结束,再由 DSH 发起检查 |
|
|
361
|
+
| 终端能启动,页面初始化失败 / 超时 | 对比 DSH 的 command/args/env/cwd,查看 Host 日志;确认服务支持 MCP stdio,且普通日志未污染用于协议通信的 stdout(日志应写 stderr) |
|
|
362
|
+
|
|
363
|
+
修正后重新启动 DSH(如变更了进程环境),在连接详情点击“重新检查”,确认工具发现结果。反馈时只提交版本、脱敏后的诊断代码、退出码和必要日志;不要上传 Token、API Key、完整环境变量或个人路径。
|
|
364
|
+
|
|
300
365
|
### 为什么显示“状态未知”
|
|
301
366
|
|
|
302
367
|
这表示插件没有足够证据确认健康或失败,常见于 DSH 刚重启、尚未执行健康检查,或当前 Host 无法读取 stdio 工具注册状态。点击“刷新连接器目录”或进入详情重新检查;若仍为未知,根据诊断的 `code` 和建议查看 Host 日志或升级 Host。不要把“状态未知”理解为“已连接”。
|
package/lib/cli-providers.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
+
import { existsSync, readFileSync, realpathSync, statSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
2
4
|
|
|
3
5
|
const MAX_OUTPUT_BYTES = 1024 * 1024;
|
|
4
6
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
@@ -198,8 +200,8 @@ export function listCliProviderTools(providerId) {
|
|
|
198
200
|
|
|
199
201
|
function assertSafeExecutable(executable) {
|
|
200
202
|
const value = String(executable ?? '').trim();
|
|
201
|
-
if (!value || /[\0\r\n]/.test(value) || /\s/.test(value)) {
|
|
202
|
-
throw new Error('CLI executable must be one command name or an absolute path
|
|
203
|
+
if (!value || /[\0\r\n]/.test(value) || (/\s/.test(value) && !path.isAbsolute(value) && !path.win32.isAbsolute(value))) {
|
|
204
|
+
throw new Error('CLI executable must be one command name or an absolute path');
|
|
203
205
|
}
|
|
204
206
|
return value;
|
|
205
207
|
}
|
|
@@ -290,11 +292,48 @@ export function redactCliError(value) {
|
|
|
290
292
|
.trim();
|
|
291
293
|
}
|
|
292
294
|
|
|
295
|
+
// Resolve only the known provider package; never interpret or execute a shell shim.
|
|
296
|
+
export function resolveCliExecutable(command, options = {}) {
|
|
297
|
+
const platform = options.platform ?? process.platform;
|
|
298
|
+
const env = options.env ?? process.env;
|
|
299
|
+
if (platform !== 'win32') return command;
|
|
300
|
+
if (/\.(cmd|bat|ps1)$/i.test(command)) throw new Error('[CLI_SHIM_UNSUPPORTED] 请指定原生 exe,而非 shell 启动脚本');
|
|
301
|
+
if (command !== 'dws') return command; // Explicit override stays authoritative.
|
|
302
|
+
const pathValue = Object.entries(env).find(([key]) => key.toLowerCase() === 'path')?.[1] ?? '';
|
|
303
|
+
let sawShim = false;
|
|
304
|
+
for (const raw of pathValue.split(';')) {
|
|
305
|
+
const dir = raw.replace(/^"(.*)"$/, '$1');
|
|
306
|
+
if (!path.isAbsolute(dir)) continue; // Never search cwd or relative PATH entries.
|
|
307
|
+
const native = path.join(dir, 'dws.exe');
|
|
308
|
+
if (existsSync(native) && statSync(native).isFile()) return native;
|
|
309
|
+
if (existsSync(path.join(dir, 'dws.cmd'))) sawShim = true;
|
|
310
|
+
const roots = path.basename(dir).toLowerCase() === '.bin'
|
|
311
|
+
? [path.join(dir, '..', 'dingtalk-workspace-cli')]
|
|
312
|
+
: [path.join(dir, 'node_modules', 'dingtalk-workspace-cli')];
|
|
313
|
+
for (const root of roots) {
|
|
314
|
+
if (!existsSync(path.join(root, 'package.json'))) continue;
|
|
315
|
+
try {
|
|
316
|
+
const pkg = JSON.parse(readFileSync(path.join(root, 'package.json'), 'utf8'));
|
|
317
|
+
if (pkg.name !== 'dingtalk-workspace-cli' || pkg.bin?.dws !== 'bin/dws.js') continue;
|
|
318
|
+
const realRoot = realpathSync(root);
|
|
319
|
+
const binary = realpathSync(path.join(root, 'vendor', 'dws.exe'));
|
|
320
|
+
const relative = path.relative(realRoot, binary);
|
|
321
|
+
if (relative.startsWith('..') || path.isAbsolute(relative) || !statSync(binary).isFile()) continue;
|
|
322
|
+
return binary;
|
|
323
|
+
} catch { /* Missing/corrupt packages must fail closed, not launch a shim. */ }
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
throw new Error(sawShim
|
|
327
|
+
? '[CLI_NATIVE_MISSING] 已发现 dws npm 启动脚本,但未找到有效的官方原生程序;请检查 CLI 安装,或通过 DSH_MCP_DINGTALK_DWS_BIN 指定 dws.exe'
|
|
328
|
+
: '[CLI_NOT_FOUND] DSH 进程 PATH 中未找到 dws 原生程序或官方 npm 包;请检查安装与 DSH 环境后重启,不代表 OAuth 未登录');
|
|
329
|
+
}
|
|
330
|
+
|
|
293
331
|
export function runCliProcess(command, args, options = {}) {
|
|
294
332
|
const timeoutMs = Number.isInteger(options.timeoutMs) ? options.timeoutMs : DEFAULT_TIMEOUT_MS;
|
|
295
333
|
const maxOutputBytes = Number.isInteger(options.maxOutputBytes) ? options.maxOutputBytes : MAX_OUTPUT_BYTES;
|
|
296
334
|
return new Promise((resolve, reject) => {
|
|
297
|
-
const
|
|
335
|
+
const executable = resolveCliExecutable(command, options);
|
|
336
|
+
const child = spawn(executable, args, {
|
|
298
337
|
shell: false,
|
|
299
338
|
windowsHide: true,
|
|
300
339
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
@@ -399,12 +438,17 @@ export async function ensureCliProviderReady(providerId, options = {}) {
|
|
|
399
438
|
// Upgrade only the exact managed legacy invocation; preserve custom commands,
|
|
400
439
|
// environment, cwd and credentials. Applied on every provision, including restore.
|
|
401
440
|
export function cliBridgeArgs(record) {
|
|
402
|
-
const legacy = ['--yes', '--legacy-peer-deps', '--package',
|
|
441
|
+
const legacy = ['--yes', '--legacy-peer-deps', '--package', argsVersion(record),
|
|
403
442
|
'--package', 'dingtalk-workspace-cli@1.0.61', 'dsh-mcp-cli-bridge', '--provider', 'dingtalk-dws'];
|
|
404
443
|
const args = record.args ?? [];
|
|
405
|
-
if (record.connectorId !== 'dingtalk' || record.command !== 'npx'
|
|
444
|
+
if (!legacy[3] || record.connectorId !== 'dingtalk' || record.command !== 'npx'
|
|
406
445
|
|| JSON.stringify(args) !== JSON.stringify(legacy)) return args;
|
|
407
|
-
return args.map((arg) => arg ===
|
|
446
|
+
return args.map((arg) => arg === legacy[3] ? 'dsh-mcp-connector@0.2.55' : arg);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function argsVersion(record) {
|
|
450
|
+
const value = record.args?.[3];
|
|
451
|
+
return ['dsh-mcp-connector@0.2.48', 'dsh-mcp-connector@0.2.49'].includes(value) ? value : null;
|
|
408
452
|
}
|
|
409
453
|
|
|
410
454
|
export async function handleCliBridgeRequest(message, options = {}) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-mcp-connector",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.56",
|
|
4
4
|
"description": "DeepSeek Harness MCP Connector: connect servers, search tools across active connections, and troubleshoot discovery. Includes a continuously updated catalog; supports OAuth 2.0 PKCE, API keys, Streamable HTTP/stdio, and mcpServers JSON import.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|