@xxxyz/dsh-mcp-manager 2.2.3 → 2.2.5

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 CHANGED
@@ -17,11 +17,12 @@
17
17
  [![GitHub](https://img.shields.io/badge/GitHub-xxxyz%2FDeepSeekHarness--MCP--Manager-181717?logo=github)](https://github.com/xxxyz/DeepSeekHarness-MCP-Manager)
18
18
  [![dsh.market](https://img.shields.io/badge/dsh.market-%E2%9C%93-3fb950)](https://dsh.market)
19
19
  [![awesome-dsh-plugin](https://img.shields.io/badge/awesome--dsh--plugin-%E5%B7%B2%E6%94%B6%E5%BD%95-3fb950)](https://awesome-dsh-plugin.com)
20
+ [![dsh-suite](https://img.shields.io/badge/featured%20on-dsh--suite-4d6bfe)](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> <a href="https://awesome-dsh-plugin.com"><b>awesome-dsh-plugin.com</b></a> 官方插件列表(<a href="https://github.com/awesome-dsh-plugin/awesome-dsh-plugin/pull/2078"><b>PR #2078</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
  [![GitHub](https://img.shields.io/badge/GitHub-xxxyz%2FDeepSeekHarness--MCP--Manager-181717?logo=github)](https://github.com/xxxyz/DeepSeekHarness-MCP-Manager)
19
19
  [![dsh.market](https://img.shields.io/badge/dsh.market-%E2%9C%93-3fb950)](https://dsh.market)
20
20
  [![awesome-dsh-plugin](https://img.shields.io/badge/awesome--dsh--plugin-listed-3fb950)](https://awesome-dsh-plugin.com)
21
+ [![dsh-suite](https://img.shields.io/badge/featured%20on-dsh--suite-4d6bfe)](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> and the <a href="https://awesome-dsh-plugin.com"><b>awesome-dsh-plugin.com</b></a> official plugin list (<a href="https://github.com/awesome-dsh-plugin/awesome-dsh-plugin/pull/2078"><b>PR #2078</b></a> merged)
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:transparent;display:flex;align-items:center;justify-content:center;z-index:99999}' +
47
- '.mcpm-dialog{background:color-mix(in srgb, currentColor 8%, transparent);backdrop-filter:blur(14px) saturate(1.2);border:1px solid 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}' +
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) => {
@@ -271,7 +293,8 @@ const factory = (require) => {
271
293
  React.createElement('div', { className: 'row' },
272
294
  React.createElement('span', { className: 'mcpm-sub' }, '备份 / 恢复'),
273
295
  React.createElement('button', { className: 'mcpm-btn', disabled: busy !== null, onClick: doExport }, '导出配置'),
274
- React.createElement('button', { className: 'mcpm-btn', disabled: busy !== null, onClick: () => { setBackup({ mode: 'import', added: [], skipped: [] }); setImportText('') } }, '导入配置')),
296
+ React.createElement('button', { className: 'mcpm-btn', disabled: busy !== null, onClick: () => { setBackup({ mode: 'import', added: [], skipped: [] }); setImportText('') } }, '导入配置'),
297
+ backup && React.createElement('button', { className: 'mcpm-btn', onClick: () => { setBackup(null); setImportText('') } }, '收起')),
275
298
  backup && backup.mode === 'export' && React.createElement('div', null,
276
299
  React.createElement('div', { className: 'mcpm-report' }, '已同时保存到: ' + (backup.savedTo || '(未落盘)')),
277
300
  React.createElement('textarea', { className: 'mcpm-json', readOnly: true, value: backup.json })),
@@ -297,7 +320,9 @@ const factory = (require) => {
297
320
  ? React.createElement('label', { className: 'full' }, '服务 URL', React.createElement('input', { value: form.url, onChange: setF('url'), placeholder: 'https://host/mcp' }))
298
321
  : React.createElement('label', { className: 'full' }, '启动命令', React.createElement('input', { value: form.command, onChange: setF('command'), placeholder: 'npx -y @modelcontextprotocol/server-github' })),
299
322
  form.transport === 'stdio' && React.createElement('label', { className: 'full' }, '参数(空格/换行分隔)', React.createElement('textarea', { value: form.args, onChange: setF('args'), placeholder: '-y\n@modelcontextprotocol/server-github' })),
300
- form.transport === 'stdio' && React.createElement('label', { className: 'full' }, '环境变量(每行 key=value)', React.createElement('textarea', { value: form.env, onChange: setF('env'), placeholder: 'GITHUB_TOKEN=xxx' })),
323
+ form.transport === 'stdio' && React.createElement('label', { className: 'full' }, '环境变量(每行 key=value)',
324
+ React.createElement('div', { className: 'mcpm-sub', style: { marginBottom: '3px' } }, '路径按系统路径写法填(Windows 用 \\,macOS/Linux 用 /)'),
325
+ React.createElement('textarea', { value: form.env, onChange: setF('env'), placeholder: 'GITHUB_TOKEN=xxx' })),
301
326
  form.transport === 'streamable-http' && React.createElement('label', { className: 'full' }, '请求头(每行 key=value)', React.createElement('textarea', { value: form.headers, onChange: setF('headers'), placeholder: 'Authorization=Bearer xxx' })),
302
327
  React.createElement('label', { className: 'full' }, ' ',
303
328
  React.createElement('div', { style: { display: 'flex', gap: '8px' } },
@@ -321,6 +346,7 @@ const factory = (require) => {
321
346
  (row.headers ? 'headers: ' + maskKv(row.headers) + ' ' : '') + (row.env ? 'env: ' + Object.keys(row.env).map((k) => k + ': ****').join(' ') : '')),
322
347
  React.createElement('div', { className: 'mcpm-row-actions' },
323
348
  row.level !== 'loader' && React.createElement('button', { className: 'mcpm-btn', disabled: rowsLocked, onClick: () => openEdit(row) }, '编辑'),
349
+ typeof row.toolCount === 'number' && row.toolCount > 0 && React.createElement('button', { className: 'mcpm-btn', disabled: toolPreviewBusy, onClick: () => openToolPreview(row) }, '工具 (' + row.toolCount + ')'),
324
350
  React.createElement('button', { className: 'mcpm-btn', disabled: rowsLocked, onClick: () => toggleRow(row) }, row.disabled ? '启用' : '禁用'),
325
351
  React.createElement('button', { className: 'mcpm-btn', disabled: rowsLocked, onClick: () => restartRow(row) }, '重启'),
326
352
  row.level !== 'loader' && React.createElement('button', { className: 'mcpm-btn danger', disabled: rowsLocked, onClick: () => removeRow(row) }, '删除')))),
@@ -331,7 +357,32 @@ const factory = (require) => {
331
357
  '确定要删除“' + confirmRow.serverName + '”吗?\n删除后该服务的配置将从补丁文件中移除,相关工具立即下线,此操作不可撤销。'),
332
358
  React.createElement('div', { className: 'mcpm-dialog-actions' },
333
359
  React.createElement('button', { className: 'mcpm-btn', onClick: () => setConfirmRow(null) }, '取消'),
334
- React.createElement('button', { className: 'mcpm-btn danger', onClick: confirmDelete }, '删除'))))
360
+ React.createElement('button', { className: 'mcpm-btn danger', onClick: confirmDelete }, '删除')))),
361
+ toolPreview && React.createElement('div', { className: 'mcpm-mask', onClick: () => setToolPreview(null) },
362
+ React.createElement('div', { className: 'mcpm-dialog mcpm-dialog-tools', onClick: (ev) => ev.stopPropagation() },
363
+ React.createElement('div', { className: 'mcpm-dialog-title' }, '工具预览:' + toolPreview.serverName + '(' + (toolPreviewBusy ? '加载中…' : (toolPreview.tools || []).length + ' 个工具') + ')'),
364
+ React.createElement('div', { className: 'mcpm-dialog-body' },
365
+ toolPreviewErr
366
+ ? React.createElement('div', { className: 'mcpm-warn' }, '⚠ ' + toolPreviewErr)
367
+ : toolPreviewBusy
368
+ ? React.createElement('div', { className: 'mcpm-sub' }, '正在获取工具列表…')
369
+ : (toolPreview.tools || []).length === 0
370
+ ? React.createElement('div', { className: 'mcpm-sub' }, '该服务暂无已注册工具' + (toolPreview.emptyHint || ''))
371
+ : React.createElement('div', { className: 'mcpm-tools-list' },
372
+ (toolPreview.tools || []).map((t) =>
373
+ React.createElement('div', { className: 'mcpm-tool' },
374
+ React.createElement('div', { className: 'mcpm-tool-name' }, t.name),
375
+ React.createElement('div', { className: 'mcpm-sub' }, t.description || '(无描述)'),
376
+ (t.parameters && t.parameters.length > 0) &&
377
+ React.createElement('div', { className: 'mcpm-tool-params' },
378
+ t.parameters.map((p) =>
379
+ React.createElement('div', { className: 'mcpm-tool-param' },
380
+ React.createElement('span', { className: 'mcpm-tool-param-key' },
381
+ p.key + (p.required ? ' *' : '')),
382
+ React.createElement('span', { className: 'mcpm-tool-param-type' }, p.type || 'any'),
383
+ React.createElement('span', { className: 'mcpm-tool-param-desc' }, p.description || '')))))))),
384
+ React.createElement('div', { className: 'mcpm-dialog-actions' },
385
+ React.createElement('button', { className: 'mcpm-btn', onClick: () => setToolPreview(null) }, '关闭'))))
335
386
  )
336
387
  }
337
388
 
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",
3
+ "version": "2.2.5",
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",