dsh-mcp 1.11.0 → 1.12.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 +28 -0
- package/CHANGELOG.md +28 -0
- package/README.en.md +6 -0
- package/README.md +9 -0
- package/lib/client.js +77 -25
- package/lib/index.js +92 -28
- package/lib/mcp-client.js +14 -12
- package/lib/oauth.js +14 -1
- package/lib/probe.js +6 -8
- package/lib/transport.js +2 -2
- package/package.json +6 -1
- package/src/client/McpSettingsSection.tsx +1 -0
- package/src/client/ServerForm.tsx +10 -0
- package/src/client/ServersJsonEditor.tsx +2 -0
- package/src/client/locales.ts +4 -0
- package/src/client/mcp-store.ts +7 -0
- package/src/client/remote-contribution.js +28 -0
- package/src/client/types.ts +4 -0
package/CHANGELOG.en.md
CHANGED
|
@@ -7,6 +7,34 @@ 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
|
+
## Compatibility
|
|
11
|
+
|
|
12
|
+
- **Supported DSH version**: **dsh `0.1.6-alpha.2`** — developed and verified on `0.1.6-alpha.2` (declared in `package.json` → `dsh.supported`). When the DSH and plugin versions do not match, the Settings page reports a diagnosis (check the `cordis.patch.yml` row → restart `dsh web` → hard-refresh → upgrade both sides).
|
|
13
|
+
- **Release convention**: every version entry states `- **Supported DSH version**: dsh <version>`, mirrored in the GitHub Release notes.
|
|
14
|
+
|
|
15
|
+
## [1.12.0] - 2026-09-18
|
|
16
|
+
|
|
17
|
+
- **Supported DSH version**: **dsh `0.1.6-alpha.2`**
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- **Migrated to the official split MCP SDK 2.0 packages**: since DSH `0.1.6-alpha.1`, the in-box `dsh-mcp-client` derives from `@modelcontextprotocol/{client,server,node}@2.0.0` instead of the monolithic `@modelcontextprotocol/sdk@1.x`, and the old package is no longer a DSH dependency. This plugin migrates with it (`lib/transport.js`, `lib/probe.js`, `lib/mcp-client.js`, `lib/oauth.js`) and declares `@modelcontextprotocol/client@2.0.0` and `zod@^4.2.0` explicitly in `package.json` instead of relying on the host profile's dependency hoisting — without this, DSH `0.1.6-alpha.1` fails the plugin load with `ERR_MODULE_NOT_FOUND: Cannot find package '@modelcontextprotocol/sdk'`, taking the Settings page and tool search down with it
|
|
22
|
+
- **Adapted to two breaking changes in SDK 2.0**: `Client` options no longer accept `authProvider` (the OAuth provider now travels on the **transport**; this plugin's `createTransport` already reads `config.authProvider` and passes it to the transport, so the OAuth flow is unchanged), and `setNotificationHandler`'s first argument is now a **method name** rather than a schema, so the tool-list-changed notification registers as `notifications/tools/list_changed`
|
|
23
|
+
- **Result schemas now come from the new package's `specTypeSchemas`**: `ListToolsResultSchema` → `specTypeSchemas.ListToolsResult`; `ToolListChangedNotificationSchema` is no longer needed since notifications register by method name
|
|
24
|
+
- **Regenerated the client half for the Typert `create()` contract**: the `@deepseek-ai/dsh-typert-generator` output in `src/client/remote-contribution.js` carried only `schema: TypertSchema`, but since DSH `0.1.6-alpha.1` that field is `create: () => TypertSchema` and the registry calls it unconditionally (`record.value ??= record.create()`) — so the Settings page's Remote descriptors threw `create is not a function` on mount and the whole MCP settings page failed. Regenerated with the current generator (all 21 strict descriptors now carry `create`) and rebuilt `lib/client.js` to match. This stayed hidden because the long-running host had been on `0.1.5-rc.1` since Sep 14, whose contract was still `schema`
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **The "do not open a browser from a tool call" OAuth guard works again**: `startConnection`'s `opts` never carried `url` or `authProvider`, so the branch that should return an authorization link when a stored token is missing or expired never ran — the SDK opened a browser mid-tool-call instead (a single session could open several tabs). `opts` now carries both fields, restoring the documented behavior
|
|
29
|
+
|
|
30
|
+
## [1.11.1] - 2026-09-13
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- **OAuth is now an explicit switch instead of a header guess (no more repeated browser authorizations)**: the previous rule was "streamable-http without an `Authorization` header gets an OAuth provider", so servers that authenticate with static tokens or custom headers (`x-bbzai-mcp-token`, `X-Mcp-Token`, `Private-Token`) were treated as OAuth servers. When such a server answered 401 (a stale token, a gateway challenge), the SDK asked for authorization, the plugin opened the browser and started its loopback callback (`127.0.0.1:<port>/callback`) — a flow that could never satisfy those servers, so every reconnect or remount opened the browser again. A stored server now has an **`oauth: true`** switch (the form's "Use OAuth authorization" checkbox, off by default; taking over a declaration without an `Authorization` header ticks it, and it stays editable)
|
|
35
|
+
- **Upgrade migration**: servers that already hold OAuth credentials (a token or a client registration) keep `oauth: true`, everything else is turned off — so servers that genuinely need OAuth keep working while the misdetected ones stop opening the browser
|
|
36
|
+
- **Automatic-authorization circuit breaker**: the plugin opens the browser **at most once per server per process**; later automatic attempts return the authorization-link error instead (the 1.8.0 behaviour), and "Test connection" can still start an authorization on demand
|
|
37
|
+
|
|
10
38
|
## [1.11.0] - 2026-09-13
|
|
11
39
|
|
|
12
40
|
### Added
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,34 @@
|
|
|
7
7
|
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
|
|
8
8
|
版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
|
9
9
|
|
|
10
|
+
## 兼容性
|
|
11
|
+
|
|
12
|
+
- **支持版本**:**dsh `0.1.6-alpha.2`** —— 本插件在 `0.1.6-alpha.2` 上开发与验证(`package.json` → `dsh.supported` 同步声明)。DSH 与插件版本不匹配时,设置页会给出排查诊断(核对 `cordis.patch.yml` 注册行 → 重启 `dsh web` → 硬刷新 → 同步升级)。
|
|
13
|
+
- **发版约定**:每个版本条目都要声明 `- **支持版本**:dsh <版本>`,并在 GitHub Release notes 中同步。
|
|
14
|
+
|
|
15
|
+
## [1.12.0] - 2026-09-18
|
|
16
|
+
|
|
17
|
+
- **支持版本**:**dsh `0.1.6-alpha.2`**
|
|
18
|
+
|
|
19
|
+
### 变更
|
|
20
|
+
|
|
21
|
+
- **迁移到官方 MCP SDK 2.0 拆分包**:DSH `0.1.6-alpha.1` 起,框架内的 `dsh-mcp-client` 已从单体包 `@modelcontextprotocol/sdk@1.x` 迁到 `@modelcontextprotocol/{client,server,node}@2.0.0`,旧包不再是 DSH 的依赖。本插件同步迁移 `lib/transport.js`、`lib/probe.js`、`lib/mcp-client.js`、`lib/oauth.js`,并在 `package.json` 显式声明 `@modelcontextprotocol/client@2.0.0` 与 `zod@^4.2.0`,不再依赖宿主 profile 的依赖提升——否则在 DSH `0.1.6-alpha.1` 上会以 `ERR_MODULE_NOT_FOUND: Cannot find package '@modelcontextprotocol/sdk'` 加载失败,设置页与 tool search 一并不可用
|
|
22
|
+
- **适配 SDK 2.0 的两处破坏性变更**:其一,`Client` 选项不再接受 `authProvider`,OAuth provider 改由 **transport** 携带(本插件的 `createTransport` 一直从 `config.authProvider` 读取并传给 transport,因此 OAuth 流程行为不变);其二,`setNotificationHandler` 的第一个参数由 schema 改为**方法名**,工具列表变更通知改用 `notifications/tools/list_changed`
|
|
23
|
+
- **结果 schema 改从新包的 `specTypeSchemas` 取**:`ListToolsResultSchema` → `specTypeSchemas.ListToolsResult`;`ToolListChangedNotificationSchema` 不再需要(通知按方法名注册)
|
|
24
|
+
- **重新生成客户端半以适配 Typert `create()` 契约**:`@deepseek-ai/dsh-typert-generator` 生成的 `src/client/remote-contribution.js` 此前只携带 `schema: TypertSchema`,而 DSH 自 `0.1.6-alpha.1` 起把该字段改成 `create: () => TypertSchema`,registry 以 `record.value ??= record.create()` **无条件调用**它——于是设置页的 Remote 描述符在挂载时抛 `create is not a function`,整块 MCP 设置页失效。现已用当前生成器重新生成(21 个 strict 描述符全部补上 `create`)并重建 `lib/client.js`。此前一直没暴露,是因为常驻宿主自 9/14 起跑的是 `0.1.5-rc.1`(当时契约仍是 `schema`)
|
|
25
|
+
|
|
26
|
+
### 修复
|
|
27
|
+
|
|
28
|
+
- **OAuth 工具调用的「不弹浏览器」保护恢复生效**:`startConnection` 的 `opts` 一直缺少 `url` 与 `authProvider` 两个字段,于是「已存 token 缺失/过期时不要从工具调用里打开浏览器,改为返回授权链接」这段判断从未触发——实际行为是让 SDK 在工具调用中弹浏览器(同一会话可能连开多个标签)。现在在 `opts` 中补上这两项,行为回到代码注释所述
|
|
29
|
+
|
|
30
|
+
## [1.11.1] - 2026-09-13
|
|
31
|
+
|
|
32
|
+
### 修复
|
|
33
|
+
|
|
34
|
+
- **OAuth 改为显式开关,不再凭请求头猜测(停止反复弹出浏览器授权)**:此前规则是"streamable-http 且没有 `Authorization` 头 → 挂 OAuth provider",于是用静态 token/自定义头(`x-bbzai-mcp-token`、`X-Mcp-Token`、`Private-Token`)认证的服务器也被当成 OAuth 服务器。这类服务器返回 401 时(token 失效、网关挑战等),SDK 会要求授权 → 插件打开浏览器并起回环回调(`127.0.0.1:<port>/callback`),而该流程永远无法让它们通过 → 每次重连/重挂载就再弹一次。现在服务器配置新增 **`oauth: true`** 开关(设置页勾选「使用 OAuth 授权」,默认关;接管声明时若该声明没有 `Authorization` 头则默认勾上,之后仍可修改)
|
|
35
|
+
- **升级自动迁移**:已存在 OAuth 凭据(token 或 client 注册记录)的服务器会保留 `oauth: true`,其余一律关闭——因此**现有真正需要 OAuth 的服务器不受影响,误判的那批立刻停止弹窗**
|
|
36
|
+
- **自动弹窗熔断**:同一服务器**每个进程最多自动打开一次**浏览器授权;之后的自动尝试不再弹窗,改为返回带授权链接的错误(沿用 1.8.0 的能力),手动点「测试连接」仍可随时发起授权
|
|
37
|
+
|
|
10
38
|
## [1.11.0] - 2026-09-13
|
|
11
39
|
|
|
12
40
|
### 新增
|
package/README.en.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://dshfind.com/en/plugins/ArvinQi/dsh-mcp?ref=badge)
|
|
4
4
|
|
|
5
|
+
> **Supported DSH version**: `dsh 0.1.6-alpha.2` — developed and verified on `0.1.6-alpha.2`, declared in `package.json` → `dsh.supported`. When the DSH and plugin versions do not match, the Settings page shows a diagnosis (check the registration row → restart `dsh web` → hard-refresh → upgrade both sides).
|
|
6
|
+
|
|
5
7
|

|
|
6
8
|
|
|
7
9
|
## Why dsh-mcp?
|
|
@@ -78,6 +80,7 @@ Since 1.11.0 those declarations appear in Settings → MCP, badged "cordis decla
|
|
|
78
80
|
- **Imported into storages as mirrors**: at startup and on every refresh the declarations are imported into the storage domain (id `cordis:<rowId>`, with `origin/declaredIn/declaredRowId`), **import only** — a row created in the plugin is never overwritten; a mirror whose declaration disappeared is **removed automatically** (a mirror is only a copy of a declaration, so an ownerless one must not pile up); a declaration containing a `!!js` expression is skipped and flagged with the reason (its value only resolves inside the Loader). Mirrors are never mounted — the composition owns the mount.
|
|
79
81
|
- **Take over / give back**: clicking "Take over" makes the plugin write an id-targeted `disabled: true` into its own **managed block** in `cordis.patch.yml` (a `.dsh-mcp.bak` backup is taken before the first write; atomic, idempotent, reversible, confined to that block). The declaration releases the `serverName` and the plugin mounts its own row instead — enabling **OAuth authorization, managed credentials, `${VAR}` header substitution and connection tests**. A hard mount failure rolls back automatically (the block is removed and the row returns to mirror state) and reports why; "Give back" hands the mount back to the declaration and deletes the managed row. A declaration without an explicit `id`, or one containing a `!!js` expression, cannot be taken over.
|
|
80
82
|
- **OAuth / placeholder limit (`needsPlugin`)**: a declaration can carry neither an OAuth provider nor `${VAR}` / bare-name placeholder substitution — only the plugin does those. Such a declaration can therefore only work while the plugin owns the mount: the page reports it as **failed with the reason** (not "connecting"), "Give back" makes its tools disappear (the confirmation and the result warning both say so), and taking it over again restores them.
|
|
83
|
+
- **OAuth is an explicit switch (since 1.11.1)**: an OAuth provider is attached only when the server sets `oauth: true` (the form's "Use OAuth authorization" checkbox, off by default). **Do not tick it for servers that authenticate with static tokens or custom headers** — otherwise a 401 is treated as an OAuth challenge and the plugin keeps opening the browser (with its `127.0.0.1:<port>/callback` loopback listener). The plugin also opens the browser **at most once per server per process**; later automatic attempts return the authorization-link error, and "Test connection" can still start one on demand. Upgrading migrates automatically from existing OAuth credentials, so servers that genuinely need OAuth are unaffected.
|
|
81
84
|
- **Safe degradation when the hot reload does not commit**: if the native tools have not unregistered within 5 seconds of writing the disable block (that profile's patch hot reload did not commit — a sibling entry failing its re-apply rolls the whole generation back), the plugin **registers the takeover without mounting** (the managed row is marked `pendingTakeover`); the next dsh start mounts it, and "Give back" reports the same need for a restart. A mount is also always skipped when same-named `mcp__<server>__` tools already exist without a local mount, so the plugin never fights a still-mounted declaration for one name.
|
|
82
85
|
- **Tool search covers them**: search/hot injection and per-tool switches work by `mcp__` prefix across the whole tool set, so declared tools need no extra configuration.
|
|
83
86
|
|
|
@@ -296,6 +299,9 @@ Check in order:
|
|
|
296
299
|
reinstalling (link install).
|
|
297
300
|
- Configuration changes (bundle additions/removals, new plugin rows) require restarting `dsh web` to enter
|
|
298
301
|
the client roster.
|
|
302
|
+
- **Every release must declare its supported DSH version**: add a
|
|
303
|
+
`- **Supported DSH version**: dsh <version>` line to the CHANGELOG entry and the GitHub Release notes, and
|
|
304
|
+
update `package.json` → `dsh.supported` plus the "Supported DSH version" note at the top of this README.
|
|
299
305
|
|
|
300
306
|
## Changelog
|
|
301
307
|
|
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://dshfind.com/zh/plugins/ArvinQi/dsh-mcp?ref=badge)
|
|
6
6
|
|
|
7
|
+
> **支持版本**:`dsh 0.1.6-alpha.2` —— 本插件在 `0.1.6-alpha.2` 上开发与验证,`package.json` → `dsh.supported` 同步声明。DSH 与插件两侧版本不匹配时,设置页会给出排查诊断(检查注册行 → 重启 `dsh web` → 硬刷新 → 同步升级)。
|
|
8
|
+
|
|
7
9
|

|
|
8
10
|
|
|
9
11
|
## 为什么用 dsh-mcp?
|
|
@@ -76,6 +78,11 @@ DSH 原生支持在组合里直接声明 MCP 服务器:**一行一台**,`nam
|
|
|
76
78
|
`${VAR}`/裸变量名占位符——这两件事只有插件会做。因此这类声明**只能由插件挂载**:页面会把它们标为
|
|
77
79
|
**挂载失败并说明原因**(不是"连接中"),「释放」会让工具消失(确认框与结果告警都会提示),恢复只需
|
|
78
80
|
重新「接管」。
|
|
81
|
+
- **OAuth 是显式开关(1.11.1 起)**:服务器配置里的 `oauth: true`(设置页「使用 OAuth 授权」勾选,默认关)
|
|
82
|
+
才会挂 OAuth provider。**用静态 token 或自定义头认证的服务器不要勾**——否则它返回 401 时会被当成 OAuth
|
|
83
|
+
挑战,插件会反复打开浏览器授权(并起 `127.0.0.1:<port>/callback` 回环回调)。另外,同一服务器**每个进程
|
|
84
|
+
最多自动弹一次**浏览器,之后只返回带授权链接的错误;手动「测试连接」仍可随时发起授权。升级时会按已有
|
|
85
|
+
OAuth 凭据自动迁移,真正需要 OAuth 的服务器不受影响。
|
|
79
86
|
- **热重载未提交时的安全降级**:写入停用块后若原生工具 5 秒内没有注销(该 profile 的 patch 热重载未提交,
|
|
80
87
|
例如某个兄弟条目重建失败导致整代回滚),插件会**登记接管但暂不挂载**(管理行标记 `pendingTakeover`),
|
|
81
88
|
重启 dsh 后由插件挂载;「释放」在同样情况下会提示需要重启。此外,挂载前若发现同名 `mcp__<server>__`
|
|
@@ -278,5 +285,7 @@ dsh plugin --profile web add link:<本仓库绝对路径>
|
|
|
278
285
|
- 浏览器半部改 `src/client/*` 后重新 `node scripts/build.mjs`;host 半部改动无需重装
|
|
279
286
|
(link 安装直接生效)。
|
|
280
287
|
- 配置变更(bundles 增删、新插件行)需重启 `dsh web` 才进入 client roster。
|
|
288
|
+
- **每次发版都必须声明支持的 DSH 版本**:在 CHANGELOG 对应条目与 GitHub Release notes 里加一行
|
|
289
|
+
`- **支持版本**:dsh <版本>`,并同步更新 `package.json` 的 `dsh.supported` 与 README 顶部的「支持版本」。
|
|
281
290
|
|
|
282
291
|
[](https://dshfind.com/zh/plugins/ArvinQi/dsh-mcp?ref=badge)
|
package/lib/client.js
CHANGED
|
@@ -14577,6 +14577,7 @@ var _deepseek_ai_dsh_mcp_manager_mcpManager_list_result$schema = external_export
|
|
|
14577
14577
|
})).readonly(),
|
|
14578
14578
|
"toolCallTimeoutMs": external_exports.number().readonly(),
|
|
14579
14579
|
"failOnStartupError": external_exports.boolean().readonly(),
|
|
14580
|
+
"oauth": external_exports.boolean().readonly().optional(),
|
|
14580
14581
|
"status": external_exports.object({
|
|
14581
14582
|
"phase": external_exports.union([external_exports.literal("failed"), external_exports.literal("stopped"), external_exports.literal("mounting"), external_exports.literal("live")]).readonly(),
|
|
14582
14583
|
"tools": external_exports.array(external_exports.string()).readonly(),
|
|
@@ -14622,7 +14623,8 @@ var _deepseek_ai_dsh_mcp_manager_mcpManager_test_parameter_0$schema = external_e
|
|
|
14622
14623
|
"value": external_exports.string().readonly()
|
|
14623
14624
|
})).readonly(),
|
|
14624
14625
|
"toolCallTimeoutMs": external_exports.number().readonly(),
|
|
14625
|
-
"failOnStartupError": external_exports.boolean().readonly()
|
|
14626
|
+
"failOnStartupError": external_exports.boolean().readonly(),
|
|
14627
|
+
"oauth": external_exports.boolean().readonly().optional()
|
|
14626
14628
|
}).readonly(),
|
|
14627
14629
|
"env": external_exports.array(external_exports.object({
|
|
14628
14630
|
"name": external_exports.string().readonly(),
|
|
@@ -14659,7 +14661,8 @@ var _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_parameter_0$schema = external
|
|
|
14659
14661
|
"value": external_exports.string().readonly()
|
|
14660
14662
|
})).readonly(),
|
|
14661
14663
|
"toolCallTimeoutMs": external_exports.number().readonly(),
|
|
14662
|
-
"failOnStartupError": external_exports.boolean().readonly()
|
|
14664
|
+
"failOnStartupError": external_exports.boolean().readonly(),
|
|
14665
|
+
"oauth": external_exports.boolean().readonly().optional()
|
|
14663
14666
|
}).readonly(),
|
|
14664
14667
|
"env": external_exports.array(external_exports.object({
|
|
14665
14668
|
"name": external_exports.string().readonly(),
|
|
@@ -14690,6 +14693,7 @@ var _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_result$schema = external_expo
|
|
|
14690
14693
|
})).readonly(),
|
|
14691
14694
|
"toolCallTimeoutMs": external_exports.number().readonly(),
|
|
14692
14695
|
"failOnStartupError": external_exports.boolean().readonly(),
|
|
14696
|
+
"oauth": external_exports.boolean().readonly().optional(),
|
|
14693
14697
|
"status": external_exports.object({
|
|
14694
14698
|
"phase": external_exports.union([external_exports.literal("failed"), external_exports.literal("stopped"), external_exports.literal("mounting"), external_exports.literal("live")]).readonly(),
|
|
14695
14699
|
"tools": external_exports.array(external_exports.string()).readonly(),
|
|
@@ -14731,7 +14735,8 @@ var _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_parameter_0$schema = exte
|
|
|
14731
14735
|
"value": external_exports.string().readonly()
|
|
14732
14736
|
})).readonly()]).readonly().optional(),
|
|
14733
14737
|
"toolCallTimeoutMs": external_exports.number().readonly().optional(),
|
|
14734
|
-
"failOnStartupError": external_exports.boolean().readonly().optional()
|
|
14738
|
+
"failOnStartupError": external_exports.boolean().readonly().optional(),
|
|
14739
|
+
"oauth": external_exports.boolean().readonly().optional()
|
|
14735
14740
|
}).readonly(),
|
|
14736
14741
|
"env": external_exports.array(external_exports.object({
|
|
14737
14742
|
"name": external_exports.string().readonly(),
|
|
@@ -14767,6 +14772,7 @@ var _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_result$schema = external_
|
|
|
14767
14772
|
})).readonly(),
|
|
14768
14773
|
"toolCallTimeoutMs": external_exports.number().readonly(),
|
|
14769
14774
|
"failOnStartupError": external_exports.boolean().readonly(),
|
|
14775
|
+
"oauth": external_exports.boolean().readonly().optional(),
|
|
14770
14776
|
"status": external_exports.object({
|
|
14771
14777
|
"phase": external_exports.union([external_exports.literal("failed"), external_exports.literal("stopped"), external_exports.literal("mounting"), external_exports.literal("live")]).readonly(),
|
|
14772
14778
|
"tools": external_exports.array(external_exports.string()).readonly(),
|
|
@@ -14887,6 +14893,7 @@ var _deepseek_ai_dsh_mcp_manager_mcpManager_adopt_result$schema = external_expor
|
|
|
14887
14893
|
})).readonly(),
|
|
14888
14894
|
"toolCallTimeoutMs": external_exports.number().readonly(),
|
|
14889
14895
|
"failOnStartupError": external_exports.boolean().readonly(),
|
|
14896
|
+
"oauth": external_exports.boolean().readonly().optional(),
|
|
14890
14897
|
"status": external_exports.object({
|
|
14891
14898
|
"phase": external_exports.union([external_exports.literal("failed"), external_exports.literal("stopped"), external_exports.literal("mounting"), external_exports.literal("live")]).readonly(),
|
|
14892
14899
|
"tools": external_exports.array(external_exports.string()).readonly(),
|
|
@@ -14945,14 +14952,16 @@ var TYPERT_REMOTE = {
|
|
|
14945
14952
|
codec: {
|
|
14946
14953
|
mode: "strict",
|
|
14947
14954
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerRemoveRequest",
|
|
14948
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_delete_parameter_0$schema
|
|
14955
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_delete_parameter_0$schema,
|
|
14956
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_delete_parameter_0$schema
|
|
14949
14957
|
}
|
|
14950
14958
|
}
|
|
14951
14959
|
],
|
|
14952
14960
|
result: {
|
|
14953
14961
|
mode: "strict",
|
|
14954
14962
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerRemoveResult",
|
|
14955
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_delete_result$schema
|
|
14963
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_delete_result$schema,
|
|
14964
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_delete_result$schema
|
|
14956
14965
|
},
|
|
14957
14966
|
sourceLocation: { "file": "packages/mcp/mcp-manager/src/index.ts", "line": 399, "column": 9 }
|
|
14958
14967
|
},
|
|
@@ -14966,7 +14975,8 @@ var TYPERT_REMOTE = {
|
|
|
14966
14975
|
result: {
|
|
14967
14976
|
mode: "strict",
|
|
14968
14977
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerListResult",
|
|
14969
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_list_result$schema
|
|
14978
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_list_result$schema,
|
|
14979
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_list_result$schema
|
|
14970
14980
|
},
|
|
14971
14981
|
sourceLocation: { "file": "packages/mcp/mcp-manager/src/index.ts", "line": 314, "column": 9 }
|
|
14972
14982
|
},
|
|
@@ -14984,14 +14994,16 @@ var TYPERT_REMOTE = {
|
|
|
14984
14994
|
codec: {
|
|
14985
14995
|
mode: "strict",
|
|
14986
14996
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerTestRequest",
|
|
14987
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_test_parameter_0$schema
|
|
14997
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_test_parameter_0$schema,
|
|
14998
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_test_parameter_0$schema
|
|
14988
14999
|
}
|
|
14989
15000
|
}
|
|
14990
15001
|
],
|
|
14991
15002
|
result: {
|
|
14992
15003
|
mode: "strict",
|
|
14993
15004
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerTestResult",
|
|
14994
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_test_result$schema
|
|
15005
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_test_result$schema,
|
|
15006
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_test_result$schema
|
|
14995
15007
|
},
|
|
14996
15008
|
sourceLocation: { "file": "packages/mcp/mcp-manager/src/index.ts", "line": 422, "column": 9 }
|
|
14997
15009
|
},
|
|
@@ -15009,14 +15021,16 @@ var TYPERT_REMOTE = {
|
|
|
15009
15021
|
codec: {
|
|
15010
15022
|
mode: "strict",
|
|
15011
15023
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerUpsertRequest",
|
|
15012
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_parameter_0$schema
|
|
15024
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_parameter_0$schema,
|
|
15025
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_parameter_0$schema
|
|
15013
15026
|
}
|
|
15014
15027
|
}
|
|
15015
15028
|
],
|
|
15016
15029
|
result: {
|
|
15017
15030
|
mode: "strict",
|
|
15018
15031
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerUpsertResult",
|
|
15019
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_result$schema
|
|
15032
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_result$schema,
|
|
15033
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_result$schema
|
|
15020
15034
|
},
|
|
15021
15035
|
sourceLocation: { "file": "packages/mcp/mcp-manager/src/index.ts", "line": 329, "column": 9 }
|
|
15022
15036
|
},
|
|
@@ -15034,14 +15048,16 @@ var TYPERT_REMOTE = {
|
|
|
15034
15048
|
codec: {
|
|
15035
15049
|
mode: "strict",
|
|
15036
15050
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerUpsertJsonRequest",
|
|
15037
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_parameter_0$schema
|
|
15051
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_parameter_0$schema,
|
|
15052
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_parameter_0$schema
|
|
15038
15053
|
}
|
|
15039
15054
|
}
|
|
15040
15055
|
],
|
|
15041
15056
|
result: {
|
|
15042
15057
|
mode: "strict",
|
|
15043
15058
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerUpsertJsonResult",
|
|
15044
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_result$schema
|
|
15059
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_result$schema,
|
|
15060
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_result$schema
|
|
15045
15061
|
},
|
|
15046
15062
|
sourceLocation: { "file": "lib/index.js" }
|
|
15047
15063
|
},
|
|
@@ -15055,7 +15071,8 @@ var TYPERT_REMOTE = {
|
|
|
15055
15071
|
result: {
|
|
15056
15072
|
mode: "strict",
|
|
15057
15073
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerToolsListResult",
|
|
15058
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsList_result$schema
|
|
15074
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsList_result$schema,
|
|
15075
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_toolsList_result$schema
|
|
15059
15076
|
},
|
|
15060
15077
|
sourceLocation: { "file": "lib/index.js" }
|
|
15061
15078
|
},
|
|
@@ -15073,14 +15090,16 @@ var TYPERT_REMOTE = {
|
|
|
15073
15090
|
codec: {
|
|
15074
15091
|
mode: "strict",
|
|
15075
15092
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerToolsSetRequest",
|
|
15076
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsSet_parameter_0$schema
|
|
15093
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsSet_parameter_0$schema,
|
|
15094
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_toolsSet_parameter_0$schema
|
|
15077
15095
|
}
|
|
15078
15096
|
}
|
|
15079
15097
|
],
|
|
15080
15098
|
result: {
|
|
15081
15099
|
mode: "strict",
|
|
15082
15100
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerToolsSetResult",
|
|
15083
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsSet_result$schema
|
|
15101
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsSet_result$schema,
|
|
15102
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_toolsSet_result$schema
|
|
15084
15103
|
},
|
|
15085
15104
|
sourceLocation: { "file": "lib/index.js" }
|
|
15086
15105
|
},
|
|
@@ -15098,14 +15117,16 @@ var TYPERT_REMOTE = {
|
|
|
15098
15117
|
codec: {
|
|
15099
15118
|
mode: "strict",
|
|
15100
15119
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerToolsModeRequest",
|
|
15101
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsMode_parameter_0$schema
|
|
15120
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsMode_parameter_0$schema,
|
|
15121
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_toolsMode_parameter_0$schema
|
|
15102
15122
|
}
|
|
15103
15123
|
}
|
|
15104
15124
|
],
|
|
15105
15125
|
result: {
|
|
15106
15126
|
mode: "strict",
|
|
15107
15127
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerToolsModeResult",
|
|
15108
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsMode_result$schema
|
|
15128
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsMode_result$schema,
|
|
15129
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_toolsMode_result$schema
|
|
15109
15130
|
},
|
|
15110
15131
|
sourceLocation: { "file": "lib/index.js" }
|
|
15111
15132
|
},
|
|
@@ -15119,7 +15140,8 @@ var TYPERT_REMOTE = {
|
|
|
15119
15140
|
result: {
|
|
15120
15141
|
mode: "strict",
|
|
15121
15142
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerEnvListResult",
|
|
15122
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_envList_result$schema
|
|
15143
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_envList_result$schema,
|
|
15144
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_envList_result$schema
|
|
15123
15145
|
},
|
|
15124
15146
|
sourceLocation: { "file": "lib/index.js" }
|
|
15125
15147
|
},
|
|
@@ -15137,14 +15159,16 @@ var TYPERT_REMOTE = {
|
|
|
15137
15159
|
codec: {
|
|
15138
15160
|
mode: "strict",
|
|
15139
15161
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerEnvSetRequest",
|
|
15140
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_envSet_parameter_0$schema
|
|
15162
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_envSet_parameter_0$schema,
|
|
15163
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_envSet_parameter_0$schema
|
|
15141
15164
|
}
|
|
15142
15165
|
}
|
|
15143
15166
|
],
|
|
15144
15167
|
result: {
|
|
15145
15168
|
mode: "strict",
|
|
15146
15169
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerEnvSetResult",
|
|
15147
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_envSet_result$schema
|
|
15170
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_envSet_result$schema,
|
|
15171
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_envSet_result$schema
|
|
15148
15172
|
},
|
|
15149
15173
|
sourceLocation: { "file": "lib/index.js" }
|
|
15150
15174
|
},
|
|
@@ -15162,14 +15186,16 @@ var TYPERT_REMOTE = {
|
|
|
15162
15186
|
codec: {
|
|
15163
15187
|
mode: "strict",
|
|
15164
15188
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerAdoptRequest",
|
|
15165
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_adopt_parameter_0$schema
|
|
15189
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_adopt_parameter_0$schema,
|
|
15190
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_adopt_parameter_0$schema
|
|
15166
15191
|
}
|
|
15167
15192
|
}
|
|
15168
15193
|
],
|
|
15169
15194
|
result: {
|
|
15170
15195
|
mode: "strict",
|
|
15171
15196
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerAdoptResult",
|
|
15172
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_adopt_result$schema
|
|
15197
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_adopt_result$schema,
|
|
15198
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_adopt_result$schema
|
|
15173
15199
|
},
|
|
15174
15200
|
sourceLocation: { "file": "lib/index.js" }
|
|
15175
15201
|
},
|
|
@@ -15187,14 +15213,16 @@ var TYPERT_REMOTE = {
|
|
|
15187
15213
|
codec: {
|
|
15188
15214
|
mode: "strict",
|
|
15189
15215
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerReleaseRequest",
|
|
15190
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_release_parameter_0$schema
|
|
15216
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_release_parameter_0$schema,
|
|
15217
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_release_parameter_0$schema
|
|
15191
15218
|
}
|
|
15192
15219
|
}
|
|
15193
15220
|
],
|
|
15194
15221
|
result: {
|
|
15195
15222
|
mode: "strict",
|
|
15196
15223
|
typeSymbol: "@deepseek-ai/dsh-mcp-manager/types#McpManagerReleaseResult",
|
|
15197
|
-
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_release_result$schema
|
|
15224
|
+
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_release_result$schema,
|
|
15225
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_release_result$schema
|
|
15198
15226
|
},
|
|
15199
15227
|
sourceLocation: { "file": "lib/index.js" }
|
|
15200
15228
|
}
|
|
@@ -15225,7 +15253,10 @@ function emptyDraft() {
|
|
|
15225
15253
|
toolCallTimeoutMs: String(DEFAULT_TOOL_CALL_TIMEOUT_MS),
|
|
15226
15254
|
// Reject the mount by default when the startup connection fails, so a
|
|
15227
15255
|
// broken server never registers stale tools.
|
|
15228
|
-
failOnStartupError: true
|
|
15256
|
+
failOnStartupError: true,
|
|
15257
|
+
// OAuth is opt-in: guessing it from the headers opened the browser for
|
|
15258
|
+
// servers that authenticate with static tokens.
|
|
15259
|
+
oauth: false
|
|
15229
15260
|
};
|
|
15230
15261
|
}
|
|
15231
15262
|
function draftFromServer(server) {
|
|
@@ -15240,6 +15271,7 @@ function draftFromServer(server) {
|
|
|
15240
15271
|
url: server.url,
|
|
15241
15272
|
headersText: server.headers.map((header) => `${header.name}: ${header.value}`).join("\n"),
|
|
15242
15273
|
toolCallTimeoutMs: String(server.toolCallTimeoutMs),
|
|
15274
|
+
oauth: server.oauth === true,
|
|
15243
15275
|
failOnStartupError: server.failOnStartupError
|
|
15244
15276
|
};
|
|
15245
15277
|
}
|
|
@@ -15326,6 +15358,7 @@ function draftToSubmission(draft) {
|
|
|
15326
15358
|
url: draft.url.trim(),
|
|
15327
15359
|
headers: parseHeaders(draft.headersText),
|
|
15328
15360
|
toolCallTimeoutMs: parseTimeout(draft.toolCallTimeoutMs),
|
|
15361
|
+
oauth: draft.oauth,
|
|
15329
15362
|
failOnStartupError: draft.failOnStartupError
|
|
15330
15363
|
}
|
|
15331
15364
|
};
|
|
@@ -15591,6 +15624,18 @@ function McpServerForm(props) {
|
|
|
15591
15624
|
}
|
|
15592
15625
|
)
|
|
15593
15626
|
] }),
|
|
15627
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: ServerForm_default.checkRow, children: [
|
|
15628
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
15629
|
+
"input",
|
|
15630
|
+
{
|
|
15631
|
+
type: "checkbox",
|
|
15632
|
+
checked: draft.oauth,
|
|
15633
|
+
onChange: (event) => update({ oauth: event.currentTarget.checked })
|
|
15634
|
+
}
|
|
15635
|
+
),
|
|
15636
|
+
t("oauthAuth")
|
|
15637
|
+
] }),
|
|
15638
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: ServerForm_default.hint, children: t("oauthAuthHint") }),
|
|
15594
15639
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: ServerForm_default.checkRow, children: [
|
|
15595
15640
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
15596
15641
|
"input",
|
|
@@ -15663,6 +15708,7 @@ function serversToJsonText(servers) {
|
|
|
15663
15708
|
}
|
|
15664
15709
|
entry.toolCallTimeoutMs = server.toolCallTimeoutMs;
|
|
15665
15710
|
entry.failOnStartupError = server.failOnStartupError;
|
|
15711
|
+
if (server.oauth === true) entry.oauth = true;
|
|
15666
15712
|
entry.env = server.env.map((row) => row.secret ? { name: row.name, secret: true, configured: row.configured } : { name: row.name, secret: false, ...row.value !== void 0 && row.value.length > 0 ? { value: row.value } : {} });
|
|
15667
15713
|
document2[server.serverName] = entry;
|
|
15668
15714
|
}
|
|
@@ -15730,6 +15776,7 @@ function parseServersJson(text) {
|
|
|
15730
15776
|
url: typeof cfg.url === "string" ? cfg.url : "",
|
|
15731
15777
|
headers: cfg.headers,
|
|
15732
15778
|
toolCallTimeoutMs: typeof cfg.toolCallTimeoutMs === "number" ? cfg.toolCallTimeoutMs : 6e4,
|
|
15779
|
+
oauth: cfg.oauth === true,
|
|
15733
15780
|
failOnStartupError: cfg.failOnStartupError !== false
|
|
15734
15781
|
};
|
|
15735
15782
|
servers.push({ server, env });
|
|
@@ -16093,6 +16140,7 @@ function viewToDraft(server) {
|
|
|
16093
16140
|
url: server.url,
|
|
16094
16141
|
headersText: server.headers.map((header) => `${header.name}: ${header.value}`).join("\n"),
|
|
16095
16142
|
toolCallTimeoutMs: String(server.toolCallTimeoutMs),
|
|
16143
|
+
oauth: server.oauth === true,
|
|
16096
16144
|
failOnStartupError: server.failOnStartupError
|
|
16097
16145
|
};
|
|
16098
16146
|
}
|
|
@@ -16515,6 +16563,8 @@ var zh = {
|
|
|
16515
16563
|
removeEnvVar: "\u79FB\u9664\u8BE5\u53D8\u91CF",
|
|
16516
16564
|
toolCallTimeoutMs: "\u5DE5\u5177\u8C03\u7528\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09",
|
|
16517
16565
|
failOnStartupError: "\u542F\u52A8\u8FDE\u63A5\u5931\u8D25\u65F6\u62D2\u7EDD\u6302\u8F7D",
|
|
16566
|
+
oauthAuth: "\u4F7F\u7528 OAuth \u6388\u6743\uFF08\u6D4F\u89C8\u5668\u6388\u6743 + token \u6258\u7BA1\uFF09",
|
|
16567
|
+
oauthAuthHint: "\u4EC5\u5F53\u8BE5\u670D\u52A1\u5668\u786E\u5B9E\u4F7F\u7528 OAuth\uFF08MCP \u6388\u6743\u7801 + PKCE\uFF09\u65F6\u52FE\u9009\u3002\u7528\u9759\u6001 token \u6216\u81EA\u5B9A\u4E49\u8BF7\u6C42\u5934\u8BA4\u8BC1\u7684\u670D\u52A1\u5668\u8BF7\u52FF\u52FE\u9009\u2014\u2014\u5426\u5219\u670D\u52A1\u5668\u8FD4\u56DE 401 \u65F6\u4F1A\u88AB\u5F53\u6210 OAuth \u6311\u6218\uFF0C\u4ECE\u800C\u53CD\u590D\u5F39\u51FA\u6D4F\u89C8\u5668\u6388\u6743\u3002",
|
|
16518
16568
|
statusMounting: "\u8FDE\u63A5\u4E2D",
|
|
16519
16569
|
statusLive: "\u5DF2\u8FDE\u63A5",
|
|
16520
16570
|
statusFailed: "\u6302\u8F7D\u5931\u8D25",
|
|
@@ -16638,6 +16688,8 @@ var en = {
|
|
|
16638
16688
|
removeEnvVar: "Remove this variable",
|
|
16639
16689
|
toolCallTimeoutMs: "Tool-call timeout (ms)",
|
|
16640
16690
|
failOnStartupError: "Reject the mount when the startup connection fails",
|
|
16691
|
+
oauthAuth: "Use OAuth authorization (browser authorization + token storage)",
|
|
16692
|
+
oauthAuthHint: "Tick only when the server really uses OAuth (MCP authorization-code + PKCE). Servers that authenticate with static tokens or custom headers must leave this off \u2014 otherwise a 401 is treated as an OAuth challenge and the browser authorization opens again and again.",
|
|
16641
16693
|
statusMounting: "Connecting",
|
|
16642
16694
|
statusLive: "Connected",
|
|
16643
16695
|
statusFailed: "Mount failed",
|
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { randomBytes } from "node:crypto";
|
|
|
2
2
|
import { Service } from "@deepseek-ai/cordis";
|
|
3
3
|
import { credentialRef } from "@deepseek-ai/dsh-credentials";
|
|
4
4
|
import * as mcpClient from "./mcp-client.js";
|
|
5
|
-
import { createOAuthProvider } from "./oauth.js";
|
|
5
|
+
import { createOAuthProvider, oauthCredentialRefs } from "./oauth.js";
|
|
6
6
|
import { probeConnection } from "./probe.js";
|
|
7
7
|
import { Remote, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
|
|
8
8
|
import { hostText } from "./host-locales.js";
|
|
@@ -56,6 +56,7 @@ const mcpServerRowSchema = z$1.object({
|
|
|
56
56
|
env: z$1.array(envEntrySchema).default([]),
|
|
57
57
|
toolCallTimeoutMs: positiveIntegerSchema,
|
|
58
58
|
failOnStartupError: z$1.boolean().default(false),
|
|
59
|
+
oauth: z$1.boolean().default(false),
|
|
59
60
|
origin: z$1.union([z$1.literal("plugin"), z$1.literal("cordis")]).default("plugin"),
|
|
60
61
|
declaredIn: z$1.string().optional(),
|
|
61
62
|
declaredRowId: z$1.string().optional(),
|
|
@@ -184,6 +185,9 @@ function toServerRow(id, server, env, previous) {
|
|
|
184
185
|
}),
|
|
185
186
|
toolCallTimeoutMs: server.toolCallTimeoutMs,
|
|
186
187
|
failOnStartupError: server.failOnStartupError,
|
|
188
|
+
// The OAuth switch is explicit: a caller that states nothing (the JSON
|
|
189
|
+
// editor omitting the field) keeps the previous choice.
|
|
190
|
+
oauth: server.oauth === true ? true : server.oauth === false ? false : previous?.oauth === true,
|
|
187
191
|
// Rows created here are the manager's own; mirrors imported from a
|
|
188
192
|
// Cordis patch layer are written by syncDeclared with origin "cordis".
|
|
189
193
|
origin: "plugin",
|
|
@@ -327,7 +331,7 @@ function placeholderName(value, envNames) {
|
|
|
327
331
|
}
|
|
328
332
|
/** Whether two server records carry the same content (mirror refresh guard). */
|
|
329
333
|
function sameRecord(left, right) {
|
|
330
|
-
return left.serverName === right.serverName && left.transport === right.transport && left.enabled === right.enabled && left.command === right.command && left.cwd === right.cwd && left.url === right.url && left.toolCallTimeoutMs === right.toolCallTimeoutMs && left.failOnStartupError === right.failOnStartupError && left.declaredIn === right.declaredIn && left.declaredRowId === right.declaredRowId && left.stale === right.stale && JSON.stringify(left.args) === JSON.stringify(right.args) && JSON.stringify(left.headers) === JSON.stringify(right.headers) && JSON.stringify(left.env) === JSON.stringify(right.env);
|
|
334
|
+
return left.serverName === right.serverName && left.transport === right.transport && left.enabled === right.enabled && left.command === right.command && left.cwd === right.cwd && left.url === right.url && left.toolCallTimeoutMs === right.toolCallTimeoutMs && left.failOnStartupError === right.failOnStartupError && left.oauth === right.oauth && left.declaredIn === right.declaredIn && left.declaredRowId === right.declaredRowId && left.stale === right.stale && JSON.stringify(left.args) === JSON.stringify(right.args) && JSON.stringify(left.headers) === JSON.stringify(right.headers) && JSON.stringify(left.env) === JSON.stringify(right.env);
|
|
331
335
|
}
|
|
332
336
|
/**
|
|
333
337
|
* The managed server id a credential reference belongs to, when the reference
|
|
@@ -561,6 +565,11 @@ let McpManagerService = (() => {
|
|
|
561
565
|
* disabled and re-enabled.
|
|
562
566
|
*/
|
|
563
567
|
everMounted = /* @__PURE__ */ new Set();
|
|
568
|
+
/**
|
|
569
|
+
* Server names whose one automatic browser authorization this process
|
|
570
|
+
* already consumed (see {@link claimAutoBrowser}).
|
|
571
|
+
*/
|
|
572
|
+
autoBrowserOpened = /* @__PURE__ */ new Set();
|
|
564
573
|
/** Per-id operation chain serializing reconcile, remove, and restart jobs. */
|
|
565
574
|
operationTails = /* @__PURE__ */ new Map();
|
|
566
575
|
/** Server ids whose secret writes are this manager's own; skip restart echoes. */
|
|
@@ -594,6 +603,7 @@ let McpManagerService = (() => {
|
|
|
594
603
|
}, "mcp-manager.domainClose");
|
|
595
604
|
this.table = domain.table("servers");
|
|
596
605
|
this.envTable = domain.table("global_env");
|
|
606
|
+
await this.migrateOAuthFlags();
|
|
597
607
|
await this.refreshDeclared(false);
|
|
598
608
|
this.reconcileDeclared();
|
|
599
609
|
this.installToolControl();
|
|
@@ -808,7 +818,11 @@ let McpManagerService = (() => {
|
|
|
808
818
|
...toMirrorRecord(entry),
|
|
809
819
|
origin: "plugin",
|
|
810
820
|
enabled: true,
|
|
811
|
-
stale: false
|
|
821
|
+
stale: false,
|
|
822
|
+
// A declaration with no `Authorization` header is the shape an
|
|
823
|
+
// OAuth-protected server has; default the switch on for the
|
|
824
|
+
// takeover (it stays visible and editable in the form).
|
|
825
|
+
oauth: entry.transport === "streamable-http" && !entry.headers.some((header) => header.name.toLowerCase() === "authorization")
|
|
812
826
|
});
|
|
813
827
|
if (!parsed.success) return this.adoptFailure("MCP_ADOPT_FAILED", parsed.error.issues[0]?.message ?? "invalid declaration");
|
|
814
828
|
const disable = writeManagedIds(entry.declaredIn, [...managedIds(entry.declaredIn), entry.rowId]);
|
|
@@ -1036,19 +1050,64 @@ let McpManagerService = (() => {
|
|
|
1036
1050
|
};
|
|
1037
1051
|
}
|
|
1038
1052
|
/**
|
|
1039
|
-
* Whether one
|
|
1040
|
-
*
|
|
1041
|
-
*
|
|
1042
|
-
*
|
|
1043
|
-
* authorization-code
|
|
1044
|
-
*
|
|
1045
|
-
* @param
|
|
1053
|
+
* Whether one stored server asks for an OAuth provider. The switch is
|
|
1054
|
+
* explicit (`oauth: true`, set in the settings form): a server that
|
|
1055
|
+
* authenticates with static headers must never be guessed into OAuth,
|
|
1056
|
+
* because a 401 from it is not a challenge and starting the
|
|
1057
|
+
* authorization-code flow for it only opens the browser forever.
|
|
1058
|
+
* stdio never needs the provider.
|
|
1059
|
+
* @param row - the stored definition (or the submitted spec).
|
|
1046
1060
|
* @returns true when OAuth (authorization-code + PKCE) should be enabled.
|
|
1047
1061
|
*/
|
|
1048
|
-
wantsOAuthProvider(
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1062
|
+
wantsOAuthProvider(row) {
|
|
1063
|
+
return row?.transport === "streamable-http" && row.oauth === true;
|
|
1064
|
+
}
|
|
1065
|
+
/**
|
|
1066
|
+
* Claim the one automatic browser authorization this process allows per
|
|
1067
|
+
* server. Without it a server whose 401 can never be satisfied by the
|
|
1068
|
+
* authorization-code flow (or whose token keeps being rejected) reopens
|
|
1069
|
+
* the browser on every mount and reconnect; later attempts surface the
|
|
1070
|
+
* authorization link instead, and `test` still opens the browser because
|
|
1071
|
+
* the user asked for it.
|
|
1072
|
+
* @param serverName - the server the provider belongs to.
|
|
1073
|
+
* @returns true when this process may open the browser automatically.
|
|
1074
|
+
*/
|
|
1075
|
+
claimAutoBrowser(serverName) {
|
|
1076
|
+
if (this.autoBrowserOpened.has(serverName)) return false;
|
|
1077
|
+
this.autoBrowserOpened.add(serverName);
|
|
1078
|
+
return true;
|
|
1079
|
+
}
|
|
1080
|
+
/**
|
|
1081
|
+
* Give stored rows that completed an OAuth flow before the explicit
|
|
1082
|
+
* switch existed their provider back (`oauth: true`). The switch replaced
|
|
1083
|
+
* a header heuristic, so a row with stored OAuth credentials really does
|
|
1084
|
+
* need authorization; rows without them stay off and stop opening the
|
|
1085
|
+
* browser for a flow that can never succeed.
|
|
1086
|
+
*/
|
|
1087
|
+
async migrateOAuthFlags() {
|
|
1088
|
+
const table = this.requireTable();
|
|
1089
|
+
for (const [id, row] of table.entries()) {
|
|
1090
|
+
if (row.oauth === true || row.origin === "cordis") continue;
|
|
1091
|
+
let configured = false;
|
|
1092
|
+
for (const ref of oauthCredentialRefs(row.serverName)) {
|
|
1093
|
+
try {
|
|
1094
|
+
if ((await this.ctx.credentials.describe(ref)).configured) {
|
|
1095
|
+
configured = true;
|
|
1096
|
+
break;
|
|
1097
|
+
}
|
|
1098
|
+
} catch {
|
|
1099
|
+
/* an absent credential document is not an error */
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
if (!configured) continue;
|
|
1103
|
+
const parsed = mcpServerRowSchema.safeParse({
|
|
1104
|
+
...row,
|
|
1105
|
+
oauth: true
|
|
1106
|
+
});
|
|
1107
|
+
if (!parsed.success) continue;
|
|
1108
|
+
await table.put(id, parsed.data);
|
|
1109
|
+
this.ctx.logger.info(`mcp-manager: "${row.serverName}" keeps OAuth (stored credentials) after the explicit switch`);
|
|
1110
|
+
}
|
|
1052
1111
|
}
|
|
1053
1112
|
/**
|
|
1054
1113
|
* Mount one server's mcp-client instance without awaiting activation, so a
|
|
@@ -1071,15 +1130,17 @@ let McpManagerService = (() => {
|
|
|
1071
1130
|
const env = await this.resolveEnv(row);
|
|
1072
1131
|
const globalEnv = await this.resolveGlobalEnv();
|
|
1073
1132
|
const config = this.toClientConfig(row, env, globalEnv);
|
|
1074
|
-
// OAuth
|
|
1075
|
-
//
|
|
1076
|
-
//
|
|
1077
|
-
//
|
|
1078
|
-
//
|
|
1079
|
-
//
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1133
|
+
// The OAuth switch is explicit per server (`oauth: true`), and
|
|
1134
|
+
// automatic browser authorization happens at most once per
|
|
1135
|
+
// server per process: later attempts surface the
|
|
1136
|
+
// authorization link instead of opening the browser again.
|
|
1137
|
+
// Tokens are keyed by serverName, so a test-connection
|
|
1138
|
+
// authorization is reused by the mount.
|
|
1139
|
+
const authProvider = this.wantsOAuthProvider(row)
|
|
1140
|
+
? createOAuthProvider(row.serverName, this.ctx, {
|
|
1141
|
+
allowBrowser: this.allowBrowserOnMount && this.claimAutoBrowser(row.serverName),
|
|
1142
|
+
serverUrl: row.url
|
|
1143
|
+
})
|
|
1083
1144
|
: void 0;
|
|
1084
1145
|
handle = this.ctx.plugin(MCP_CLIENT_PLUGIN, { ...config, ...authProvider === void 0 ? {} : { authProvider } });
|
|
1085
1146
|
} catch (error) {
|
|
@@ -1182,6 +1243,7 @@ let McpManagerService = (() => {
|
|
|
1182
1243
|
env,
|
|
1183
1244
|
toolCallTimeoutMs: row.toolCallTimeoutMs,
|
|
1184
1245
|
failOnStartupError: row.failOnStartupError,
|
|
1246
|
+
...(mirror ? {} : { oauth: row.oauth === true }),
|
|
1185
1247
|
...(mirrorNeedsPlugin ? { needsPlugin: true } : {}),
|
|
1186
1248
|
status: {
|
|
1187
1249
|
// A mirror never mounts here: its phase follows the declaration
|
|
@@ -1393,7 +1455,8 @@ let McpManagerService = (() => {
|
|
|
1393
1455
|
url: typeof item.server.url === "string" ? item.server.url : "",
|
|
1394
1456
|
headers: normalizeHeaders(item.server.headers),
|
|
1395
1457
|
toolCallTimeoutMs: Number.isInteger(item.server.toolCallTimeoutMs) ? item.server.toolCallTimeoutMs : 60e3,
|
|
1396
|
-
failOnStartupError: item.server.failOnStartupError !== false
|
|
1458
|
+
failOnStartupError: item.server.failOnStartupError !== false,
|
|
1459
|
+
oauth: item.server.oauth === void 0 ? void 0 : item.server.oauth === true
|
|
1397
1460
|
};
|
|
1398
1461
|
try {
|
|
1399
1462
|
validateServerInput(spec, env);
|
|
@@ -1595,12 +1658,13 @@ let McpManagerService = (() => {
|
|
|
1595
1658
|
// Test connection also supports OAuth: an OAuth-protected server
|
|
1596
1659
|
// opens the browser for authorization and the probe continues after
|
|
1597
1660
|
// tokens are stored (keyed by serverName, matching the mount path).
|
|
1598
|
-
//
|
|
1599
|
-
// the
|
|
1600
|
-
//
|
|
1661
|
+
// The user asked for this probe, so it may open the browser even
|
|
1662
|
+
// when the mount-time circuit breaker already fired; servers without
|
|
1663
|
+
// the explicit switch skip the provider so a 401 reports an
|
|
1664
|
+
// authentication failure instead of starting a bogus flow.
|
|
1601
1665
|
const probe = await probeConnection(probeConfig, {
|
|
1602
1666
|
timeoutMs: this.probeTimeoutMs,
|
|
1603
|
-
...(this.wantsOAuthProvider(
|
|
1667
|
+
...(this.wantsOAuthProvider(request.server)
|
|
1604
1668
|
? { authProvider: createOAuthProvider(request.server.serverName, this.ctx, { serverUrl: request.server.url }) }
|
|
1605
1669
|
: {})
|
|
1606
1670
|
});
|
package/lib/mcp-client.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import z from "@deepseek-ai/schemastery";
|
|
2
2
|
import { MAX_TIMER_DELAY_MS } from "@deepseek-ai/dsh-timeout";
|
|
3
|
-
import { Client } from "@modelcontextprotocol/
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
3
|
+
import { Client, specTypeSchemas } from "@modelcontextprotocol/client";
|
|
4
|
+
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
|
|
5
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/client";
|
|
7
6
|
import { scrubbedParentEnv } from "@deepseek-ai/dsh-subprocess";
|
|
8
7
|
import { createHash } from "node:crypto";
|
|
9
8
|
import { isDeepStrictEqual } from "node:util";
|
|
@@ -92,7 +91,7 @@ function listToolsUncached(client, cursor) {
|
|
|
92
91
|
return client.request({
|
|
93
92
|
method: "tools/list",
|
|
94
93
|
...cursor === void 0 ? {} : { params: { cursor } }
|
|
95
|
-
},
|
|
94
|
+
}, specTypeSchemas.ListToolsResult);
|
|
96
95
|
}
|
|
97
96
|
/** Call without the SDK pre-validating an output schema the bridge may not support. */
|
|
98
97
|
function callToolUncached(client, rawName, args, exec, opts) {
|
|
@@ -558,7 +557,11 @@ function startConnection(ctx, config, policy) {
|
|
|
558
557
|
const opts = {
|
|
559
558
|
registrationFailure: "contain",
|
|
560
559
|
serverName: config.serverName,
|
|
561
|
-
toolCallTimeoutMs: config.toolCallTimeoutMs
|
|
560
|
+
toolCallTimeoutMs: config.toolCallTimeoutMs,
|
|
561
|
+
// Read by the per-tool-call OAuth guard: the server URL drives discovery,
|
|
562
|
+
// and the provider reports whether a stored token is still usable.
|
|
563
|
+
url: config.url,
|
|
564
|
+
authProvider: config.authProvider
|
|
562
565
|
};
|
|
563
566
|
const startupOpts = config.failOnStartupError ? {
|
|
564
567
|
...opts,
|
|
@@ -659,13 +662,12 @@ function startConnection(ctx, config, policy) {
|
|
|
659
662
|
* @param startup - Whether this is the plugin's activation attempt.
|
|
660
663
|
*/
|
|
661
664
|
async function connectGeneration(startup) {
|
|
665
|
+
// SDK 2.0 no longer accepts `authProvider` in ClientOptions; the transport
|
|
666
|
+
// created by createTransport(config) carries it (config.authProvider).
|
|
662
667
|
const generation = new Client({
|
|
663
668
|
name: "dsh-mcp-client",
|
|
664
669
|
version: "0.0.1"
|
|
665
|
-
}, {
|
|
666
|
-
capabilities: {},
|
|
667
|
-
...(opts.authProvider === void 0 ? {} : { authProvider: opts.authProvider })
|
|
668
|
-
});
|
|
670
|
+
}, { capabilities: {} });
|
|
669
671
|
const closed = Promise.withResolvers();
|
|
670
672
|
let attemptSettled = false;
|
|
671
673
|
let closeObserved = false;
|
|
@@ -677,7 +679,7 @@ function startConnection(ctx, config, policy) {
|
|
|
677
679
|
closed.resolve();
|
|
678
680
|
if (attemptSettled) generationDown(generation);
|
|
679
681
|
};
|
|
680
|
-
generation.setNotificationHandler(
|
|
682
|
+
generation.setNotificationHandler("notifications/tools/list_changed", async () => {
|
|
681
683
|
if (!isCurrent(generation)) return;
|
|
682
684
|
ctx.logger.info(`${label}: tool list changed, re-syncing`);
|
|
683
685
|
try {
|
|
@@ -783,7 +785,7 @@ async function runProbe(client, config) {
|
|
|
783
785
|
const response = await client.request({
|
|
784
786
|
method: "tools/list",
|
|
785
787
|
...cursor === void 0 ? {} : { params: { cursor } }
|
|
786
|
-
},
|
|
788
|
+
}, specTypeSchemas.ListToolsResult);
|
|
787
789
|
for (const tool of response.tools) tools.push({
|
|
788
790
|
name: tool.name,
|
|
789
791
|
...tool.description === void 0 ? {} : { description: tool.description }
|
package/lib/oauth.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
exchangeAuthorization,
|
|
20
20
|
registerClient,
|
|
21
21
|
startAuthorization,
|
|
22
|
-
} from "@modelcontextprotocol/
|
|
22
|
+
} from "@modelcontextprotocol/client";
|
|
23
23
|
import { credentialRef } from "@deepseek-ai/dsh-credentials";
|
|
24
24
|
import { hostText } from "./host-locales.js";
|
|
25
25
|
|
|
@@ -77,6 +77,19 @@ function oauthClientRef(serverId) {
|
|
|
77
77
|
return oauthRef(OAUTH_CLIENT_REF_PREFIX, serverId);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
/**
|
|
81
|
+
* The credential references one server's OAuth flow writes (token + client).
|
|
82
|
+
* Recognising servers that demonstrably completed a flow is how stored rows
|
|
83
|
+
* migrate to the explicit OAuth switch: the switch replaced a header
|
|
84
|
+
* heuristic, and a server with stored OAuth credentials really does need
|
|
85
|
+
* authorization.
|
|
86
|
+
* @param serverId - the server name the flow is keyed by.
|
|
87
|
+
* @returns both credential reference names.
|
|
88
|
+
*/
|
|
89
|
+
export function oauthCredentialRefs(serverId) {
|
|
90
|
+
return [oauthTokenRef(serverId), oauthClientRef(serverId)];
|
|
91
|
+
}
|
|
92
|
+
|
|
80
93
|
/** Open the system browser to one URL, best effort. */
|
|
81
94
|
function openBrowser(url) {
|
|
82
95
|
const command =
|
package/lib/probe.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Client } from "@modelcontextprotocol/
|
|
2
|
-
import { ListToolsResultSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
1
|
+
import { Client, specTypeSchemas } from "@modelcontextprotocol/client";
|
|
3
2
|
import { createTransport } from "./transport.js";
|
|
4
3
|
const DEFAULT_PROBE_TIMEOUT_MS = 15e3;
|
|
5
4
|
function probeErrorMessage(error) {
|
|
@@ -12,7 +11,7 @@ async function runProbe(client, config) {
|
|
|
12
11
|
do {
|
|
13
12
|
const response = await client.request(
|
|
14
13
|
{ method: "tools/list", ...cursor === void 0 ? {} : { params: { cursor } } },
|
|
15
|
-
|
|
14
|
+
specTypeSchemas.ListToolsResult
|
|
16
15
|
);
|
|
17
16
|
for (const tool of response.tools) {
|
|
18
17
|
tools.push({
|
|
@@ -37,12 +36,11 @@ async function probeConnection(config, options = {}) {
|
|
|
37
36
|
// the tokens and the next probe succeeds.
|
|
38
37
|
const OAUTH_PROBE_BUDGET_MS = 5 * 60e3;
|
|
39
38
|
const budgetMs = options.authProvider === void 0 ? timeoutMs : Math.max(timeoutMs, OAUTH_PROBE_BUDGET_MS);
|
|
39
|
+
// Client options no longer carry `authProvider`; the SDK reads it from the
|
|
40
|
+
// transport (see the transportConfig below).
|
|
40
41
|
const client = new Client(
|
|
41
42
|
{ name: "dsh-mcp-client", version: "0.0.1" },
|
|
42
|
-
{
|
|
43
|
-
capabilities: {},
|
|
44
|
-
...(options.authProvider === void 0 ? {} : { authProvider: options.authProvider })
|
|
45
|
-
}
|
|
43
|
+
{ capabilities: {} }
|
|
46
44
|
);
|
|
47
45
|
const timeout = new Promise((_, reject) => {
|
|
48
46
|
const timer = setTimeout(() => reject(new Error(`connection probe timed out after ${budgetMs}ms`)), budgetMs);
|
|
@@ -50,7 +48,7 @@ async function probeConnection(config, options = {}) {
|
|
|
50
48
|
});
|
|
51
49
|
try {
|
|
52
50
|
// The SDK performs OAuth in the transport layer, so the authProvider must
|
|
53
|
-
// reach the transport config
|
|
51
|
+
// reach the transport config.
|
|
54
52
|
const transportConfig = {
|
|
55
53
|
...config,
|
|
56
54
|
...(options.authProvider === void 0 ? {} : { authProvider: options.authProvider })
|
package/lib/transport.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { StdioClientTransport } from "@modelcontextprotocol/
|
|
2
|
-
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/
|
|
1
|
+
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
|
|
2
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/client";
|
|
3
3
|
import { scrubbedParentEnv } from "@deepseek-ai/dsh-subprocess";
|
|
4
4
|
function buildChildEnv(extra) {
|
|
5
5
|
return { ...scrubbedParentEnv(), ...extra };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "MCP 管理界面 + tool search:可视化配置/启停/刷新 MCP 服务器与工具勾选,按需检索(tool search)热注入;工具列表稳定命中缓存、不撑爆上下文。DeepSeek Harness plugin: MCP management UI + tool search — stable tool list, cache-friendly, no context bloat.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
"build": "node scripts/build.mjs",
|
|
25
25
|
"test": "node scripts/test.mjs"
|
|
26
26
|
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@modelcontextprotocol/client": "2.0.0",
|
|
29
|
+
"zod": "^4.2.0"
|
|
30
|
+
},
|
|
27
31
|
"author": "Arvin.qi <arvin.qi@qq.com>",
|
|
28
32
|
"license": "MIT",
|
|
29
33
|
"repository": {
|
|
@@ -35,6 +39,7 @@
|
|
|
35
39
|
"url": "https://github.com/ArvinQi/dsh-mcp/issues"
|
|
36
40
|
},
|
|
37
41
|
"dsh": {
|
|
42
|
+
"supported": "0.1.6-alpha.2",
|
|
38
43
|
"client": {
|
|
39
44
|
"inject": [
|
|
40
45
|
"@deepseek-ai/dsh-api-remotes",
|
|
@@ -73,6 +73,7 @@ function viewToDraft(server: McpServerView): McpDraft {
|
|
|
73
73
|
url: server.url,
|
|
74
74
|
headersText: server.headers.map(header => `${header.name}: ${header.value}`).join('\n'),
|
|
75
75
|
toolCallTimeoutMs: String(server.toolCallTimeoutMs),
|
|
76
|
+
oauth: server.oauth === true,
|
|
76
77
|
failOnStartupError: server.failOnStartupError,
|
|
77
78
|
}
|
|
78
79
|
}
|
|
@@ -225,6 +225,16 @@ export function McpServerForm(props: McpServerFormProps): ReactNode {
|
|
|
225
225
|
/>
|
|
226
226
|
</label>
|
|
227
227
|
|
|
228
|
+
<label className={css.checkRow}>
|
|
229
|
+
<input
|
|
230
|
+
type="checkbox"
|
|
231
|
+
checked={draft.oauth}
|
|
232
|
+
onChange={(event) => update({ oauth: event.currentTarget.checked })}
|
|
233
|
+
/>
|
|
234
|
+
{t('oauthAuth')}
|
|
235
|
+
</label>
|
|
236
|
+
<p className={css.hint}>{t('oauthAuthHint')}</p>
|
|
237
|
+
|
|
228
238
|
<label className={css.checkRow}>
|
|
229
239
|
<input
|
|
230
240
|
type="checkbox"
|
|
@@ -77,6 +77,7 @@ export function serversToJsonText(servers: readonly McpServerView[]): string {
|
|
|
77
77
|
}
|
|
78
78
|
entry.toolCallTimeoutMs = server.toolCallTimeoutMs
|
|
79
79
|
entry.failOnStartupError = server.failOnStartupError
|
|
80
|
+
if (server.oauth === true) entry.oauth = true
|
|
80
81
|
entry.env = server.env.map(row => row.secret
|
|
81
82
|
? { name: row.name, secret: true, configured: row.configured }
|
|
82
83
|
: { name: row.name, secret: false, ...(row.value !== undefined && row.value.length > 0 ? { value: row.value } : {}) })
|
|
@@ -150,6 +151,7 @@ export function parseServersJson(text: string): { ok: true; servers: readonly Se
|
|
|
150
151
|
url: typeof cfg.url === 'string' ? cfg.url : '',
|
|
151
152
|
headers: cfg.headers,
|
|
152
153
|
toolCallTimeoutMs: typeof cfg.toolCallTimeoutMs === 'number' ? cfg.toolCallTimeoutMs : 60000,
|
|
154
|
+
oauth: cfg.oauth === true,
|
|
153
155
|
failOnStartupError: cfg.failOnStartupError !== false,
|
|
154
156
|
}
|
|
155
157
|
servers.push({ server, env })
|
package/src/client/locales.ts
CHANGED
|
@@ -39,6 +39,8 @@ export const zh = {
|
|
|
39
39
|
removeEnvVar: '移除该变量',
|
|
40
40
|
toolCallTimeoutMs: '工具调用超时(毫秒)',
|
|
41
41
|
failOnStartupError: '启动连接失败时拒绝挂载',
|
|
42
|
+
oauthAuth: '使用 OAuth 授权(浏览器授权 + token 托管)',
|
|
43
|
+
oauthAuthHint: '仅当该服务器确实使用 OAuth(MCP 授权码 + PKCE)时勾选。用静态 token 或自定义请求头认证的服务器请勿勾选——否则服务器返回 401 时会被当成 OAuth 挑战,从而反复弹出浏览器授权。',
|
|
42
44
|
statusMounting: '连接中',
|
|
43
45
|
statusLive: '已连接',
|
|
44
46
|
statusFailed: '挂载失败',
|
|
@@ -167,6 +169,8 @@ export const en = {
|
|
|
167
169
|
removeEnvVar: 'Remove this variable',
|
|
168
170
|
toolCallTimeoutMs: 'Tool-call timeout (ms)',
|
|
169
171
|
failOnStartupError: 'Reject the mount when the startup connection fails',
|
|
172
|
+
oauthAuth: 'Use OAuth authorization (browser authorization + token storage)',
|
|
173
|
+
oauthAuthHint: 'Tick only when the server really uses OAuth (MCP authorization-code + PKCE). Servers that authenticate with static tokens or custom headers must leave this off — otherwise a 401 is treated as an OAuth challenge and the browser authorization opens again and again.',
|
|
170
174
|
statusMounting: 'Connecting',
|
|
171
175
|
statusLive: 'Connected',
|
|
172
176
|
statusFailed: 'Mount failed',
|
package/src/client/mcp-store.ts
CHANGED
|
@@ -25,6 +25,8 @@ export interface McpDraft {
|
|
|
25
25
|
readonly headersText: string
|
|
26
26
|
/** Timeout as editor text; blank falls back to the default. */
|
|
27
27
|
readonly toolCallTimeoutMs: string
|
|
28
|
+
/** Explicit OAuth switch: only then does the Host attach an OAuth provider. */
|
|
29
|
+
readonly oauth: boolean
|
|
28
30
|
readonly failOnStartupError: boolean
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -78,6 +80,9 @@ export function emptyDraft(): McpDraft {
|
|
|
78
80
|
// Reject the mount by default when the startup connection fails, so a
|
|
79
81
|
// broken server never registers stale tools.
|
|
80
82
|
failOnStartupError: true,
|
|
83
|
+
// OAuth is opt-in: guessing it from the headers opened the browser for
|
|
84
|
+
// servers that authenticate with static tokens.
|
|
85
|
+
oauth: false,
|
|
81
86
|
}
|
|
82
87
|
}
|
|
83
88
|
|
|
@@ -94,6 +99,7 @@ export function draftFromServer(server: McpServerView): McpDraft {
|
|
|
94
99
|
url: server.url,
|
|
95
100
|
headersText: server.headers.map(header => `${header.name}: ${header.value}`).join('\n'),
|
|
96
101
|
toolCallTimeoutMs: String(server.toolCallTimeoutMs),
|
|
102
|
+
oauth: server.oauth === true,
|
|
97
103
|
failOnStartupError: server.failOnStartupError,
|
|
98
104
|
}
|
|
99
105
|
}
|
|
@@ -205,6 +211,7 @@ export function draftToSubmission(draft: McpDraft): McpSubmission {
|
|
|
205
211
|
url: draft.url.trim(),
|
|
206
212
|
headers: parseHeaders(draft.headersText),
|
|
207
213
|
toolCallTimeoutMs: parseTimeout(draft.toolCallTimeoutMs),
|
|
214
|
+
oauth: draft.oauth,
|
|
208
215
|
failOnStartupError: draft.failOnStartupError,
|
|
209
216
|
},
|
|
210
217
|
}
|
|
@@ -36,6 +36,7 @@ const _deepseek_ai_dsh_mcp_manager_mcpManager_list_result$schema = z.object({
|
|
|
36
36
|
})).readonly(),
|
|
37
37
|
'toolCallTimeoutMs': z.number().readonly(),
|
|
38
38
|
'failOnStartupError': z.boolean().readonly(),
|
|
39
|
+
'oauth': z.boolean().readonly().optional(),
|
|
39
40
|
'status': z.object({
|
|
40
41
|
'phase': z.union([z.literal("failed"), z.literal("stopped"), z.literal("mounting"), z.literal("live")]).readonly(),
|
|
41
42
|
'tools': z.array(z.string()).readonly(),
|
|
@@ -82,6 +83,7 @@ const _deepseek_ai_dsh_mcp_manager_mcpManager_test_parameter_0$schema = z.object
|
|
|
82
83
|
})).readonly(),
|
|
83
84
|
'toolCallTimeoutMs': z.number().readonly(),
|
|
84
85
|
'failOnStartupError': z.boolean().readonly(),
|
|
86
|
+
'oauth': z.boolean().readonly().optional(),
|
|
85
87
|
}).readonly(),
|
|
86
88
|
'env': z.array(z.object({
|
|
87
89
|
'name': z.string().readonly(),
|
|
@@ -119,6 +121,7 @@ const _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_parameter_0$schema = z.obje
|
|
|
119
121
|
})).readonly(),
|
|
120
122
|
'toolCallTimeoutMs': z.number().readonly(),
|
|
121
123
|
'failOnStartupError': z.boolean().readonly(),
|
|
124
|
+
'oauth': z.boolean().readonly().optional(),
|
|
122
125
|
}).readonly(),
|
|
123
126
|
'env': z.array(z.object({
|
|
124
127
|
'name': z.string().readonly(),
|
|
@@ -149,6 +152,7 @@ const _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_result$schema = z.union([z.
|
|
|
149
152
|
})).readonly(),
|
|
150
153
|
'toolCallTimeoutMs': z.number().readonly(),
|
|
151
154
|
'failOnStartupError': z.boolean().readonly(),
|
|
155
|
+
'oauth': z.boolean().readonly().optional(),
|
|
152
156
|
'status': z.object({
|
|
153
157
|
'phase': z.union([z.literal("failed"), z.literal("stopped"), z.literal("mounting"), z.literal("live")]).readonly(),
|
|
154
158
|
'tools': z.array(z.string()).readonly(),
|
|
@@ -191,6 +195,7 @@ const _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_parameter_0$schema = z.
|
|
|
191
195
|
})).readonly()]).readonly().optional(),
|
|
192
196
|
'toolCallTimeoutMs': z.number().readonly().optional(),
|
|
193
197
|
'failOnStartupError': z.boolean().readonly().optional(),
|
|
198
|
+
'oauth': z.boolean().readonly().optional(),
|
|
194
199
|
}).readonly(),
|
|
195
200
|
'env': z.array(z.object({
|
|
196
201
|
'name': z.string().readonly(),
|
|
@@ -226,6 +231,7 @@ const _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_result$schema = z.union
|
|
|
226
231
|
})).readonly(),
|
|
227
232
|
'toolCallTimeoutMs': z.number().readonly(),
|
|
228
233
|
'failOnStartupError': z.boolean().readonly(),
|
|
234
|
+
'oauth': z.boolean().readonly().optional(),
|
|
229
235
|
'status': z.object({
|
|
230
236
|
'phase': z.union([z.literal("failed"), z.literal("stopped"), z.literal("mounting"), z.literal("live")]).readonly(),
|
|
231
237
|
'tools': z.array(z.string()).readonly(),
|
|
@@ -347,6 +353,7 @@ const _deepseek_ai_dsh_mcp_manager_mcpManager_adopt_result$schema = z.union([z.o
|
|
|
347
353
|
})).readonly(),
|
|
348
354
|
'toolCallTimeoutMs': z.number().readonly(),
|
|
349
355
|
'failOnStartupError': z.boolean().readonly(),
|
|
356
|
+
'oauth': z.boolean().readonly().optional(),
|
|
350
357
|
'status': z.object({
|
|
351
358
|
'phase': z.union([z.literal("failed"), z.literal("stopped"), z.literal("mounting"), z.literal("live")]).readonly(),
|
|
352
359
|
'tools': z.array(z.string()).readonly(),
|
|
@@ -407,6 +414,7 @@ export const TYPERT_REMOTE = {
|
|
|
407
414
|
mode: 'strict',
|
|
408
415
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerRemoveRequest',
|
|
409
416
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_delete_parameter_0$schema,
|
|
417
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_delete_parameter_0$schema,
|
|
410
418
|
},
|
|
411
419
|
},
|
|
412
420
|
],
|
|
@@ -414,6 +422,7 @@ export const TYPERT_REMOTE = {
|
|
|
414
422
|
mode: 'strict',
|
|
415
423
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerRemoveResult',
|
|
416
424
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_delete_result$schema,
|
|
425
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_delete_result$schema,
|
|
417
426
|
},
|
|
418
427
|
sourceLocation: {"file":"packages/mcp/mcp-manager/src/index.ts","line":399,"column":9},
|
|
419
428
|
},
|
|
@@ -429,6 +438,7 @@ export const TYPERT_REMOTE = {
|
|
|
429
438
|
mode: 'strict',
|
|
430
439
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerListResult',
|
|
431
440
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_list_result$schema,
|
|
441
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_list_result$schema,
|
|
432
442
|
},
|
|
433
443
|
sourceLocation: {"file":"packages/mcp/mcp-manager/src/index.ts","line":314,"column":9},
|
|
434
444
|
},
|
|
@@ -447,6 +457,7 @@ export const TYPERT_REMOTE = {
|
|
|
447
457
|
mode: 'strict',
|
|
448
458
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerTestRequest',
|
|
449
459
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_test_parameter_0$schema,
|
|
460
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_test_parameter_0$schema,
|
|
450
461
|
},
|
|
451
462
|
},
|
|
452
463
|
],
|
|
@@ -454,6 +465,7 @@ export const TYPERT_REMOTE = {
|
|
|
454
465
|
mode: 'strict',
|
|
455
466
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerTestResult',
|
|
456
467
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_test_result$schema,
|
|
468
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_test_result$schema,
|
|
457
469
|
},
|
|
458
470
|
sourceLocation: {"file":"packages/mcp/mcp-manager/src/index.ts","line":422,"column":9},
|
|
459
471
|
},
|
|
@@ -472,6 +484,7 @@ export const TYPERT_REMOTE = {
|
|
|
472
484
|
mode: 'strict',
|
|
473
485
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerUpsertRequest',
|
|
474
486
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_parameter_0$schema,
|
|
487
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_parameter_0$schema,
|
|
475
488
|
},
|
|
476
489
|
},
|
|
477
490
|
],
|
|
@@ -479,6 +492,7 @@ export const TYPERT_REMOTE = {
|
|
|
479
492
|
mode: 'strict',
|
|
480
493
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerUpsertResult',
|
|
481
494
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_result$schema,
|
|
495
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_upsert_result$schema,
|
|
482
496
|
},
|
|
483
497
|
sourceLocation: {"file":"packages/mcp/mcp-manager/src/index.ts","line":329,"column":9},
|
|
484
498
|
},
|
|
@@ -497,6 +511,7 @@ export const TYPERT_REMOTE = {
|
|
|
497
511
|
mode: 'strict',
|
|
498
512
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerUpsertJsonRequest',
|
|
499
513
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_parameter_0$schema,
|
|
514
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_parameter_0$schema,
|
|
500
515
|
},
|
|
501
516
|
},
|
|
502
517
|
],
|
|
@@ -504,6 +519,7 @@ export const TYPERT_REMOTE = {
|
|
|
504
519
|
mode: 'strict',
|
|
505
520
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerUpsertJsonResult',
|
|
506
521
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_result$schema,
|
|
522
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_upsertJson_result$schema,
|
|
507
523
|
},
|
|
508
524
|
sourceLocation: {"file":"lib/index.js"},
|
|
509
525
|
},
|
|
@@ -519,6 +535,7 @@ export const TYPERT_REMOTE = {
|
|
|
519
535
|
mode: 'strict',
|
|
520
536
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerToolsListResult',
|
|
521
537
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsList_result$schema,
|
|
538
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_toolsList_result$schema,
|
|
522
539
|
},
|
|
523
540
|
sourceLocation: {"file":"lib/index.js"},
|
|
524
541
|
},
|
|
@@ -537,6 +554,7 @@ export const TYPERT_REMOTE = {
|
|
|
537
554
|
mode: 'strict',
|
|
538
555
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerToolsSetRequest',
|
|
539
556
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsSet_parameter_0$schema,
|
|
557
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_toolsSet_parameter_0$schema,
|
|
540
558
|
},
|
|
541
559
|
},
|
|
542
560
|
],
|
|
@@ -544,6 +562,7 @@ export const TYPERT_REMOTE = {
|
|
|
544
562
|
mode: 'strict',
|
|
545
563
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerToolsSetResult',
|
|
546
564
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsSet_result$schema,
|
|
565
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_toolsSet_result$schema,
|
|
547
566
|
},
|
|
548
567
|
sourceLocation: {"file":"lib/index.js"},
|
|
549
568
|
},
|
|
@@ -562,6 +581,7 @@ export const TYPERT_REMOTE = {
|
|
|
562
581
|
mode: 'strict',
|
|
563
582
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerToolsModeRequest',
|
|
564
583
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsMode_parameter_0$schema,
|
|
584
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_toolsMode_parameter_0$schema,
|
|
565
585
|
},
|
|
566
586
|
},
|
|
567
587
|
],
|
|
@@ -569,6 +589,7 @@ export const TYPERT_REMOTE = {
|
|
|
569
589
|
mode: 'strict',
|
|
570
590
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerToolsModeResult',
|
|
571
591
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_toolsMode_result$schema,
|
|
592
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_toolsMode_result$schema,
|
|
572
593
|
},
|
|
573
594
|
sourceLocation: {"file":"lib/index.js"},
|
|
574
595
|
},
|
|
@@ -584,6 +605,7 @@ export const TYPERT_REMOTE = {
|
|
|
584
605
|
mode: 'strict',
|
|
585
606
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerEnvListResult',
|
|
586
607
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_envList_result$schema,
|
|
608
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_envList_result$schema,
|
|
587
609
|
},
|
|
588
610
|
sourceLocation: {"file":"lib/index.js"},
|
|
589
611
|
},
|
|
@@ -602,6 +624,7 @@ export const TYPERT_REMOTE = {
|
|
|
602
624
|
mode: 'strict',
|
|
603
625
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerEnvSetRequest',
|
|
604
626
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_envSet_parameter_0$schema,
|
|
627
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_envSet_parameter_0$schema,
|
|
605
628
|
},
|
|
606
629
|
},
|
|
607
630
|
],
|
|
@@ -609,6 +632,7 @@ export const TYPERT_REMOTE = {
|
|
|
609
632
|
mode: 'strict',
|
|
610
633
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerEnvSetResult',
|
|
611
634
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_envSet_result$schema,
|
|
635
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_envSet_result$schema,
|
|
612
636
|
},
|
|
613
637
|
sourceLocation: {"file":"lib/index.js"},
|
|
614
638
|
},
|
|
@@ -627,6 +651,7 @@ export const TYPERT_REMOTE = {
|
|
|
627
651
|
mode: 'strict',
|
|
628
652
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerAdoptRequest',
|
|
629
653
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_adopt_parameter_0$schema,
|
|
654
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_adopt_parameter_0$schema,
|
|
630
655
|
},
|
|
631
656
|
},
|
|
632
657
|
],
|
|
@@ -634,6 +659,7 @@ export const TYPERT_REMOTE = {
|
|
|
634
659
|
mode: 'strict',
|
|
635
660
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerAdoptResult',
|
|
636
661
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_adopt_result$schema,
|
|
662
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_adopt_result$schema,
|
|
637
663
|
},
|
|
638
664
|
sourceLocation: {"file":"lib/index.js"},
|
|
639
665
|
},
|
|
@@ -652,6 +678,7 @@ export const TYPERT_REMOTE = {
|
|
|
652
678
|
mode: 'strict',
|
|
653
679
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerReleaseRequest',
|
|
654
680
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_release_parameter_0$schema,
|
|
681
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_release_parameter_0$schema,
|
|
655
682
|
},
|
|
656
683
|
},
|
|
657
684
|
],
|
|
@@ -659,6 +686,7 @@ export const TYPERT_REMOTE = {
|
|
|
659
686
|
mode: 'strict',
|
|
660
687
|
typeSymbol: '@deepseek-ai/dsh-mcp-manager/types#McpManagerReleaseResult',
|
|
661
688
|
schema: _deepseek_ai_dsh_mcp_manager_mcpManager_release_result$schema,
|
|
689
|
+
create: () => _deepseek_ai_dsh_mcp_manager_mcpManager_release_result$schema,
|
|
662
690
|
},
|
|
663
691
|
sourceLocation: {"file":"lib/index.js"},
|
|
664
692
|
},
|
package/src/client/types.ts
CHANGED
|
@@ -44,6 +44,8 @@ export interface McpServerInput {
|
|
|
44
44
|
readonly url: string
|
|
45
45
|
readonly headers: readonly McpHeaderEntry[]
|
|
46
46
|
readonly toolCallTimeoutMs: number
|
|
47
|
+
/** Explicit OAuth switch: only then does the Host attach an OAuth provider. */
|
|
48
|
+
readonly oauth: boolean
|
|
47
49
|
readonly failOnStartupError: boolean
|
|
48
50
|
}
|
|
49
51
|
|
|
@@ -86,6 +88,8 @@ export interface McpServerView {
|
|
|
86
88
|
readonly env: readonly McpEnvVarView[]
|
|
87
89
|
readonly toolCallTimeoutMs: number
|
|
88
90
|
readonly failOnStartupError: boolean
|
|
91
|
+
/** Explicit OAuth switch of a managed row (absent for declared rows). */
|
|
92
|
+
readonly oauth?: boolean
|
|
89
93
|
readonly status: McpServerStatus
|
|
90
94
|
/** `plugin` = stored and mounted here; `cordis` = declared in a patch layer. */
|
|
91
95
|
readonly source?: McpServerSource
|