@xxxyz/dsh-mcp-manager 2.2.2 → 2.2.4
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/README.md +2 -1
- package/README_EN.md +2 -1
- package/lib/client.js +61 -13
- package/lib/index.js +51 -0
- package/package.json +1 -1
- package/show.png +0 -0
package/README.md
CHANGED
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
[](https://github.com/xxxyz/DeepSeekHarness-MCP-Manager)
|
|
18
18
|
[](https://dsh.market)
|
|
19
19
|
[](https://awesome-dsh-plugin.com)
|
|
20
|
+
[](https://whyihaveyou.github.io/dsh-suite/)
|
|
20
21
|
|
|
21
22
|
</div>
|
|
22
23
|
|
|
23
24
|
<div align="center">
|
|
24
|
-
🛒 已收录于 <a href="https://dsh.market"><b>dsh.market</b></a>
|
|
25
|
+
🛒 已收录于 <a href="https://dsh.market"><b>dsh.market</b></a> · <a href="https://awesome-dsh-plugin.com"><b>awesome-dsh-plugin.com</b></a> · <a href="https://whyihaveyou.github.io/dsh-suite/"><b>dsh-suite</b></a>
|
|
25
26
|
</div>
|
|
26
27
|
|
|
27
28
|
<div align="center">
|
package/README_EN.md
CHANGED
|
@@ -18,11 +18,12 @@
|
|
|
18
18
|
[](https://github.com/xxxyz/DeepSeekHarness-MCP-Manager)
|
|
19
19
|
[](https://dsh.market)
|
|
20
20
|
[](https://awesome-dsh-plugin.com)
|
|
21
|
+
[](https://whyihaveyou.github.io/dsh-suite/)
|
|
21
22
|
|
|
22
23
|
</div>
|
|
23
24
|
|
|
24
25
|
<div align="center">
|
|
25
|
-
🛒 Listed on <a href="https://dsh.market"><b>dsh.market</b></a>
|
|
26
|
+
🛒 Listed on <a href="https://dsh.market"><b>dsh.market</b></a> · <a href="https://awesome-dsh-plugin.com"><b>awesome-dsh-plugin.com</b></a> · <a href="https://whyihaveyou.github.io/dsh-suite/"><b>dsh-suite</b></a>
|
|
26
27
|
</div>
|
|
27
28
|
|
|
28
29
|
<div align="center">
|
package/lib/client.js
CHANGED
|
@@ -17,25 +17,25 @@ const factory = (require) => {
|
|
|
17
17
|
'.mcpm-msg.err{background:rgba(248,81,73,.15);border:1px solid rgba(248,81,73,.4)}' +
|
|
18
18
|
'.mcpm-msg.info{background:rgba(88,166,255,.15);border:1px solid rgba(88,166,255,.5)}' +
|
|
19
19
|
'.mcpm-path{font-family:monospace;font-size:11px;opacity:.7;word-break:break-all}' +
|
|
20
|
-
'.mcpm-btn{font-size:12px;padding:3px 10px;border-radius:5px;border:1px solid rgba(128,128,128,.5);background:transparent;color:inherit;cursor:pointer;white-space:nowrap}' +
|
|
20
|
+
'.mcpm-btn{font-size:12px;padding:3px 10px;border-radius:5px;border:1px solid var(--dsw-alias-border-l2, rgba(128,128,128,.5));background:transparent;color:inherit;cursor:pointer;white-space:nowrap}' +
|
|
21
21
|
'.mcpm-btn:disabled{opacity:.5;cursor:default}' +
|
|
22
22
|
'.mcpm-btn.primary{border-color:rgba(88,166,255,.7)}' +
|
|
23
23
|
'.mcpm-btn.danger{border-color:rgba(248,81,73,.7)}' +
|
|
24
|
-
'.mcpm-backup{display:flex;flex-direction:column;gap:8px;border:1px dashed rgba(128,128,128,.45);border-radius:8px;padding:10px 12px}' +
|
|
24
|
+
'.mcpm-backup{display:flex;flex-direction:column;gap:8px;border:1px dashed var(--dsw-alias-border-l2, rgba(128,128,128,.45));border-radius:8px;padding:10px 12px}' +
|
|
25
25
|
'.mcpm-backup .row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}' +
|
|
26
|
-
'.mcpm-json{width:100%;box-sizing:border-box;font-family:monospace;font-size:11px;min-height:70px;background:transparent;color:inherit;border:1px solid rgba(128,128,128,.4);border-radius:5px;padding:6px;white-space:pre;overflow:auto}' +
|
|
26
|
+
'.mcpm-json{width:100%;box-sizing:border-box;font-family:monospace;font-size:11px;min-height:70px;background:transparent;color:inherit;border:1px solid var(--dsw-alias-border-l2, rgba(128,128,128,.4));border-radius:5px;padding:6px;white-space:pre;overflow:auto}' +
|
|
27
27
|
'.mcpm-report{font-family:monospace;font-size:11px;opacity:.85;word-break:break-all}' +
|
|
28
28
|
'.mcpm-warn{font-size:11px;color:rgba(248,81,73,.95)}' +
|
|
29
|
-
'.mcpm-form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 12px;border:1px solid rgba(128,128,128,.35);border-radius:8px;padding:12px}' +
|
|
29
|
+
'.mcpm-form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 12px;border:1px solid var(--dsw-alias-border-l2, rgba(128,128,128,.35));border-radius:8px;padding:12px}' +
|
|
30
30
|
'.mcpm-form h3{margin:0;grid-column:1/-1;font-size:13px}' +
|
|
31
31
|
'.mcpm-form label{display:flex;flex-direction:column;gap:3px;font-size:12px}' +
|
|
32
32
|
'.mcpm-form .full{grid-column:1/-1}' +
|
|
33
|
-
'.mcpm-form input,.mcpm-form select,.mcpm-form textarea{font-size:12px;padding:4px 6px;border-radius:5px;border:1px solid rgba(128,128,128,.5);background:transparent;color:inherit}' +
|
|
33
|
+
'.mcpm-form input,.mcpm-form select,.mcpm-form textarea{font-size:12px;padding:4px 6px;border-radius:5px;border:1px solid var(--dsw-alias-border-l2, rgba(128,128,128,.5));background:transparent;color:inherit}' +
|
|
34
34
|
'.mcpm-form textarea{font-family:monospace;resize:vertical;min-height:44px}' +
|
|
35
|
-
'.mcpm-row{border:1px solid rgba(128,128,128,.35);border-radius:8px;padding:10px 12px;display:flex;flex-direction:column;gap:8px}' +
|
|
35
|
+
'.mcpm-row{border:1px solid var(--dsw-alias-border-l2, rgba(128,128,128,.35));border-radius:8px;padding:10px 12px;display:flex;flex-direction:column;gap:8px}' +
|
|
36
36
|
'.mcpm-row-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}' +
|
|
37
37
|
'.mcpm-name{font-weight:600}' +
|
|
38
|
-
'.mcpm-chip{font-size:11px;padding:1px 8px;border-radius:999px;border:1px solid rgba(128,128,128,.5);white-space:nowrap}' +
|
|
38
|
+
'.mcpm-chip{font-size:11px;padding:1px 8px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2, rgba(128,128,128,.5));white-space:nowrap}' +
|
|
39
39
|
'.mcpm-chip.on{background:rgba(46,160,67,.18);border-color:rgba(46,160,67,.55)}' +
|
|
40
40
|
'.mcpm-chip.off{background:rgba(128,128,128,.15)}' +
|
|
41
41
|
'.mcpm-chip.live{background:rgba(88,166,255,.15);border-color:rgba(88,166,255,.5)}' +
|
|
@@ -43,17 +43,27 @@ const factory = (require) => {
|
|
|
43
43
|
'.mcpm-chip.warn{background:rgba(219,154,4,.18);border-color:rgba(219,154,4,.6)}' +
|
|
44
44
|
'.mcpm-row-actions{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}' +
|
|
45
45
|
'.mcpm-detail{font-family:monospace;font-size:11px;opacity:.75;word-break:break-all}' +
|
|
46
|
-
'.mcpm-mask{position:fixed;inset:0;background:
|
|
47
|
-
'.mcpm-dialog{background:
|
|
46
|
+
'.mcpm-mask{position:fixed;inset:0;background:var(--dsw-alias-bg-mask-drop);display:flex;align-items:center;justify-content:center;z-index:99999}' +
|
|
47
|
+
'.mcpm-dialog{background:var(--dsw-alias-bg-layer-3, var(--dsw-alias-bg-base, #fff));border:1px solid var(--dsw-alias-border-l2, rgba(128,128,128,.5));border-radius:10px;padding:16px 18px;min-width:300px;max-width:440px;box-shadow:0 10px 34px rgba(0,0,0,.35);color:inherit}' +
|
|
48
48
|
'.mcpm-dialog-title{font-size:14px;font-weight:600;margin-bottom:8px}' +
|
|
49
49
|
'.mcpm-dialog-body{font-size:12px;opacity:.88;line-height:1.7;margin-bottom:16px;word-break:break-all}' +
|
|
50
50
|
'.mcpm-dialog-actions{display:flex;justify-content:flex-end;gap:8px}' +
|
|
51
|
-
'.skm-search{font-size:12px;padding:5px 8px;border-radius:6px;border:1px solid rgba(128,128,128,.5);background:transparent;color:inherit;width:100%;box-sizing:border-box}' +
|
|
52
|
-
'.skm-group-title{font-size:12px;font-weight:600;opacity:.85;margin-top:4px;padding-bottom:2px;border-bottom:1px solid rgba(128,128,128,.25)}' +
|
|
51
|
+
'.skm-search{font-size:12px;padding:5px 8px;border-radius:6px;border:1px solid var(--dsw-alias-border-l2, rgba(128,128,128,.5));background:transparent;color:inherit;width:100%;box-sizing:border-box}' +
|
|
52
|
+
'.skm-group-title{font-size:12px;font-weight:600;opacity:.85;margin-top:4px;padding-bottom:2px;border-bottom:1px solid var(--dsw-alias-border-l2, rgba(128,128,128,.25))}' +
|
|
53
53
|
'.skm-provider-title{font-size:12px;font-weight:600;cursor:pointer;user-select:none;margin-top:4px;opacity:.9}' +
|
|
54
54
|
'.mcpm-version{margin-left:8px;font-size:11px;font-weight:500;opacity:.55;letter-spacing:.3px;vertical-align:middle}' +
|
|
55
55
|
'.mcpm-token{display:flex;align-items:center;gap:8px;font-size:12px;opacity:.85}' +
|
|
56
|
-
'.mcpm-token input{font-size:12px;padding:3px 6px;border-radius:5px;border:1px solid rgba(128,128,128,.5);background:transparent;color:inherit;flex:1;max-width:260px}'
|
|
56
|
+
'.mcpm-token input{font-size:12px;padding:3px 6px;border-radius:5px;border:1px solid var(--dsw-alias-border-l2, rgba(128,128,128,.5));background:transparent;color:inherit;flex:1;max-width:260px}' +
|
|
57
|
+
'.mcpm-dialog-tools{max-width:560px;max-height:70vh;display:flex;flex-direction:column}' +
|
|
58
|
+
'.mcpm-dialog-tools .mcpm-dialog-body{flex:1;min-height:0;overflow:auto;margin-bottom:12px}' +
|
|
59
|
+
'.mcpm-tools-list{display:flex;flex-direction:column;gap:8px;padding-right:4px}' +
|
|
60
|
+
'.mcpm-tool{border:1px solid var(--dsw-alias-border-l2, rgba(128,128,128,.3));border-radius:6px;padding:8px 10px}' +
|
|
61
|
+
'.mcpm-tool-name{font-family:monospace;font-size:12px;font-weight:600;word-break:break-all}' +
|
|
62
|
+
'.mcpm-tool-params{display:flex;flex-direction:column;gap:2px;margin-top:6px;padding-top:6px;border-top:1px dashed var(--dsw-alias-border-l2, rgba(128,128,128,.3))}' +
|
|
63
|
+
'.mcpm-tool-param{display:flex;gap:8px;font-size:11px;align-items:baseline}' +
|
|
64
|
+
'.mcpm-tool-param-key{font-family:monospace;font-weight:600;min-width:80px;word-break:break-all}' +
|
|
65
|
+
'.mcpm-tool-param-type{opacity:.6;min-width:60px}' +
|
|
66
|
+
'.mcpm-tool-param-desc{opacity:.8;flex:1;word-break:break-all}'
|
|
57
67
|
|
|
58
68
|
function ensureCss() {
|
|
59
69
|
if (typeof document === 'undefined') return
|
|
@@ -136,6 +146,9 @@ const factory = (require) => {
|
|
|
136
146
|
const [backup, setBackup] = React.useState(null)
|
|
137
147
|
const [importText, setImportText] = React.useState('')
|
|
138
148
|
const [confirmRow, setConfirmRow] = React.useState(null)
|
|
149
|
+
const [toolPreview, setToolPreview] = React.useState(null)
|
|
150
|
+
const [toolPreviewErr, setToolPreviewErr] = React.useState(null)
|
|
151
|
+
const [toolPreviewBusy, setToolPreviewBusy] = React.useState(false)
|
|
139
152
|
|
|
140
153
|
const refresh = () => {
|
|
141
154
|
apiCall('mcpm-list', {}).then((res) => {
|
|
@@ -221,6 +234,15 @@ const factory = (require) => {
|
|
|
221
234
|
setConfirmRow(null)
|
|
222
235
|
if (row) run('mcpm-remove', { id: row.id, level: row.level }, row.id + ':remove')
|
|
223
236
|
}
|
|
237
|
+
const openToolPreview = (row) => {
|
|
238
|
+
setToolPreviewErr(null)
|
|
239
|
+
setToolPreviewBusy(true)
|
|
240
|
+
setToolPreview({ serverName: row.serverName, tools: [] })
|
|
241
|
+
apiCall('mcpm-tools', { serverName: row.serverName }).then((res) => {
|
|
242
|
+
if (res && res.ok) { setToolPreview({ serverName: row.serverName, tools: (res.tools) || [] }) }
|
|
243
|
+
else setToolPreviewErr((res && res.error) || '加载工具失败')
|
|
244
|
+
}).catch((e) => setToolPreviewErr(String((e && e.message) || e))).then(() => setToolPreviewBusy(false))
|
|
245
|
+
}
|
|
224
246
|
|
|
225
247
|
const rows = state.rows || []
|
|
226
248
|
const maskKv = (obj) => {
|
|
@@ -321,6 +343,7 @@ const factory = (require) => {
|
|
|
321
343
|
(row.headers ? 'headers: ' + maskKv(row.headers) + ' ' : '') + (row.env ? 'env: ' + Object.keys(row.env).map((k) => k + ': ****').join(' ') : '')),
|
|
322
344
|
React.createElement('div', { className: 'mcpm-row-actions' },
|
|
323
345
|
row.level !== 'loader' && React.createElement('button', { className: 'mcpm-btn', disabled: rowsLocked, onClick: () => openEdit(row) }, '编辑'),
|
|
346
|
+
typeof row.toolCount === 'number' && row.toolCount > 0 && React.createElement('button', { className: 'mcpm-btn', disabled: toolPreviewBusy, onClick: () => openToolPreview(row) }, '工具 (' + row.toolCount + ')'),
|
|
324
347
|
React.createElement('button', { className: 'mcpm-btn', disabled: rowsLocked, onClick: () => toggleRow(row) }, row.disabled ? '启用' : '禁用'),
|
|
325
348
|
React.createElement('button', { className: 'mcpm-btn', disabled: rowsLocked, onClick: () => restartRow(row) }, '重启'),
|
|
326
349
|
row.level !== 'loader' && React.createElement('button', { className: 'mcpm-btn danger', disabled: rowsLocked, onClick: () => removeRow(row) }, '删除')))),
|
|
@@ -331,7 +354,32 @@ const factory = (require) => {
|
|
|
331
354
|
'确定要删除“' + confirmRow.serverName + '”吗?\n删除后该服务的配置将从补丁文件中移除,相关工具立即下线,此操作不可撤销。'),
|
|
332
355
|
React.createElement('div', { className: 'mcpm-dialog-actions' },
|
|
333
356
|
React.createElement('button', { className: 'mcpm-btn', onClick: () => setConfirmRow(null) }, '取消'),
|
|
334
|
-
React.createElement('button', { className: 'mcpm-btn danger', onClick: confirmDelete }, '删除'))))
|
|
357
|
+
React.createElement('button', { className: 'mcpm-btn danger', onClick: confirmDelete }, '删除')))),
|
|
358
|
+
toolPreview && React.createElement('div', { className: 'mcpm-mask', onClick: () => setToolPreview(null) },
|
|
359
|
+
React.createElement('div', { className: 'mcpm-dialog mcpm-dialog-tools', onClick: (ev) => ev.stopPropagation() },
|
|
360
|
+
React.createElement('div', { className: 'mcpm-dialog-title' }, '工具预览:' + toolPreview.serverName + '(' + (toolPreviewBusy ? '加载中…' : (toolPreview.tools || []).length + ' 个工具') + ')'),
|
|
361
|
+
React.createElement('div', { className: 'mcpm-dialog-body' },
|
|
362
|
+
toolPreviewErr
|
|
363
|
+
? React.createElement('div', { className: 'mcpm-warn' }, '⚠ ' + toolPreviewErr)
|
|
364
|
+
: toolPreviewBusy
|
|
365
|
+
? React.createElement('div', { className: 'mcpm-sub' }, '正在获取工具列表…')
|
|
366
|
+
: (toolPreview.tools || []).length === 0
|
|
367
|
+
? React.createElement('div', { className: 'mcpm-sub' }, '该服务暂无已注册工具' + (toolPreview.emptyHint || ''))
|
|
368
|
+
: React.createElement('div', { className: 'mcpm-tools-list' },
|
|
369
|
+
(toolPreview.tools || []).map((t) =>
|
|
370
|
+
React.createElement('div', { className: 'mcpm-tool' },
|
|
371
|
+
React.createElement('div', { className: 'mcpm-tool-name' }, t.name),
|
|
372
|
+
React.createElement('div', { className: 'mcpm-sub' }, t.description || '(无描述)'),
|
|
373
|
+
(t.parameters && t.parameters.length > 0) &&
|
|
374
|
+
React.createElement('div', { className: 'mcpm-tool-params' },
|
|
375
|
+
t.parameters.map((p) =>
|
|
376
|
+
React.createElement('div', { className: 'mcpm-tool-param' },
|
|
377
|
+
React.createElement('span', { className: 'mcpm-tool-param-key' },
|
|
378
|
+
p.key + (p.required ? ' *' : '')),
|
|
379
|
+
React.createElement('span', { className: 'mcpm-tool-param-type' }, p.type || 'any'),
|
|
380
|
+
React.createElement('span', { className: 'mcpm-tool-param-desc' }, p.description || '')))))))),
|
|
381
|
+
React.createElement('div', { className: 'mcpm-dialog-actions' },
|
|
382
|
+
React.createElement('button', { className: 'mcpm-btn', onClick: () => setToolPreview(null) }, '关闭'))))
|
|
335
383
|
)
|
|
336
384
|
}
|
|
337
385
|
|
package/lib/index.js
CHANGED
|
@@ -844,6 +844,56 @@ export default {
|
|
|
844
844
|
async function pluginVersion() {
|
|
845
845
|
return { ok: true, version: PKG_VERSION };
|
|
846
846
|
}
|
|
847
|
+
// Tool preview for one MCP server: project the model-facing schemas down to
|
|
848
|
+
// a name + description + parameter-summary list. The registry prefixes every
|
|
849
|
+
// MCP tool with `mcp__<serverName>__`; we filter on that and strip the prefix
|
|
850
|
+
// for display. Only the direct `properties` of the parameters object are
|
|
851
|
+
// summarized — nested object/array children are omitted (one level is enough
|
|
852
|
+
// for a preview, keeps the dialog readable).
|
|
853
|
+
async function mcpmTools(args) {
|
|
854
|
+
const serverName = String(args && args.serverName || '').trim();
|
|
855
|
+
if (!serverName)
|
|
856
|
+
return { ok: false, error: 'serverName 不能为空' };
|
|
857
|
+
const prefix = 'mcp__' + serverName + '__';
|
|
858
|
+
let schemas = [];
|
|
859
|
+
try {
|
|
860
|
+
schemas = await tools.schemas();
|
|
861
|
+
}
|
|
862
|
+
catch (e) {
|
|
863
|
+
return { ok: false, error: message(e) };
|
|
864
|
+
}
|
|
865
|
+
const toolsList = [];
|
|
866
|
+
for (const s of schemas) {
|
|
867
|
+
const fullName = String(s && s.name || '');
|
|
868
|
+
if (!fullName.startsWith(prefix))
|
|
869
|
+
continue;
|
|
870
|
+
const params = [];
|
|
871
|
+
const props = s.parameters && typeof s.parameters === 'object' ? s.parameters.properties : null;
|
|
872
|
+
const requiredSet = new Set();
|
|
873
|
+
if (s.parameters && Array.isArray(s.parameters.required)) {
|
|
874
|
+
for (const k of s.parameters.required)
|
|
875
|
+
if (typeof k === 'string')
|
|
876
|
+
requiredSet.add(k);
|
|
877
|
+
}
|
|
878
|
+
if (props && typeof props === 'object') {
|
|
879
|
+
for (const [key, spec] of Object.entries(props)) {
|
|
880
|
+
const ps = (spec && typeof spec === 'object') ? spec : {};
|
|
881
|
+
params.push({
|
|
882
|
+
key,
|
|
883
|
+
required: requiredSet.has(key),
|
|
884
|
+
type: typeof ps.type === 'string' ? ps.type : 'any',
|
|
885
|
+
...(typeof ps.description === 'string' ? { description: ps.description } : {}),
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
toolsList.push({
|
|
890
|
+
name: fullName.slice(prefix.length),
|
|
891
|
+
description: typeof s.description === 'string' ? s.description : '',
|
|
892
|
+
parameters: params,
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
return { ok: true, tools: toolsList };
|
|
896
|
+
}
|
|
847
897
|
async function mcpmList() {
|
|
848
898
|
const p = await ensurePaths();
|
|
849
899
|
const rows = [];
|
|
@@ -1195,6 +1245,7 @@ export default {
|
|
|
1195
1245
|
const handlers = {
|
|
1196
1246
|
'plugin-version': pluginVersion,
|
|
1197
1247
|
'mcpm-list': mcpmList,
|
|
1248
|
+
'mcpm-tools': mcpmTools,
|
|
1198
1249
|
'mcpm-add': mcpmAdd,
|
|
1199
1250
|
'mcpm-edit': mcpmEdit,
|
|
1200
1251
|
'mcpm-set-enabled': mcpmSetEnabled,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xxxyz/dsh-mcp-manager",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.4",
|
|
4
4
|
"description": "DSH-standard MCP manager plugin: Settings UI + HTTP API + model-facing mcp_manager_* tools. Install with one command: dsh plugin --profile web add @xxxyz/dsh-mcp-manager@latest",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
package/show.png
CHANGED
|
Binary file
|