dsh-mcp-connector 0.2.12 → 0.2.13

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 CHANGED
@@ -4,6 +4,22 @@
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.2.13] - 2026-08-24
8
+
9
+ ### Added
10
+
11
+ - 当前市场已上架连接器全部进入推荐位;独立 Registry 新增 GitHub、Cloudflare、Notion、Tavily 四张经过官方配置与公开端点探针核验的推荐卡片。
12
+
13
+ ### Changed
14
+
15
+ - 市场筛选精简为“全部 / 推荐 / 业务分类”,移除服务商下拉框和 OAuth、Key / Token、免密接入方式筛选,降低首屏信息密度。
16
+ - 独立 Registry 的北大法宝、Wind、八爪鱼、QVeris、盈米统一使用标准分类并进入推荐位。
17
+
18
+ ### Verification
19
+
20
+ - 84 项插件自动测试、lint、内置目录校验与 45 个 npm 发布文件白名单/敏感内容扫描通过。
21
+ - Registry 9 项测试、9 条连接器构建、schema 校验与远程图标检查通过;GitHub、Cloudflare、Notion、Tavily 均完成 MCP 端点与鉴权元数据探针,未代替用户执行 OAuth 登录或授权后工具调用。
22
+
7
23
  ## [0.2.12] - 2026-08-23
8
24
 
9
25
  ### Added
package/README.en.md CHANGED
@@ -15,7 +15,7 @@ Browse and install MCP connectors from different providers in DeepSeek Harness D
15
15
  ## Features
16
16
 
17
17
  - A primary sidebar entry below New Conversation and above workspaces/conversations, with a public footer-slot fallback for incompatible DSH DOM versions.
18
- - Searchable Marketplace and Installed views, featured and nine-category filters, provider and connection-method filters, catalog refresh, and active health checks that distinguish Configured, Connected, Reauthorization Required, Partially Unavailable, and Connection Error states.
18
+ - Searchable Marketplace and Installed views, featured and nine-category filters, catalog refresh, and active health checks that distinguish Configured, Connected, Reauthorization Required, Partially Unavailable, and Connection Error states.
19
19
  - OAuth 2.0 Authorization Code with PKCE, API key/Bearer/unauthenticated HTTP configuration, stdio local-process configuration, and `mcpServers` JSON import.
20
20
  - Installation from a credential-free connector descriptor URL.
21
21
  - Credential and MCP initialize validation before API-key connectors are saved as installed.
@@ -26,7 +26,7 @@ Browse and install MCP connectors from different providers in DeepSeek Harness D
26
26
  - A standalone remote Registry, allowing new marketplace cards to appear after refresh without publishing a new npm version.
27
27
  - Explicit, non-destructive migration of authorization from the two earlier Qichacha OAuth plugins.
28
28
 
29
- The first four bundled cards are Qichacha connectors, followed by PKULaw and Wind. After a remote Registry refresh, Yingmi, QVeris, and Bazhuayu Cloud Collection are also available, for nine published marketplace cards in total. Bazhuayu is the first third-party example to exercise the complete OAuth 2.1 + PKCE dynamic-registration flow; the architecture remains provider-neutral.
29
+ The first four bundled cards are Qichacha connectors, followed by PKULaw and Wind. After a remote Registry refresh, Yingmi, QVeris, Bazhuayu Cloud Collection, GitHub, Cloudflare, Notion, and Tavily are also available, for 13 published marketplace cards after deduplication. Bazhuayu is the first third-party example to exercise the complete OAuth 2.1 + PKCE dynamic-registration flow; the architecture remains provider-neutral.
30
30
 
31
31
  ## Interface and demo
32
32
 
@@ -101,7 +101,7 @@ npm run dev:ui
101
101
 
102
102
  `npm run check` performs syntax checks, automated tests, and an npm package allowlist/sensitive-content audit. `npm run market:check` tracks the external DSH marketplace PR and live directory. Tags matching `v*` trigger GitHub Actions; the tag must match `package.json`. npm releases use Trusted Publishing through GitHub OIDC and do not require a long-lived `NPM_TOKEN`.
103
103
 
104
- The current public version is [`dsh-mcp-connector@0.2.11`](https://www.npmjs.com/package/dsh-mcp-connector), with [GitHub Release v0.2.11](https://github.com/duhu2000/dsh-mcp-connector/releases/tag/v0.2.11).
104
+ The current public version is [`dsh-mcp-connector@0.2.13`](https://www.npmjs.com/package/dsh-mcp-connector), with [GitHub Release v0.2.13](https://github.com/duhu2000/dsh-mcp-connector/releases/tag/v0.2.13).
105
105
 
106
106
  See [CHANGELOG.md](CHANGELOG.md) for version history and [docs/DESKTOP-E2E.md](docs/DESKTOP-E2E.md) for the Desktop release checklist.
107
107
 
package/README.md CHANGED
@@ -15,7 +15,7 @@
15
15
  ## 功能
16
16
 
17
17
  - 左侧主导航入口:目标位置为“新会话”下方、“工作区/会话列表”上方;若 DSH DOM 结构不兼容,自动回退到底部公开插槽。
18
- - 图形化市场:市场/已安装、推荐与 9 类业务分类、全文搜索、服务商/接入方式组合筛选、刷新与主动健康检查;区分“已配置”、“已连接”、“需重新授权”、“部分异常”和“连接异常”。
18
+ - 图形化市场:市场/已安装、推荐与 9 类业务分类、全文搜索、刷新与主动健康检查;区分“已配置”、“已连接”、“需重新授权”、“部分异常”和“连接异常”。
19
19
  - 图形化添加:手动 HTTP/stdio、`mcpServers` JSON、连接器描述 URL 三种入口,失败时保留表单并给出修复建议。
20
20
  - 连接器详情:精选 Prompt 优先展示,点击可带入 DSH 新会话;工具按 Server 分组,支持描述、搜索和独立滚动。
21
21
  - Prompt 模板:使用 `{{company}}` 等变量,发送前填写真实查询主体。
@@ -28,7 +28,7 @@
28
28
  - 平滑迁移:显式扫描并复制两个旧企查查 OAuth 插件授权;不删除原插件或原凭据。
29
29
  - 对话工具:`mcp_connector_catalog`、`connect`、`configure`、`import_json`、`install_from_url`、`status`、`health_check`、`set_enabled`、`disconnect`、`refresh_catalog`、`publish`、`tools_list`。
30
30
 
31
- 随包目录前 4 张为企查查连接器,另含“北大法宝·法律检索”和“Wind·股票数据”。远程 Registry 刷新后还会加入“盈米·基金投顾”、“QVerisMCP”和“八爪鱼·云采集”,当前共 9 张已发布市场卡片;其中八爪鱼是首个完整跑通标准 OAuth 2.1 + PKCE 动态注册链路的第三方示例,插件架构不限定厂商。
31
+ 随包目录前 4 张为企查查连接器,另含“北大法宝·法律检索”和“Wind·股票数据”。远程 Registry 刷新后还会加入“盈米·基金投顾”、“QVerisMCP”、“八爪鱼·云采集”、GitHub、Cloudflare、Notion 和 Tavily,合并去重后当前共 13 张已发布市场卡片;其中八爪鱼是首个完整跑通标准 OAuth 2.1 + PKCE 动态注册链路的第三方示例,插件架构不限定厂商。
32
32
 
33
33
  ## 界面与演示
34
34
 
@@ -96,7 +96,7 @@ npm run dev:ui
96
96
 
97
97
  `check` 执行语法检查、自动测试和 npm 发布包白名单校验;`market:check` 检查外部 DSH 市场 PR 与线上目录;`dev:ui` 启动不含真实凭据的本地 mock 市场。CI 使用 `--legacy-peer-deps` 安装显式测试依赖,DSH 运行期 peer 仍由 Host 提供。`v*` Tag 会触发 GitHub Actions;Tag 必须与 `package.json` 版本一致。Release 通过 npm Trusted Publishing (GitHub OIDC) 发布,不依赖长期 `NPM_TOKEN`。
98
98
 
99
- 当前公开版本为 [`dsh-mcp-connector@0.2.11`](https://www.npmjs.com/package/dsh-mcp-connector),对应 [GitHub Release v0.2.11](https://github.com/duhu2000/dsh-mcp-connector/releases/tag/v0.2.11)。
99
+ 当前公开版本为 [`dsh-mcp-connector@0.2.13`](https://www.npmjs.com/package/dsh-mcp-connector),对应 [GitHub Release v0.2.13](https://github.com/duhu2000/dsh-mcp-connector/releases/tag/v0.2.13)。
100
100
 
101
101
  版本能力与变更记录见 [CHANGELOG.md](CHANGELOG.md)。
102
102
  Desktop 发版回归见 [docs/DESKTOP-E2E.md](docs/DESKTOP-E2E.md)。
@@ -72,7 +72,7 @@
72
72
  "description": "法律法规逐字条文、指导性/公报/典型案例检索、案号引用核验,面向法律意见书与类案检索场景。",
73
73
  "tags": ["法律", "法规", "案例", "核验"],
74
74
  "published": true,
75
- "featured": false,
75
+ "featured": true,
76
76
  "homepage": "https://open.qcc.com",
77
77
  "promptVariables": [
78
78
  { "name": "topic", "label": "法律主题", "default": "劳动合同解除", "placeholder": "例如:劳动合同解除", "required": true }
@@ -106,7 +106,7 @@
106
106
  "description": "覆盖全国招投标公告、中标结果、采购信息,适用于竞对分析、市场研究、销售线索挖掘场景。",
107
107
  "tags": ["招投标", "采购", "中标", "竞对"],
108
108
  "published": true,
109
- "featured": false,
109
+ "featured": true,
110
110
  "homepage": "https://open.qcc.com",
111
111
  "promptVariables": [
112
112
  { "name": "keyword", "label": "项目关键词", "default": "智慧城市", "placeholder": "例如:智慧城市", "required": true },
@@ -139,7 +139,7 @@
139
139
  "description": "基于企业数据自动生成分析报告、尽职调查文档,支持文档结构化解析与内容提取。",
140
140
  "tags": ["文档", "报告", "分析"],
141
141
  "published": true,
142
- "featured": false,
142
+ "featured": true,
143
143
  "homepage": "https://open.qcc.com",
144
144
  "promptVariables": [
145
145
  { "name": "company", "label": "企业名称", "default": "小米科技有限责任公司", "placeholder": "例如:小米科技有限责任公司", "required": true }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-mcp-connector",
3
- "version": "0.2.12",
3
+ "version": "0.2.13",
4
4
  "description": "General-purpose MCP connector, connection manager, plugin extension, and integration marketplace for DeepSeek Harness, initiated and maintained by Qichacha/QCC.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
package/ui/index.html CHANGED
@@ -105,16 +105,10 @@
105
105
  .stats .count { font-size: 13px; color: var(--text-2); }
106
106
  .stats .count strong { color: var(--text); font-weight: 600; }
107
107
  .market-filters {
108
- display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
108
+ display: flex; align-items: center;
109
109
  margin-bottom: 14px; padding: 10px 12px;
110
110
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
111
111
  }
112
- .market-filters .filter-label { color: var(--muted); font-size: 12px; flex: 0 0 auto; }
113
- .market-filters select {
114
- min-width: 150px; height: 34px; border: 1px solid var(--line); border-radius: 8px;
115
- background: var(--bg); color: var(--text); padding: 0 30px 0 10px; font: inherit; font-size: 12px;
116
- }
117
- .market-filters select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-light); }
118
112
  .filter-chips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
119
113
  .filter-chip {
120
114
  border: 1px solid var(--line); background: var(--bg); color: var(--text-2);
@@ -122,8 +116,7 @@
122
116
  }
123
117
  .filter-chip:hover { border-color: var(--accent); color: var(--accent); }
124
118
  .filter-chip.active { border-color: var(--accent); background: var(--accent-light); color: var(--accent); font-weight: 600; }
125
- .filter-reset { margin-left: auto; }
126
- .category-chips { display: flex; gap: 6px; flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
119
+ .category-chips { width: 100%; display: flex; gap: 6px; flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
127
120
  .category-chip { flex-shrink: 0; }
128
121
 
129
122
  /* Grid - TraeWork 风格:3 列 */
@@ -370,8 +363,6 @@
370
363
  .card .actions { width: 100%; justify-content: flex-end; }
371
364
  .form-row { grid-template-columns: 1fr; gap: 0; }
372
365
  .market-filters { align-items: stretch; }
373
- .market-filters select { width: 100%; }
374
- .filter-reset { margin-left: 0; }
375
366
  }
376
367
 
377
368
  /* Scrollbar */
@@ -478,8 +469,6 @@
478
469
  let view = 'market';
479
470
  let marketItems = {};
480
471
  let searchQuery = '';
481
- let marketVendor = '';
482
- let marketAuth = '';
483
472
  let marketCategory = '';
484
473
  const PROMPT_PAGE_SIZE = 4;
485
474
  let detailPrompts = [];
@@ -706,13 +695,6 @@
706
695
  || (d.tags || []).some(t => t.toLowerCase().includes(q));
707
696
  }
708
697
 
709
- const AUTH_FILTERS = [
710
- { value: '', label: '全部接入' },
711
- { value: 'oauth2-pkce', label: 'OAuth' },
712
- { value: 'credential', label: 'Key / Token' },
713
- { value: 'none', label: '免密' },
714
- ];
715
-
716
698
  const CATEGORIES = [
717
699
  { value: '', label: '全部' },
718
700
  { value: 'recommended', label: '推荐' },
@@ -724,6 +706,7 @@
724
706
  { value: '调研分析', label: '调研分析' },
725
707
  { value: '设计创意', label: '设计创意' },
726
708
  { value: '效率工具', label: '效率工具' },
709
+ { value: '其他', label: '其他' },
727
710
  ];
728
711
 
729
712
  const CATEGORY_MAP = {
@@ -738,20 +721,12 @@
738
721
  if (!matchesSearch(d)) return false;
739
722
  if (marketCategory === 'recommended' && !d.featured) return false;
740
723
  if (marketCategory && marketCategory !== 'recommended' && normalizeCategory(d.category) !== marketCategory) return false;
741
- if (marketVendor && d.vendor !== marketVendor) return false;
742
- if (marketAuth === 'credential') return ['bearer', 'api-key'].includes(d.authMode);
743
- if (marketAuth && d.authMode !== marketAuth) return false;
744
724
  return true;
745
725
  }
746
726
 
747
- function marketFilterHtml(items) {
727
+ function marketFilterHtml() {
748
728
  const categoryChips = CATEGORIES.map((cat) => `<button class="filter-chip category-chip ${cat.value === marketCategory ? 'active' : ''}" type="button" data-category-filter="${esc(cat.value)}" aria-pressed="${cat.value === marketCategory ? 'true' : 'false'}">${esc(cat.label)}</button>`).join('');
749
- const vendors = [...new Set(items.map((item) => item.vendor).filter(Boolean))]
750
- .sort((a, b) => a.localeCompare(b, 'zh-CN'));
751
- const vendorOptions = [`<option value="">全部服务商</option>`, ...vendors.map((vendor) => `<option value="${esc(vendor)}" ${vendor === marketVendor ? 'selected' : ''}>${esc(vendor)}</option>`)].join('');
752
- const authButtons = AUTH_FILTERS.map((filter) => `<button class="filter-chip ${filter.value === marketAuth ? 'active' : ''}" type="button" data-auth-filter="${esc(filter.value)}" aria-pressed="${filter.value === marketAuth ? 'true' : 'false'}">${esc(filter.label)}</button>`).join('');
753
- const active = Boolean(marketVendor || marketAuth || marketCategory);
754
- return `<div class="market-filters" role="group" aria-label="市场筛选"><div class="filter-chips category-chips" role="group" aria-label="按分类筛选">${categoryChips}</div><span class="filter-label">服务商</span><select id="market-vendor-filter" aria-label="按服务商筛选">${vendorOptions}</select><span class="filter-label">接入方式</span><div class="filter-chips" role="group" aria-label="按接入方式筛选">${authButtons}</div><button class="text-btn filter-reset" id="market-filter-reset" type="button" ${active ? '' : 'hidden'}>清除筛选</button></div>`;
729
+ return `<div class="market-filters" role="group" aria-label="市场分类"><div class="filter-chips category-chips" role="group" aria-label="按分类筛选">${categoryChips}</div></div>`;
755
730
  }
756
731
 
757
732
  async function loadMarket({ checkHealth = true } = {}) {
@@ -765,13 +740,12 @@
765
740
  const filtered = items.filter(matchesMarketFilters);
766
741
  const count = filtered.length;
767
742
  const visible = filtered.slice(0, catalogRenderLimit);
768
- const authLabel = AUTH_FILTERS.find((filter) => filter.value === marketAuth)?.label;
769
743
  const categoryLabel = CATEGORIES.find((cat) => cat.value === marketCategory)?.label;
770
- const filterSummary = `${marketCategory ? ` · 分类「${esc(categoryLabel)}」` : ''}${marketVendor ? ` · 服务商「${esc(marketVendor)}」` : ''}${marketAuth ? ` · 接入方式「${esc(authLabel)}」` : ''}`;
744
+ const filterSummary = marketCategory ? ` · 分类「${esc(categoryLabel)}」` : '';
771
745
  const resultHtml = visible.length > 0
772
746
  ? `<div class="grid">${visible.map(cardHtml).join('')}</div>${visible.length < count ? `<button class="tools-more" id="catalog-more" type="button">再显示 ${Math.min(60, count - visible.length)} 个(剩余 ${count - visible.length})</button>` : ''}`
773
747
  : '<div class="empty">没有匹配当前筛选条件的连接器</div>';
774
- main.innerHTML = `${marketFilterHtml(items)}<div class="stats"><span class="count">共 <strong>${count}</strong> 个连接器${searchQuery ? ` · 搜索「${esc(searchQuery)}」` : ''}${filterSummary} · 点击卡片查看能力,点击「连接」完成授权</span></div>${resultHtml}`;
748
+ main.innerHTML = `${marketFilterHtml()}<div class="stats"><span class="count">共 <strong>${count}</strong> 个连接器${searchQuery ? ` · 搜索「${esc(searchQuery)}」` : ''}${filterSummary} · 点击卡片查看能力,点击「连接」完成授权</span></div>${resultHtml}`;
775
749
  if (checkHealth && !initialHealthCheckStarted && items.some((item) => item.connected?.length > 0)) {
776
750
  initialHealthCheckStarted = true;
777
751
  call('healthCheck', {}).then(() => {
@@ -1327,33 +1301,11 @@
1327
1301
  loadMarket({ checkHealth: false });
1328
1302
  return;
1329
1303
  }
1330
- const authFilter = event.target.closest('[data-auth-filter]');
1331
- if (authFilter) {
1332
- marketAuth = authFilter.dataset.authFilter || '';
1333
- catalogRenderLimit = 60;
1334
- loadMarket({ checkHealth: false });
1335
- return;
1336
- }
1337
- if (event.target.closest('#market-filter-reset')) {
1338
- marketVendor = '';
1339
- marketAuth = '';
1340
- marketCategory = '';
1341
- catalogRenderLimit = 60;
1342
- loadMarket({ checkHealth: false });
1343
- return;
1344
- }
1345
1304
  if (event.target.closest('#catalog-more')) {
1346
1305
  catalogRenderLimit += 60;
1347
1306
  loadMarket({ checkHealth: false });
1348
1307
  }
1349
1308
  });
1350
- main.addEventListener('change', (event) => {
1351
- if (event.target.id !== 'market-vendor-filter') return;
1352
- marketVendor = event.target.value;
1353
- catalogRenderLimit = 60;
1354
- loadMarket({ checkHealth: false });
1355
- });
1356
-
1357
1309
  $('#refresh').addEventListener('click', async () => {
1358
1310
  const r = await call('refreshCatalog', {});
1359
1311
  showToast(r.message, r.ok);