dsh-mcp-connector 0.1.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.md ADDED
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ 本项目遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/);首个公开版本从 `0.1.0` 开始。
4
+
5
+ ## [0.1.0] - 2026-08-20
6
+
7
+ ### Added
8
+
9
+ - DeepSeek Harness Desktop 左侧“MCP连接器”入口,位于“新会话”下、“工作区/会话列表”上,并提供 footer 自动降级。
10
+ - 图形化连接器市场与已安装列表,内置 4 个企查查连接器和本地 QCC Logo。
11
+ - OAuth 2.0 PKCE、自定义 MCP 配置、`mcpServers` JSON 导入和描述 URL 安装四条接入路径。
12
+ - 连接持久化、重启恢复、启停、断开、OAuth Token 刷新与撤销。
13
+ - 连接器详情弹框、按 Server 分组的工具描述/搜索/滚动,以及精选 Prompt 换一批。
14
+ - 示例 Prompt 一键带入 DSH 新会话,包含同源校验、超时提示和重复点击保护。
15
+ - 内置目录、远程 registry、本地覆盖、上下架与精选能力。
16
+ - 11 个 `mcp_connector_*` 对话工具。
17
+ - Node.js 20/22/24 CI、Tag 发布工作流和 npm 发布包白名单/敏感内容校验。
18
+
19
+ ### Security
20
+
21
+ - 凭证仅持久化在 DSH storage domain。
22
+ - 外部 URL 与导入 Header 执行安全校验。
23
+ - iframe 消息校验同源和消息来源。
24
+
25
+ [0.1.0]: https://github.com/duhu2000/dsh-mcp-connector/releases/tag/v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-mcp-connector contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # MCP连接器(DeepSeek Harness 插件)
2
+
3
+ 在 DeepSeek Harness Desktop 中提供类似 WorkBuddy 的 MCP 连接器市场与连接管理:浏览连接器、OAuth 授权、查看工具、快速发起对话,并管理已安装连接。
4
+
5
+ [![CI](https://github.com/duhu2000/dsh-mcp-connector/actions/workflows/ci.yml/badge.svg)](https://github.com/duhu2000/dsh-mcp-connector/actions/workflows/ci.yml)
6
+ [![npm](https://img.shields.io/npm/v/dsh-mcp-connector.svg)](https://www.npmjs.com/package/dsh-mcp-connector)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
8
+
9
+ ## 功能
10
+
11
+ - 左侧主导航入口:目标位置为“新会话”下方、“工作区/会话列表”上方;若 DSH DOM 结构不兼容,自动回退到底部公开插槽。
12
+ - 图形化市场:市场/已安装、搜索、连接状态与刷新。
13
+ - 连接器详情:精选 Prompt 优先展示,点击可带入 DSH 新会话;工具按 Server 分组,支持描述、搜索和独立滚动。
14
+ - 三种接入:OAuth 2.0 PKCE、自定义 URL/鉴权、导入 `mcpServers` JSON;也支持从连接器描述 URL 安装。
15
+ - 生命周期管理:连接持久化、重启恢复、启停、断开、OAuth 刷新与撤销。
16
+ - 目录运营:内置目录、远程 registry、本地覆盖,支持 `published` 上下架与 `featured` 精选。
17
+ - 对话工具:`mcp_connector_catalog`、`connect`、`configure`、`import_json`、`install_from_url`、`status`、`set_enabled`、`disconnect`、`refresh_catalog`、`publish`、`tools_list`。
18
+
19
+ 首版内置 4 个企查查连接器,卡片统一使用包内企查查 Logo;插件架构本身不限定厂商。
20
+
21
+ ## 安装
22
+
23
+ 要求:DeepSeek Harness Desktop/web profile,Node.js 20 或更高版本。
24
+
25
+ ```bash
26
+ dsh plugin --profile web add dsh-mcp-connector
27
+ ```
28
+
29
+ 也可使用安装脚本:
30
+
31
+ ```bash
32
+ bash <(curl -fsSL https://raw.githubusercontent.com/duhu2000/dsh-mcp-connector/main/install.sh)
33
+ ```
34
+
35
+ 安装或升级后需完全退出并重启 DeepSeek Harness Desktop。
36
+
37
+ ## 使用
38
+
39
+ 1. 点击左侧“🧩 MCP连接器”。
40
+ 2. 在市场中选择连接器并完成授权或配置。
41
+ 3. 打开卡片详情,可点击示例 Prompt 的发送按钮,在当前工作区创建/复用空白会话并写入草稿。
42
+ 4. 在“已安装”或对话工具中查看、停用、恢复或断开连接。
43
+
44
+ 连接成功后,工具按 `mcp__<serverName>__*` 前缀提供给模型。
45
+
46
+ ## 配置
47
+
48
+ Bundle 默认配置位于 `cordis.patch.yml`:
49
+
50
+ ```yaml
51
+ - id: mcp-connector
52
+ name: dsh-mcp-connector
53
+ config:
54
+ catalogUrl: ''
55
+ persistSecrets: true
56
+ entryPrefix: mcp
57
+ refreshSkewMs: 300000
58
+ openBrowser: true
59
+ ```
60
+
61
+ ## 开发与发布门禁
62
+
63
+ ```bash
64
+ npm run check
65
+ ```
66
+
67
+ 该命令依次执行语法检查、29 项测试和 npm 发布包白名单校验。CI 使用 `--legacy-peer-deps` 安装显式测试依赖,DSH 运行期 peer 仍由 Host 提供。`v*` Tag 会触发 GitHub Actions;Tag 必须与 `package.json` 版本一致。仓库配置 `NPM_TOKEN` 后自动发布 npm,否则只创建 GitHub Release。
68
+
69
+ 首个公开版本规划为 `dsh-mcp-connector@0.1.0`。
70
+
71
+ 版本能力与变更记录见 [CHANGELOG.md](CHANGELOG.md)。
72
+
73
+ ## 安全与限制
74
+
75
+ - 凭证只持久化在 DSH storage domain,不进入目录、Git 仓库或对话历史。
76
+ - 外部 URL 仅允许 HTTPS,HTTP 仅允许回环地址;导入配置会校验 URL 与 Header。
77
+ - 当前以 streamable-http 为主并兼容 SSE;stdio 配置会被明确跳过。
78
+ - 顶部入口通过 DSH 稳定 `data-slot` 定位并使用 React Portal;DSH 若移除该标记,入口会回退到底部,不影响连接器功能。
79
+
80
+ ## License
81
+
82
+ MIT
@@ -0,0 +1,162 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "connectors": [
4
+ {
5
+ "id": "qcc-company",
6
+ "name": "企查查·企业工商",
7
+ "vendor": "企查查 Qichacha",
8
+ "icon": "/mcp-connector/ui/assets/qcc-logo.svg",
9
+ "category": "企业数据",
10
+ "summary": "一站式企业工商 / 股权 / 经营信息查询",
11
+ "description": "覆盖工商注册、股东、实际控制人、对外投资、经营异常、行政处罚等企业全景数据,适用于尽调、风控、营销获客场景。",
12
+ "tags": ["工商", "风控", "尽调", "获客"],
13
+ "published": true,
14
+ "featured": true,
15
+ "homepage": "https://open.qcc.com",
16
+ "auth": {
17
+ "mode": "oauth2-pkce",
18
+ "issuer": "https://agent.qcc.com",
19
+ "scope": "mcp:tools",
20
+ "clientName": "DeepSeek Harness - MCP 连接器",
21
+ "tokenEndpointAuthMethod": "none",
22
+ "grantSharing": "issuer"
23
+ },
24
+ "servers": [
25
+ { "serverKey": "company", "url": "https://agent.qcc.com/mcp/company/stream", "serverName": "qcc-company", "transport": "streamable-http", "headers": {} },
26
+ { "serverKey": "risk", "url": "https://agent.qcc.com/mcp/risk/stream", "serverName": "qcc-risk", "transport": "streamable-http", "headers": {} },
27
+ { "serverKey": "ipr", "url": "https://agent.qcc.com/mcp/ipr/stream", "serverName": "qcc-ipr", "transport": "streamable-http", "headers": {} },
28
+ { "serverKey": "operation", "url": "https://agent.qcc.com/mcp/operation/stream", "serverName": "qcc-operation", "transport": "streamable-http", "headers": {} },
29
+ { "serverKey": "history", "url": "https://agent.qcc.com/mcp/history/stream", "serverName": "qcc-history", "transport": "streamable-http", "headers": {} },
30
+ { "serverKey": "executive", "url": "https://agent.qcc.com/mcp/executive/stream", "serverName": "qcc-executive", "transport": "streamable-http", "headers": {} }
31
+ ],
32
+ "prompts": [
33
+ { "title": "企业最新工商变更", "text": "查询 小米科技有限责任公司 的最新工商变更记录", "server": "company" },
34
+ { "title": "股东结构", "text": "查询 小米科技有限责任公司 的股东构成与出资信息", "server": "company" },
35
+ { "title": "实际控制人", "text": "查询 小米科技有限责任公司 的实际控制人信息", "server": "company" },
36
+ { "title": "主要人员(高管团队)", "text": "查询 小米科技有限责任公司 的主要人员信息", "server": "company" },
37
+ { "title": "对外投资", "text": "查询 小米科技有限责任公司 的对外投资信息", "server": "company" },
38
+ { "title": "受益所有人识别", "text": "查询 小米科技有限责任公司 的受益所有人识别信息", "server": "company" },
39
+ { "title": "企业风险全景扫描", "text": "对 小米科技有限责任公司 做一次企业风险全景扫描", "server": "risk" },
40
+ { "title": "失信信息", "text": "查询 小米科技有限责任公司 的失信信息", "server": "risk" },
41
+ { "title": "被执行人信息", "text": "查询 小米科技有限责任公司 的被执行人信息", "server": "risk" },
42
+ { "title": "经营异常", "text": "查询 小米科技有限责任公司 的经营异常信息", "server": "risk" },
43
+ { "title": "商标信息", "text": "查询 小米科技有限责任公司 的商标信息", "server": "ipr" },
44
+ { "title": "专利信息", "text": "查询 小米科技有限责任公司 的专利信息", "server": "ipr" },
45
+ { "title": "软件著作权", "text": "查询 小米科技有限责任公司 的软件著作权信息", "server": "ipr" },
46
+ { "title": "作品著作权", "text": "查询 小米科技有限责任公司 的作品著作权信息", "server": "ipr" },
47
+ { "title": "招投标信息", "text": "查询 小米科技有限责任公司 的招投标信息", "server": "operation" },
48
+ { "title": "资质证书", "text": "查询 小米科技有限责任公司 的资质证书信息", "server": "operation" },
49
+ { "title": "行政许可", "text": "查询 小米科技有限责任公司 的行政许可信息", "server": "operation" },
50
+ { "title": "新闻舆情", "text": "查询 小米科技有限责任公司 的新闻舆情信息", "server": "operation" },
51
+ { "title": "历史股东", "text": "查询 小米科技有限责任公司 的历史股东变动记录", "server": "history" },
52
+ { "title": "历史法定代表人", "text": "查询 小米科技有限责任公司 的历史法定代表人记录", "server": "history" },
53
+ { "title": "历史失信", "text": "查询 小米科技有限责任公司 的历史失信记录(已移出名单)", "server": "history" },
54
+ { "title": "历史行政处罚", "text": "查询 小米科技有限责任公司 的历史行政处罚记录", "server": "history" },
55
+ { "title": "董监高个人风险扫描", "text": "对 小米科技有限责任公司 的董监高 雷军 做一次个人风险全景扫描", "server": "executive" },
56
+ { "title": "担任法定代表人", "text": "查询 小米科技有限责任公司 的董监高 雷军 担任法定代表人的情况", "server": "executive" },
57
+ { "title": "在外任职", "text": "查询 小米科技有限责任公司 的董监高 雷军 的在外任职信息", "server": "executive" },
58
+ { "title": "全部关联企业", "text": "查询 小米科技有限责任公司 的董监高 雷军 的全部关联企业", "server": "executive" }
59
+ ]
60
+ },
61
+ {
62
+ "id": "qcc-legal",
63
+ "name": "企查查·法律数据",
64
+ "vendor": "企查查 Qichacha",
65
+ "icon": "/mcp-connector/ui/assets/qcc-logo.svg",
66
+ "category": "企业数据",
67
+ "summary": "法规条文 / 司法案例检索与核验",
68
+ "description": "法律法规逐字条文、指导性/公报/典型案例检索、案号引用核验,面向法律意见书与类案检索场景。",
69
+ "tags": ["法律", "法规", "案例", "核验"],
70
+ "published": true,
71
+ "featured": false,
72
+ "homepage": "https://open.qcc.com",
73
+ "auth": {
74
+ "mode": "oauth2-pkce",
75
+ "issuer": "https://agent.qcc.com",
76
+ "scope": "mcp:tools",
77
+ "clientName": "DeepSeek Harness - MCP 连接器",
78
+ "tokenEndpointAuthMethod": "none",
79
+ "grantSharing": "issuer"
80
+ },
81
+ "servers": [
82
+ { "serverKey": "regulation", "url": "https://agent.qcc.com/mcp/regulation/stream", "serverName": "qcc-regulation", "transport": "streamable-http", "headers": {} },
83
+ { "serverKey": "case", "url": "https://agent.qcc.com/mcp/case/stream", "serverName": "qcc-case", "transport": "streamable-http", "headers": {} }
84
+ ],
85
+ "prompts": [
86
+ { "title": "法规检索", "text": "检索与「劳动合同解除」相关的法律法规", "server": "regulation" },
87
+ { "title": "法条检索", "text": "检索与「劳动合同解除」相关的法条原文", "server": "regulation" },
88
+ { "title": "司法案例检索", "text": "检索与「劳动合同违法解除」相关的司法案例", "server": "case" },
89
+ { "title": "权威案例检索", "text": "检索与「劳动合同违法解除」相关的权威司法案例", "server": "case" }
90
+ ]
91
+ },
92
+ {
93
+ "id": "qcc-tender",
94
+ "name": "企查查·招投标",
95
+ "vendor": "企查查 Qichacha",
96
+ "icon": "/mcp-connector/ui/assets/qcc-logo.svg",
97
+ "category": "企业数据",
98
+ "summary": "招投标公告 / 中标结果 / 采购信息",
99
+ "description": "覆盖全国招投标公告、中标结果、采购信息,适用于竞对分析、市场研究、销售线索挖掘场景。",
100
+ "tags": ["招投标", "采购", "中标", "竞对"],
101
+ "published": true,
102
+ "featured": false,
103
+ "homepage": "https://open.qcc.com",
104
+ "auth": {
105
+ "mode": "oauth2-pkce",
106
+ "issuer": "https://agent.qcc.com",
107
+ "scope": "mcp:tools",
108
+ "clientName": "DeepSeek Harness - MCP 连接器",
109
+ "tokenEndpointAuthMethod": "none",
110
+ "grantSharing": "issuer"
111
+ },
112
+ "servers": [
113
+ { "serverKey": "tender", "url": "https://agent.qcc.com/mcp/tender/stream", "serverName": "qcc-tender", "transport": "streamable-http", "headers": {} }
114
+ ],
115
+ "prompts": [
116
+ { "title": "招投标检索", "text": "检索与「智慧城市」相关的招投标、采购和中标标讯", "server": "tender" },
117
+ { "title": "拟建项目检索", "text": "检索与「新能源汽车」相关的拟建项目", "server": "tender" },
118
+ { "title": "企业招投标检索", "text": "查询 华为技术有限公司 相关的招标、投标、中标和采购标讯", "server": "tender" }
119
+ ]
120
+ },
121
+ {
122
+ "id": "qcc-document",
123
+ "name": "企查查·文档报告",
124
+ "vendor": "企查查 Qichacha",
125
+ "icon": "/mcp-connector/ui/assets/qcc-logo.svg",
126
+ "category": "企业数据",
127
+ "summary": "企业报告生成 / 文档分析",
128
+ "description": "基于企业数据自动生成分析报告、尽职调查文档,支持文档结构化解析与内容提取。",
129
+ "tags": ["文档", "报告", "分析"],
130
+ "published": true,
131
+ "featured": false,
132
+ "homepage": "https://open.qcc.com",
133
+ "auth": {
134
+ "mode": "oauth2-pkce",
135
+ "issuer": "https://agent.qcc.com",
136
+ "scope": "mcp:tools",
137
+ "clientName": "DeepSeek Harness - MCP 连接器",
138
+ "tokenEndpointAuthMethod": "none",
139
+ "grantSharing": "issuer"
140
+ },
141
+ "servers": [
142
+ { "serverKey": "document", "url": "https://agent.qcc.com/mcp/document/stream", "serverName": "qcc-document", "transport": "streamable-http", "headers": {} }
143
+ ],
144
+ "prompts": []
145
+ },
146
+ {
147
+ "id": "legacy-internal",
148
+ "name": "内测·待上架连接器",
149
+ "vendor": "内部团队",
150
+ "category": "其他",
151
+ "summary": "下架示例:published=false 不出现在用户货架",
152
+ "description": "该条目用于演示「下架」语义——已装用户保留连接,但新用户刷新目录不可见。",
153
+ "tags": ["内测"],
154
+ "published": false,
155
+ "featured": false,
156
+ "auth": { "mode": "none" },
157
+ "servers": [
158
+ { "serverKey": "internal", "url": "https://mcp.internal.example.com/stream", "serverName": "internal-demo", "transport": "streamable-http", "headers": {} }
159
+ ]
160
+ }
161
+ ]
162
+ }
@@ -0,0 +1,166 @@
1
+ {
2
+ "$comment": "MCP连接器内置目录示例。published=true 才出现在用户货架;registry 中禁止携带任何密钥(加载时校验剥离)。",
3
+ "meta": {
4
+ "schemaVersion": 1,
5
+ "categories": ["企业数据", "办公协作", "地图出行", "金融行情", "开发工具", "数据库", "AI 模型", "其他"]
6
+ },
7
+ "connectors": [
8
+ {
9
+ "id": "qcc-company",
10
+ "name": "企查查·企业工商",
11
+ "vendor": "企查查 Qichacha",
12
+ "icon": "https://qcc-static.oss-cn-hangzhou.aliyuncs.com/mcp/qcc.svg",
13
+ "category": "企业数据",
14
+ "summary": "一站式企业工商 / 股权 / 经营信息查询",
15
+ "description": "覆盖工商注册、股东、实际控制人、对外投资、经营异常、行政处罚等企业全景数据,适用于尽调、风控、营销获客场景。",
16
+ "tags": ["工商", "风控", "尽调", "获客"],
17
+ "published": true,
18
+ "featured": true,
19
+ "homepage": "https://open.qcc.com",
20
+ "auth": {
21
+ "mode": "oauth2-pkce",
22
+ "issuer": "https://agent.qcc.com",
23
+ "scope": "mcp:tools",
24
+ "clientName": "DeepSeek Harness - MCP 连接器",
25
+ "tokenEndpointAuthMethod": "none",
26
+ "grantSharing": "issuer"
27
+ },
28
+ "servers": [
29
+ {
30
+ "serverKey": "company",
31
+ "url": "https://agent.qcc.com/mcp/company/stream",
32
+ "serverName": "qcc-company",
33
+ "transport": "streamable-http",
34
+ "headers": {}
35
+ },
36
+ {
37
+ "serverKey": "risk",
38
+ "url": "https://agent.qcc.com/mcp/risk/stream",
39
+ "serverName": "qcc-risk",
40
+ "transport": "streamable-http",
41
+ "headers": {}
42
+ },
43
+ {
44
+ "serverKey": "ipr",
45
+ "url": "https://agent.qcc.com/mcp/ipr/stream",
46
+ "serverName": "qcc-ipr",
47
+ "transport": "streamable-http",
48
+ "headers": {}
49
+ }
50
+ ]
51
+ },
52
+ {
53
+ "id": "qcc-legal",
54
+ "name": "企查查·法律数据",
55
+ "vendor": "企查查 Qichacha",
56
+ "icon": "https://qcc-static.oss-cn-hangzhou.aliyuncs.com/mcp/qcc-legal.svg",
57
+ "category": "企业数据",
58
+ "summary": "法规条文 / 司法案例检索与核验",
59
+ "description": "法律法规逐字条文、指导性/公报/典型案例检索、案号引用核验,面向法律意见书与类案检索场景。",
60
+ "tags": ["法律", "法规", "案例", "核验"],
61
+ "published": true,
62
+ "featured": false,
63
+ "homepage": "https://open.qcc.com",
64
+ "auth": {
65
+ "mode": "oauth2-pkce",
66
+ "issuer": "https://agent.qcc.com",
67
+ "scope": "mcp:tools",
68
+ "clientName": "DeepSeek Harness - MCP 连接器",
69
+ "tokenEndpointAuthMethod": "none",
70
+ "grantSharing": "issuer"
71
+ },
72
+ "servers": [
73
+ {
74
+ "serverKey": "regulation",
75
+ "url": "https://agent.qcc.com/mcp/regulation/stream",
76
+ "serverName": "qcc-regulation",
77
+ "transport": "streamable-http",
78
+ "headers": {}
79
+ },
80
+ {
81
+ "serverKey": "case",
82
+ "url": "https://agent.qcc.com/mcp/case/stream",
83
+ "serverName": "qcc-case",
84
+ "transport": "streamable-http",
85
+ "headers": {}
86
+ }
87
+ ]
88
+ },
89
+ {
90
+ "id": "amap-geo",
91
+ "name": "高德·地图出行",
92
+ "vendor": "高德开放平台",
93
+ "icon": "https://webapi.amap.com/theme/v1.3/open_mac_color.png",
94
+ "category": "地图出行",
95
+ "summary": "地理编码 / 逆地理编码 / 路径规划 / POI 检索",
96
+ "description": "示例:api-key 型连接器。用户在自定义配置里填入厂商下发的 API Key,即可获得地图与位置类 MCP 工具。",
97
+ "tags": ["地图", "定位", "POI", "路线"],
98
+ "published": true,
99
+ "featured": false,
100
+ "homepage": "https://lbs.amap.com",
101
+ "auth": {
102
+ "mode": "api-key",
103
+ "apiKeyHeader": "X-Api-Key",
104
+ "clientName": "DeepSeek Harness - MCP 连接器"
105
+ },
106
+ "servers": [
107
+ {
108
+ "serverKey": "geo",
109
+ "url": "https://mcp.amap.com/stream",
110
+ "serverName": "amap-geo",
111
+ "transport": "streamable-http",
112
+ "headers": {}
113
+ }
114
+ ]
115
+ },
116
+ {
117
+ "id": "vendor-stock",
118
+ "name": "行情·示例厂商",
119
+ "vendor": "某金融数据厂商",
120
+ "icon": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iLi4uIi8+",
121
+ "category": "金融行情",
122
+ "summary": "A 股 / 港股 / 美股行情与基本面(示例)",
123
+ "description": "示例:bearer 型连接器。用户在自定义配置里粘贴 Bearer Token 即可连接;目录仅含模板,不含密钥。",
124
+ "tags": ["行情", "选股", "基本面"],
125
+ "published": true,
126
+ "featured": false,
127
+ "homepage": "https://example.com/mcp",
128
+ "auth": {
129
+ "mode": "bearer",
130
+ "clientName": "DeepSeek Harness - MCP 连接器"
131
+ },
132
+ "servers": [
133
+ {
134
+ "serverKey": "market",
135
+ "url": "https://mcp.example.com/market/stream",
136
+ "serverName": "example-market",
137
+ "transport": "streamable-http",
138
+ "headers": {}
139
+ }
140
+ ]
141
+ },
142
+ {
143
+ "id": "legacy-internal",
144
+ "name": "内测·待上架连接器",
145
+ "vendor": "内部团队",
146
+ "icon": "data:image/svg+xml;base64,PHN2Zy8+",
147
+ "category": "其他",
148
+ "summary": "下架示例:published=false 不出现在用户货架",
149
+ "description": "该条目用于演示「下架」语义——已装用户保留连接,但新用户刷新目录不可见。",
150
+ "tags": ["内测"],
151
+ "published": false,
152
+ "featured": false,
153
+ "homepage": "https://example.com",
154
+ "auth": { "mode": "none" },
155
+ "servers": [
156
+ {
157
+ "serverKey": "internal",
158
+ "url": "https://mcp.internal.example.com/stream",
159
+ "serverName": "internal-demo",
160
+ "transport": "streamable-http",
161
+ "headers": {}
162
+ }
163
+ ]
164
+ }
165
+ ]
166
+ }
@@ -0,0 +1,12 @@
1
+ # MCP连接器 插件(DSH Bundle patch)
2
+ # 作为 bundle 被合入 profile 时,自动插入本插件行。
3
+ # 插件负责连接器目录、三通道连接、凭证存储与 mcp-client 条目动态配置。
4
+ - insert:
5
+ - id: mcp-connector
6
+ name: 'dsh-mcp-connector'
7
+ config:
8
+ catalogUrl: ''
9
+ persistSecrets: true
10
+ entryPrefix: 'mcp'
11
+ refreshSkewMs: 300000
12
+ openBrowser: true
package/install.sh ADDED
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env bash
2
+ # dsh-mcp-connector 一键安装脚本(DeepSeek Harness)
3
+ # 用法:
4
+ # 本地: bash install.sh
5
+ # 远端: bash <(curl -fsSL https://raw.githubusercontent.com/duhu2000/dsh-mcp-connector/main/install.sh)
6
+ # 支持:优先 dsh CLI(自动注册 bundle);无 dsh 时回退 pnpm 并兜底注册 bundles。
7
+ # 幂等:重复执行不会重复注册或破坏已有配置。
8
+ set -euo pipefail
9
+
10
+ PKG="dsh-mcp-connector"
11
+ DSH_HOME="${DSH_HOME:-$HOME/.dsh}"
12
+ PROFILE="${DSH_PROFILE:-web}"
13
+ PROFILE_DIR="$DSH_HOME/profiles/$PROFILE"
14
+ PJ="$PROFILE_DIR/package.json"
15
+
16
+ echo "==> 目标 profile: $PROFILE_DIR"
17
+
18
+ if [ ! -d "$PROFILE_DIR" ]; then
19
+ echo "错误:profile 不存在:$PROFILE_DIR"
20
+ echo "请确认 DSH_HOME 与 DSH_PROFILE(默认 ~/.dsh 与 web)。"
21
+ exit 1
22
+ fi
23
+
24
+ if command -v dsh >/dev/null 2>&1; then
25
+ echo "==> dsh plugin --profile $PROFILE add $PKG"
26
+ dsh plugin --profile "$PROFILE" add "$PKG"
27
+ else
28
+ if command -v pnpm >/dev/null 2>&1; then
29
+ echo "==> 未找到 dsh CLI,回退 pnpm 安装(需自行确保 bundle 注册,见下)"
30
+ (cd "$PROFILE_DIR" && pnpm add "$PKG")
31
+ else
32
+ echo "错误:未找到 dsh 或 pnpm,无法安装。请先安装 DeepSeek Harness。"
33
+ exit 1
34
+ fi
35
+ fi
36
+
37
+ if [ -f "$PJ" ]; then
38
+ NEED=$(python3 - "$PJ" "$PKG" <<'PY' 2>/dev/null || echo "1"
39
+ import json, sys
40
+ d = json.load(open(sys.argv[1]))
41
+ print("0" if sys.argv[2] in d.get("dsh", {}).get("profile", {}).get("bundles", []) else "1")
42
+ PY
43
+ )
44
+ if [ "$NEED" = "1" ]; then
45
+ echo "==> 注册 bundle:$PKG"
46
+ python3 - "$PJ" "$PKG" <<'PY'
47
+ import json, sys
48
+ p, pkg = sys.argv[1], sys.argv[2]
49
+ d = json.load(open(p))
50
+ d.setdefault("dsh", {}).setdefault("profile", {}).setdefault("bundles", []).append(pkg)
51
+ json.dump(d, open(p, "w"), indent=2)
52
+ print("已添加", pkg)
53
+ PY
54
+ else
55
+ echo "==> bundle 已注册"
56
+ fi
57
+ else
58
+ echo "警告:未找到 $PJ,请确认 profile 完整。"
59
+ fi
60
+
61
+ echo
62
+ echo "✅ 安装完成!最后一步:重启 DeepSeek Harness(停止后重新运行 dsh web)。"
63
+ echo " 重启后点击左侧「MCP连接器」,或在对话中输入「列出连接器」浏览货架。"
64
+ echo " 详见:https://github.com/duhu2000/dsh-mcp-connector"
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Loopback 回调服务器(OAuth Native/Desktop 场景)
3
+ * 监听 127.0.0.1:{随机端口}/callback,接收授权页回跳的 code + state。
4
+ * 约束:先启动监听再打开授权页;收到回调后先校验 state;code 只使用一次。
5
+ */
6
+ import { createServer } from 'node:http';
7
+
8
+ export class CallbackTimeoutError extends Error {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = 'CallbackTimeoutError';
12
+ }
13
+ }
14
+
15
+ /**
16
+ * 启动 loopback 回调监听。
17
+ * @returns {Promise<{port:number, url:string, waitForCallback:()=>Promise<{code:string,state:string}>, close:()=>Promise<void>}>}
18
+ */
19
+ export async function startCallbackServer({ path = '/callback', port = 0, host = '127.0.0.1', timeoutMs = 300_000, signal } = {}) {
20
+ if (!path.startsWith('/')) path = `/${path}`;
21
+
22
+ let resolveCallback;
23
+ let rejectCallback;
24
+ const callbackPromise = new Promise((resolve, reject) => {
25
+ resolveCallback = resolve;
26
+ rejectCallback = reject;
27
+ });
28
+ callbackPromise.catch(() => {});
29
+
30
+ const onAbort = () => rejectCallback(new CallbackTimeoutError('callback wait aborted'));
31
+ if (signal) {
32
+ if (signal.aborted) onAbort();
33
+ else signal.addEventListener('abort', onAbort, { once: true });
34
+ }
35
+
36
+ const timer = setTimeout(() => {
37
+ rejectCallback(new CallbackTimeoutError(`no callback received within ${timeoutMs}ms`));
38
+ }, timeoutMs);
39
+
40
+ const server = createServer((req, res) => {
41
+ const requestUrl = new URL(req.url, `http://${host}:${port}`);
42
+ if (requestUrl.pathname === path) {
43
+ const code = requestUrl.searchParams.get('code');
44
+ const state = requestUrl.searchParams.get('state');
45
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
46
+ res.end(
47
+ '<!doctype html><html><head><meta charset="utf-8"><title>MCP 连接器授权</title></head>' +
48
+ '<body style="font-family:system-ui;text-align:center;padding-top:80px">' +
49
+ '<h2>✅ 授权成功</h2><p>外部 MCP 已连接,可以关闭此页面并返回 DeepSeek Harness。</p>' +
50
+ '</body></html>',
51
+ );
52
+ if (code !== null && state !== null) {
53
+ resolveCallback({ code, state });
54
+ } else {
55
+ rejectCallback(new Error('callback missing code or state'));
56
+ }
57
+ return;
58
+ }
59
+ if (requestUrl.pathname === '/' || requestUrl.pathname === '/health') {
60
+ res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
61
+ res.end('mcp-connector callback server is running');
62
+ return;
63
+ }
64
+ res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });
65
+ res.end('not found');
66
+ });
67
+
68
+ await new Promise((resolve, reject) => {
69
+ server.once('error', reject);
70
+ server.listen(port, host, () => resolve());
71
+ });
72
+
73
+ const actualPort = server.address().port;
74
+ const url = `http://${host}:${actualPort}${path}`;
75
+
76
+ const close = () =>
77
+ new Promise((resolve) => {
78
+ clearTimeout(timer);
79
+ if (signal) signal.removeEventListener('abort', onAbort);
80
+ server.close(() => resolve());
81
+ });
82
+
83
+ const waitForCallback = async () => {
84
+ try {
85
+ return await callbackPromise;
86
+ } finally {
87
+ await close();
88
+ }
89
+ };
90
+
91
+ return { port: actualPort, url, waitForCallback, close };
92
+ }