@railgun52/dsh-mcp-servers 0.1.0 → 0.1.2
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 +3 -1
- package/README.zh.md +3 -1
- package/lib/client.js +38 -11
- package/lib/client.js.map +1 -1
- package/lib/index.js +1 -1
- package/lib/types/client/McpSection.d.ts.map +1 -1
- package/lib/types/client/McpSection.js +8 -2
- package/lib/types/client/McpSection.js.map +1 -1
- package/lib/types/client/locales.d.ts +2 -0
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/locales.js +4 -0
- package/lib/types/client/locales.js.map +1 -1
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +2 -2
- package/lib/types/index.js.map +1 -1
- package/package.json +2 -2
- package/src/client/McpSection.module.css +18 -1
- package/src/client/McpSection.tsx +23 -2
- package/src/client/locales.ts +4 -0
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# dsh-mcp-servers — MCP servers settings page
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@railgun52/dsh-mcp-servers)
|
|
4
|
+
|
|
3
5
|
English | [中文](README.zh.md)
|
|
4
6
|
|
|
5
7
|
> A profile-config settings page for DeepSeek Harness that lets you manage MCP servers from the Web UI and mounts live `mcp-client` instances from the saved list.
|
|
@@ -43,7 +45,7 @@ dsh-mcp-servers/
|
|
|
43
45
|
### From a local directory (development)
|
|
44
46
|
dsh plugin --profile web add link:/absolute/path/to/dsh-mcp-servers
|
|
45
47
|
|
|
46
|
-
### From npm (
|
|
48
|
+
### From npm (recommended)
|
|
47
49
|
dsh plugin --profile web add @railgun52/dsh-mcp-servers@latest
|
|
48
50
|
```
|
|
49
51
|
|
package/README.zh.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# dsh-mcp-servers — MCP 服务器设置页
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@railgun52/dsh-mcp-servers)
|
|
4
|
+
|
|
3
5
|
[English](README.md) | 中文
|
|
4
6
|
|
|
5
7
|
> DeepSeek Harness 的 profile-config 设置页,在 Web UI 里管理 MCP 服务器,并把保存的服务器列表挂成实时运行的 `mcp-client` 实例。
|
|
@@ -43,7 +45,7 @@ dsh-mcp-servers/
|
|
|
43
45
|
### 从本地目录(开发)
|
|
44
46
|
dsh plugin --profile web add link:/absolute/path/to/dsh-mcp-servers
|
|
45
47
|
|
|
46
|
-
### 从 npm
|
|
48
|
+
### 从 npm(推荐)
|
|
47
49
|
dsh plugin --profile web add @railgun52/dsh-mcp-servers@latest
|
|
48
50
|
```
|
|
49
51
|
|
package/lib/client.js
CHANGED
|
@@ -8,7 +8,7 @@ window.__ModuleLoader__.load({
|
|
|
8
8
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
9
9
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
10
10
|
//#region \0dsh-css:G:\DSH2026\deepseek-harness-master\packages\client\ui-settings-mcp\src\client\McpSection.module.css.mjs
|
|
11
|
-
const css = ".gZZtfG_section{max-width:800px;padding:24px}.gZZtfG_header{margin-bottom:24px}.gZZtfG_title{margin:0 0 8px;font-size:20px;font-weight:600}.gZZtfG_intro{color:var(--text-secondary);margin:0;font-size:14px}.gZZtfG_toolbar{margin-bottom:16px}.gZZtfG_list{flex-direction:column;gap:8px;display:flex}.gZZtfG_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;justify-content:space-between;align-items:center;padding:12px 16px;transition:box-shadow .15s;display:flex}.gZZtfG_card:hover{box-shadow:0 1px 4px #0000000f}.gZZtfG_cardBody{flex:1;min-width:0}.gZZtfG_cardName{align-items:center;gap:8px;font-weight:500;display:flex}.gZZtfG_cardMeta{color:var(--text-secondary);text-overflow:ellipsis;white-space:nowrap;margin-top:4px;font-size:12px;overflow:hidden}.gZZtfG_cardMeta code{font-size:12px}.gZZtfG_cardActions{flex-shrink:0;align-items:center;gap:4px;display:flex}.gZZtfG_statusOn{background:#22c55e;border-radius:50%;width:8px;height:8px;display:inline-block}.gZZtfG_statusOff{background:#888;border-radius:50%;width:8px;height:8px;display:inline-block}.gZZtfG_deleteBtn{cursor:pointer;color:var(--text-secondary);background:0 0;border:none;border-radius:4px;align-items:center;padding:4px;display:flex}.gZZtfG_deleteBtn:hover{background:var(--bg-hover);color:var(--text-error)}.gZZtfG_empty{text-align:center;color:var(--text-secondary);padding:40px}.gZZtfG_error{background:var(--bg-error);color:var(--text-error);border-radius:6px;margin-bottom:16px;padding:8px 12px;font-size:13px}.gZZtfG_loading{text-align:center;color:var(--text-secondary);padding:40px}.gZZtfG_modalBody{padding:0}.gZZtfG_modalBody p{padding:0 16px}.gZZtfG_modalActions{justify-content:flex-end;gap:8px;padding:16px;display:flex}.gZZtfG_jsonEditor{resize:vertical;background:var(--bg-input);width:100%;color:var(--text-primary);box-sizing:border-box;border:none;outline:none;min-height:300px;padding:12px;font-family:monospace;font-size:13px;line-height:1.5}.gZZtfG_jsonEditor:focus{background:var(--bg-input-focus)}.gZZtfG_dialogMcp{width:min(720px,100%)}";
|
|
11
|
+
const css = ".gZZtfG_section{max-width:800px;padding:24px}.gZZtfG_header{margin-bottom:24px}.gZZtfG_title{margin:0 0 8px;font-size:20px;font-weight:600}.gZZtfG_intro{color:var(--text-secondary);margin:0;font-size:14px}.gZZtfG_toolbar{margin-bottom:16px}.gZZtfG_list{flex-direction:column;gap:8px;display:flex}.gZZtfG_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:10px;justify-content:space-between;align-items:center;padding:12px 16px;transition:box-shadow .15s;display:flex}.gZZtfG_card:hover{box-shadow:0 1px 4px #0000000f}.gZZtfG_cardBody{flex:1;min-width:0}.gZZtfG_cardName{align-items:center;gap:8px;font-weight:500;display:flex}.gZZtfG_cardMeta{color:var(--text-secondary);text-overflow:ellipsis;white-space:nowrap;margin-top:4px;font-size:12px;overflow:hidden}.gZZtfG_cardMeta code{font-size:12px}.gZZtfG_cardActions{flex-shrink:0;align-items:center;gap:8px;display:flex}.gZZtfG_enableSwitch{margin-right:4px}.gZZtfG_iconBtn{cursor:pointer;color:var(--text-secondary);background:0 0;border:none;border-radius:4px;align-items:center;padding:4px;display:flex}.gZZtfG_iconBtn:hover{background:var(--bg-hover);color:var(--text-primary)}.gZZtfG_statusOn{background:#22c55e;border-radius:50%;width:8px;height:8px;display:inline-block}.gZZtfG_statusOff{background:#888;border-radius:50%;width:8px;height:8px;display:inline-block}.gZZtfG_deleteBtn{cursor:pointer;color:var(--text-secondary);background:0 0;border:none;border-radius:4px;align-items:center;padding:4px;display:flex}.gZZtfG_deleteBtn:hover{background:var(--bg-hover);color:var(--text-error)}.gZZtfG_empty{text-align:center;color:var(--text-secondary);padding:40px}.gZZtfG_error{background:var(--bg-error);color:var(--text-error);border-radius:6px;margin-bottom:16px;padding:8px 12px;font-size:13px}.gZZtfG_loading{text-align:center;color:var(--text-secondary);padding:40px}.gZZtfG_modalBody{padding:0}.gZZtfG_modalBody p{padding:0 16px}.gZZtfG_modalActions{justify-content:flex-end;gap:8px;padding:16px;display:flex}.gZZtfG_jsonEditor{resize:vertical;background:var(--bg-input);width:100%;color:var(--text-primary);box-sizing:border-box;border:none;outline:none;min-height:300px;padding:12px;font-family:monospace;font-size:13px;line-height:1.5}.gZZtfG_jsonEditor:focus{background:var(--bg-input-focus)}.gZZtfG_dialogMcp{width:min(720px,100%)}";
|
|
12
12
|
const tagId = "@railgun52/dsh-mcp-servers/McpSection.module.css";
|
|
13
13
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
14
14
|
const tag = document.createElement("style");
|
|
@@ -26,8 +26,10 @@ window.__ModuleLoader__.load({
|
|
|
26
26
|
"deleteBtn": "gZZtfG_deleteBtn",
|
|
27
27
|
"dialogMcp": "gZZtfG_dialogMcp",
|
|
28
28
|
"empty": "gZZtfG_empty",
|
|
29
|
+
"enableSwitch": "gZZtfG_enableSwitch",
|
|
29
30
|
"error": "gZZtfG_error",
|
|
30
31
|
"header": "gZZtfG_header",
|
|
32
|
+
"iconBtn": "gZZtfG_iconBtn",
|
|
31
33
|
"intro": "gZZtfG_intro",
|
|
32
34
|
"jsonEditor": "gZZtfG_jsonEditor",
|
|
33
35
|
"list": "gZZtfG_list",
|
|
@@ -50,6 +52,7 @@ window.__ModuleLoader__.load({
|
|
|
50
52
|
if (Object.keys(s.env).length > 0) entry.env = s.env;
|
|
51
53
|
if (s.transport === "streamable-http") entry.transport = "streamable-http";
|
|
52
54
|
if (s.url) entry.url = s.url;
|
|
55
|
+
if (!s.enabled) entry.enabled = false;
|
|
53
56
|
mcpServers[s.name] = entry;
|
|
54
57
|
}
|
|
55
58
|
return JSON.stringify({ mcpServers }, null, 2);
|
|
@@ -152,6 +155,12 @@ window.__ModuleLoader__.load({
|
|
|
152
155
|
setEditError(e instanceof Error ? e.message : String(e));
|
|
153
156
|
}
|
|
154
157
|
};
|
|
158
|
+
const handleToggle = async (index, enabled) => {
|
|
159
|
+
await saveConfig(servers.map((s, i) => i === index ? {
|
|
160
|
+
...s,
|
|
161
|
+
enabled
|
|
162
|
+
} : s));
|
|
163
|
+
};
|
|
155
164
|
const handleDelete = async (index) => {
|
|
156
165
|
await saveConfig(servers.filter((_, i) => i !== index));
|
|
157
166
|
setDeleteTarget(null);
|
|
@@ -215,17 +224,31 @@ window.__ModuleLoader__.load({
|
|
|
215
224
|
})]
|
|
216
225
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
217
226
|
className: McpSection_module_css_default.cardActions,
|
|
218
|
-
children: [
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
227
|
+
children: [
|
|
228
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
229
|
+
checked: server.enabled,
|
|
230
|
+
onChange: (enabled) => handleToggle(i, enabled),
|
|
231
|
+
label: `${server.name} ${server.enabled ? t("enabled") : t("disabled")}`,
|
|
232
|
+
title: server.enabled ? t("enabled") : t("disabled"),
|
|
233
|
+
className: McpSection_module_css_default.enableSwitch,
|
|
234
|
+
disabled: saving
|
|
226
235
|
}),
|
|
227
|
-
|
|
228
|
-
|
|
236
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
237
|
+
className: McpSection_module_css_default.iconBtn,
|
|
238
|
+
title: t("edit"),
|
|
239
|
+
"aria-label": t("edit"),
|
|
240
|
+
onClick: () => handleEdit(i),
|
|
241
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutlineRegular, {})
|
|
242
|
+
}),
|
|
243
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
244
|
+
className: McpSection_module_css_default.deleteBtn,
|
|
245
|
+
onClick: () => setDeleteTarget({
|
|
246
|
+
name: server.name,
|
|
247
|
+
index: i
|
|
248
|
+
}),
|
|
249
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutlineRegular, {})
|
|
250
|
+
})
|
|
251
|
+
]
|
|
229
252
|
})]
|
|
230
253
|
}, i))
|
|
231
254
|
}),
|
|
@@ -286,6 +309,8 @@ window.__ModuleLoader__.load({
|
|
|
286
309
|
intro: "Manage your MCP servers by editing the JSON configuration below.",
|
|
287
310
|
add: "Add server",
|
|
288
311
|
edit: "Edit MCP config",
|
|
312
|
+
enabled: "Enabled",
|
|
313
|
+
disabled: "Disabled",
|
|
289
314
|
remove: "Delete",
|
|
290
315
|
deleteConfirm: "Delete {server}?",
|
|
291
316
|
deleteDescription: "This will remove the MCP server configuration.",
|
|
@@ -303,6 +328,8 @@ window.__ModuleLoader__.load({
|
|
|
303
328
|
intro: "通过编辑下方的 JSON 配置来管理 MCP 服务器。",
|
|
304
329
|
add: "添加服务器",
|
|
305
330
|
edit: "编辑 MCP 配置",
|
|
331
|
+
enabled: "已启用",
|
|
332
|
+
disabled: "已禁用",
|
|
306
333
|
remove: "删除",
|
|
307
334
|
deleteConfirm: "删除 {server}?",
|
|
308
335
|
deleteDescription: "这将移除 MCP 服务器配置。",
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["styles","Button","IconPlusOutlineRegular","IconTrashOutlineRegular","Modal"],"sources":["../../../packages/client/ui-settings-mcp/src/client/McpSection.tsx","../../../packages/client/ui-settings-mcp/src/client/locales.ts","../../../packages/client/ui-settings-mcp/src/client/index.ts"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react'\nimport { Button, IconPlusOutlineRegular, IconTrashOutlineRegular, Modal } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { McpKey } from './locales.ts'\nimport styles from './McpSection.module.css'\n\ninterface McpServer {\n name: string\n command: string\n args: string[]\n env: Record<string, string>\n transport: 'stdio' | 'streamable-http'\n url: string\n enabled: boolean\n}\n\nexport interface McpSectionInjected {\n load: () => unknown[]\n save: (servers: unknown[]) => Promise<void>\n t: (key: McpKey) => string\n}\n\nexport type McpSectionProps = Partial<McpSectionInjected>\n\nfunction serversToJson(servers: McpServer[]): string {\n const mcpServers: Record<string, Record<string, unknown>> = {}\n for (const s of servers) {\n const entry: Record<string, unknown> = { command: s.command }\n if (s.args.length > 0) entry.args = s.args\n if (Object.keys(s.env).length > 0) entry.env = s.env\n if (s.transport === 'streamable-http') entry.transport = 'streamable-http'\n if (s.url) entry.url = s.url\n mcpServers[s.name] = entry\n }\n return JSON.stringify({ mcpServers }, null, 2)\n}\n\nfunction jsonToServers(text: string): McpServer[] {\n const parsed = JSON.parse(text)\n const map = parsed.mcpServers\n if (!map || typeof map !== 'object') throw new Error('Missing \"mcpServers\" key')\n return Object.entries(map).map(([name, config]) => {\n const c = config as Record<string, unknown>\n const args = Array.isArray(c.args) ? c.args.map(String) : []\n const env = c.env && typeof c.env === 'object'\n ? Object.fromEntries(Object.entries(c.env).map(([k, v]) => [k, String(v)]))\n : {}\n return {\n name,\n command: String(c.command ?? ''),\n args,\n env,\n transport: c.transport === 'streamable-http' ? 'streamable-http' as const : 'stdio' as const,\n url: String(c.url ?? ''),\n enabled: c.enabled !== false,\n }\n })\n}\n\nconst EMPTY_TEMPLATE = JSON.stringify({\n mcpServers: {\n 'my-server': {\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', '/path'],\n },\n },\n}, null, 2)\n\nexport function McpSection({ load, save, t: t_ }: McpSectionProps) {\n const t = t_ ?? ((key: string) => key)\n const [servers, setServers] = useState<McpServer[]>([])\n const [loading, setLoading] = useState(true)\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [editJson, setEditJson] = useState('')\n const [editIndex, setEditIndex] = useState<number | null>(null)\n const [showEditModal, setShowEditModal] = useState(false)\n const [editError, setEditError] = useState<string | null>(null)\n const [deleteTarget, setDeleteTarget] = useState<{ name: string; index: number } | null>(null)\n\n const loadConfig = useCallback(() => {\n setLoading(true)\n setError(null)\n try {\n const loaded = load?.() ?? []\n setServers(loaded as McpServer[])\n } catch (e) {\n setError(t('loadFailed'))\n } finally {\n setLoading(false)\n }\n }, [load, t])\n\n useEffect(() => { loadConfig() }, [loadConfig])\n\n const saveConfig = async (newServers: McpServer[]) => {\n setSaving(true)\n setError(null)\n try {\n await save?.(newServers)\n setServers(newServers)\n } catch (e) {\n setError(t('saveFailed'))\n } finally {\n setSaving(false)\n }\n }\n\n const handleAdd = () => {\n setEditJson(EMPTY_TEMPLATE)\n setEditIndex(null)\n setEditError(null)\n setShowEditModal(true)\n }\n\n const handleEdit = (index: number) => {\n const server = servers[index]\n if (!server) return\n setEditJson(serversToJson([server]))\n setEditIndex(index)\n setEditError(null)\n setShowEditModal(true)\n }\n\n const handleSaveJson = async () => {\n try {\n const parsed = jsonToServers(editJson)\n if (parsed.length === 0) {\n setEditError('No servers found in JSON')\n return\n }\n if (editIndex !== null) {\n const newServers = [...servers]\n newServers[editIndex] = parsed[0]!\n await saveConfig(newServers)\n } else {\n const merged = new Map(servers.map(s => [s.name, s]))\n for (const s of parsed) merged.set(s.name, s)\n await saveConfig(Array.from(merged.values()).filter((s): s is McpServer => s !== undefined))\n }\n setShowEditModal(false)\n } catch (e) {\n setEditError(e instanceof Error ? e.message : String(e))\n }\n }\n\n const handleDelete = async (index: number) => {\n const newServers = servers.filter((_, i) => i !== index)\n await saveConfig(newServers)\n setDeleteTarget(null)\n }\n\n if (loading) {\n return <div className={styles.section}><div className={styles.loading}>Loading...</div></div>\n }\n\n return (\n <div className={styles.section}>\n <div className={styles.header}>\n <h2 className={styles.title}>{t('title')}</h2>\n <p className={styles.intro}>{t('intro')}</p>\n </div>\n\n {error && <div className={styles.error}>{error}</div>}\n\n <div className={styles.toolbar}>\n <Button onClick={handleAdd} disabled={saving}>\n <IconPlusOutlineRegular /> {t('add')}\n </Button>\n </div>\n\n {servers.length === 0 && (\n <div className={styles.empty}>{t('noServers')}</div>\n )}\n\n <div className={styles.list}>\n {servers.map((server, i) => (\n <div key={i} className={styles.card}>\n <div className={styles.cardBody}>\n <div className={styles.cardName}>\n <span className={server.enabled ? styles.statusOn : styles.statusOff} />\n {server.name}\n </div>\n <div className={styles.cardMeta}>\n <code>{server.command} {server.args.join(' ')}</code>\n </div>\n </div>\n <div className={styles.cardActions}>\n <Button onClick={() => handleEdit(i)}>{t('edit')}</Button>\n <button className={styles.deleteBtn} onClick={() => setDeleteTarget({ name: server.name, index: i })}>\n <IconTrashOutlineRegular />\n </button>\n </div>\n </div>\n ))}\n </div>\n\n {showEditModal && (\n <Modal\n open\n onClose={() => setShowEditModal(false)}\n title={editIndex !== null ? t('edit') : t('add')}\n closeLabel={t('close')}\n className={styles.dialogMcp ?? ''}\n footer={(\n <>\n <Button onClick={handleSaveJson} disabled={saving}>{t('save')}</Button>\n <Button onClick={() => setShowEditModal(false)}>{t('cancel')}</Button>\n </>\n )}\n >\n <div className={styles.modalBody}>\n {editError && <div className={styles.error}>{editError}</div>}\n <textarea\n className={styles.jsonEditor}\n value={editJson}\n onChange={e => setEditJson(e.target.value)}\n rows={16}\n spellCheck={false}\n />\n </div>\n </Modal>\n )}\n\n {deleteTarget && (\n <Modal\n open\n onClose={() => setDeleteTarget(null)}\n title={t('remove')}\n closeLabel={t('close')}\n className={styles.dialogMcp ?? ''}\n footer={(\n <>\n <Button onClick={() => handleDelete(deleteTarget.index)}>{t('remove')}</Button>\n <Button onClick={() => setDeleteTarget(null)}>{t('cancel')}</Button>\n </>\n )}\n >\n <div className={styles.modalBody}>\n <p>{t('deleteConfirm').replace('{server}', deleteTarget.name)}</p>\n <p>{t('deleteDescription')}</p>\n </div>\n </Modal>\n )}\n </div>\n )\n}\n\n\n","export const en = {\n nav: 'MCP Servers',\n title: 'MCP Configuration',\n intro: 'Manage your MCP servers by editing the JSON configuration below.',\n add: 'Add server',\n edit: 'Edit MCP config',\n remove: 'Delete',\n deleteConfirm: 'Delete {server}?',\n deleteDescription: 'This will remove the MCP server configuration.',\n save: 'Save',\n cancel: 'Cancel',\n close: 'Close',\n noServers: 'No MCP servers configured. Click \"Add server\" to get started.',\n loadFailed: 'Failed to load MCP configuration.',\n saveFailed: 'Failed to save MCP configuration.',\n saved: 'Configuration saved.',\n}\nexport type McpKey = keyof typeof en\nexport const zh: { [Key in keyof typeof en]: string } = {\n nav: 'MCP 服务器',\n title: 'MCP 配置',\n intro: '通过编辑下方的 JSON 配置来管理 MCP 服务器。',\n add: '添加服务器',\n edit: '编辑 MCP 配置',\n remove: '删除',\n deleteConfirm: '删除 {server}?',\n deleteDescription: '这将移除 MCP 服务器配置。',\n save: '保存',\n cancel: '取消',\n close: '关闭',\n noServers: '还没有配置 MCP 服务器,点击\"添加服务器\"开始配置。',\n loadFailed: '加载 MCP 配置失败。',\n saveFailed: '保存 MCP 配置失败。',\n saved: '配置已保存。',\n}\n","import type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport { McpSection } from './McpSection.tsx'\nimport type { McpSectionInjected } from './McpSection.tsx'\nimport { en, zh, type McpKey } from './locales.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'settings.mcp': McpKey\n }\n}\nconst NS = 'settings.mcp'\nconst NAMESPACE = 'mcp-servers'\n\ninterface McpServersConfig {\n servers: unknown[]\n}\n\nexport const inject = ['slots', 'locale', 'configForms']\n\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'ui-settings-mcp: copy dictionaries')\n const form = ctx.configForms.get<McpServersConfig>(NAMESPACE)\n const t = ctx.locale.bind(NS) as McpSectionInjected['t']\n const load = (): unknown[] => form.getSnapshot().value?.servers ?? []\n const save = async (servers: unknown[]): Promise<void> => { await form.set('servers', servers) }\n ctx.effect(() => ctx.configForms.whileServed([NAMESPACE], () => ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'mcp',\n order: 25,\n label: () => t('nav'),\n locale: NS,\n inject: (): McpSectionInjected => ({ load, save, t }),\n }, McpSection))), 'ui-settings-mcp: page')\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["styles","Button","IconPlusOutlineRegular","Switch","IconEditOutlineRegular","IconTrashOutlineRegular","Modal"],"sources":["../../../packages/client/ui-settings-mcp/src/client/McpSection.tsx","../../../packages/client/ui-settings-mcp/src/client/locales.ts","../../../packages/client/ui-settings-mcp/src/client/index.ts"],"sourcesContent":["import { useState, useEffect, useCallback } from 'react'\nimport { Button, IconEditOutlineRegular, IconPlusOutlineRegular, IconTrashOutlineRegular, Modal, Switch } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { McpKey } from './locales.ts'\nimport styles from './McpSection.module.css'\n\ninterface McpServer {\n name: string\n command: string\n args: string[]\n env: Record<string, string>\n transport: 'stdio' | 'streamable-http'\n url: string\n enabled: boolean\n}\n\nexport interface McpSectionInjected {\n load: () => unknown[]\n save: (servers: unknown[]) => Promise<void>\n t: (key: McpKey) => string\n}\n\nexport type McpSectionProps = Partial<McpSectionInjected>\n\nfunction serversToJson(servers: McpServer[]): string {\n const mcpServers: Record<string, Record<string, unknown>> = {}\n for (const s of servers) {\n const entry: Record<string, unknown> = { command: s.command }\n if (s.args.length > 0) entry.args = s.args\n if (Object.keys(s.env).length > 0) entry.env = s.env\n if (s.transport === 'streamable-http') entry.transport = 'streamable-http'\n if (s.url) entry.url = s.url\n if (!s.enabled) entry.enabled = false\n mcpServers[s.name] = entry\n }\n return JSON.stringify({ mcpServers }, null, 2)\n}\n\nfunction jsonToServers(text: string): McpServer[] {\n const parsed = JSON.parse(text)\n const map = parsed.mcpServers\n if (!map || typeof map !== 'object') throw new Error('Missing \"mcpServers\" key')\n return Object.entries(map).map(([name, config]) => {\n const c = config as Record<string, unknown>\n const args = Array.isArray(c.args) ? c.args.map(String) : []\n const env = c.env && typeof c.env === 'object'\n ? Object.fromEntries(Object.entries(c.env).map(([k, v]) => [k, String(v)]))\n : {}\n return {\n name,\n command: String(c.command ?? ''),\n args,\n env,\n transport: c.transport === 'streamable-http' ? 'streamable-http' as const : 'stdio' as const,\n url: String(c.url ?? ''),\n enabled: c.enabled !== false,\n }\n })\n}\n\nconst EMPTY_TEMPLATE = JSON.stringify({\n mcpServers: {\n 'my-server': {\n command: 'npx',\n args: ['-y', '@modelcontextprotocol/server-filesystem', '/path'],\n },\n },\n}, null, 2)\n\nexport function McpSection({ load, save, t: t_ }: McpSectionProps) {\n const t = t_ ?? ((key: string) => key)\n const [servers, setServers] = useState<McpServer[]>([])\n const [loading, setLoading] = useState(true)\n const [saving, setSaving] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [editJson, setEditJson] = useState('')\n const [editIndex, setEditIndex] = useState<number | null>(null)\n const [showEditModal, setShowEditModal] = useState(false)\n const [editError, setEditError] = useState<string | null>(null)\n const [deleteTarget, setDeleteTarget] = useState<{ name: string; index: number } | null>(null)\n\n const loadConfig = useCallback(() => {\n setLoading(true)\n setError(null)\n try {\n const loaded = load?.() ?? []\n setServers(loaded as McpServer[])\n } catch (e) {\n setError(t('loadFailed'))\n } finally {\n setLoading(false)\n }\n }, [load, t])\n\n useEffect(() => { loadConfig() }, [loadConfig])\n\n const saveConfig = async (newServers: McpServer[]) => {\n setSaving(true)\n setError(null)\n try {\n await save?.(newServers)\n setServers(newServers)\n } catch (e) {\n setError(t('saveFailed'))\n } finally {\n setSaving(false)\n }\n }\n\n const handleAdd = () => {\n setEditJson(EMPTY_TEMPLATE)\n setEditIndex(null)\n setEditError(null)\n setShowEditModal(true)\n }\n\n const handleEdit = (index: number) => {\n const server = servers[index]\n if (!server) return\n setEditJson(serversToJson([server]))\n setEditIndex(index)\n setEditError(null)\n setShowEditModal(true)\n }\n\n const handleSaveJson = async () => {\n try {\n const parsed = jsonToServers(editJson)\n if (parsed.length === 0) {\n setEditError('No servers found in JSON')\n return\n }\n if (editIndex !== null) {\n const newServers = [...servers]\n newServers[editIndex] = parsed[0]!\n await saveConfig(newServers)\n } else {\n const merged = new Map(servers.map(s => [s.name, s]))\n for (const s of parsed) merged.set(s.name, s)\n await saveConfig(Array.from(merged.values()).filter((s): s is McpServer => s !== undefined))\n }\n setShowEditModal(false)\n } catch (e) {\n setEditError(e instanceof Error ? e.message : String(e))\n }\n }\n\n const handleToggle = async (index: number, enabled: boolean) => {\n const newServers = servers.map((s, i) => (i === index ? { ...s, enabled } : s))\n await saveConfig(newServers)\n }\n\n const handleDelete = async (index: number) => {\n const newServers = servers.filter((_, i) => i !== index)\n await saveConfig(newServers)\n setDeleteTarget(null)\n }\n\n if (loading) {\n return <div className={styles.section}><div className={styles.loading}>Loading...</div></div>\n }\n\n return (\n <div className={styles.section}>\n <div className={styles.header}>\n <h2 className={styles.title}>{t('title')}</h2>\n <p className={styles.intro}>{t('intro')}</p>\n </div>\n\n {error && <div className={styles.error}>{error}</div>}\n\n <div className={styles.toolbar}>\n <Button onClick={handleAdd} disabled={saving}>\n <IconPlusOutlineRegular /> {t('add')}\n </Button>\n </div>\n\n {servers.length === 0 && (\n <div className={styles.empty}>{t('noServers')}</div>\n )}\n\n <div className={styles.list}>\n {servers.map((server, i) => (\n <div key={i} className={styles.card}>\n <div className={styles.cardBody}>\n <div className={styles.cardName}>\n <span className={server.enabled ? styles.statusOn : styles.statusOff} />\n {server.name}\n </div>\n <div className={styles.cardMeta}>\n <code>{server.command} {server.args.join(' ')}</code>\n </div>\n </div>\n <div className={styles.cardActions}>\n <Switch\n checked={server.enabled}\n onChange={enabled => handleToggle(i, enabled)}\n label={`${server.name} ${server.enabled ? t('enabled') : t('disabled')}`}\n title={server.enabled ? t('enabled') : t('disabled')}\n className={styles.enableSwitch}\n disabled={saving}\n />\n <button\n className={styles.iconBtn}\n title={t('edit')}\n aria-label={t('edit')}\n onClick={() => handleEdit(i)}\n >\n <IconEditOutlineRegular />\n </button>\n <button className={styles.deleteBtn} onClick={() => setDeleteTarget({ name: server.name, index: i })}>\n <IconTrashOutlineRegular />\n </button>\n </div>\n </div>\n ))}\n </div>\n\n {showEditModal && (\n <Modal\n open\n onClose={() => setShowEditModal(false)}\n title={editIndex !== null ? t('edit') : t('add')}\n closeLabel={t('close')}\n className={styles.dialogMcp ?? ''}\n footer={(\n <>\n <Button onClick={handleSaveJson} disabled={saving}>{t('save')}</Button>\n <Button onClick={() => setShowEditModal(false)}>{t('cancel')}</Button>\n </>\n )}\n >\n <div className={styles.modalBody}>\n {editError && <div className={styles.error}>{editError}</div>}\n <textarea\n className={styles.jsonEditor}\n value={editJson}\n onChange={e => setEditJson(e.target.value)}\n rows={16}\n spellCheck={false}\n />\n </div>\n </Modal>\n )}\n\n {deleteTarget && (\n <Modal\n open\n onClose={() => setDeleteTarget(null)}\n title={t('remove')}\n closeLabel={t('close')}\n className={styles.dialogMcp ?? ''}\n footer={(\n <>\n <Button onClick={() => handleDelete(deleteTarget.index)}>{t('remove')}</Button>\n <Button onClick={() => setDeleteTarget(null)}>{t('cancel')}</Button>\n </>\n )}\n >\n <div className={styles.modalBody}>\n <p>{t('deleteConfirm').replace('{server}', deleteTarget.name)}</p>\n <p>{t('deleteDescription')}</p>\n </div>\n </Modal>\n )}\n </div>\n )\n}\n\n\n","export const en = {\n nav: 'MCP Servers',\n title: 'MCP Configuration',\n intro: 'Manage your MCP servers by editing the JSON configuration below.',\n add: 'Add server',\n edit: 'Edit MCP config',\n enabled: 'Enabled',\n disabled: 'Disabled',\n remove: 'Delete',\n deleteConfirm: 'Delete {server}?',\n deleteDescription: 'This will remove the MCP server configuration.',\n save: 'Save',\n cancel: 'Cancel',\n close: 'Close',\n noServers: 'No MCP servers configured. Click \"Add server\" to get started.',\n loadFailed: 'Failed to load MCP configuration.',\n saveFailed: 'Failed to save MCP configuration.',\n saved: 'Configuration saved.',\n}\nexport type McpKey = keyof typeof en\nexport const zh: { [Key in keyof typeof en]: string } = {\n nav: 'MCP 服务器',\n title: 'MCP 配置',\n intro: '通过编辑下方的 JSON 配置来管理 MCP 服务器。',\n add: '添加服务器',\n edit: '编辑 MCP 配置',\n enabled: '已启用',\n disabled: '已禁用',\n remove: '删除',\n deleteConfirm: '删除 {server}?',\n deleteDescription: '这将移除 MCP 服务器配置。',\n save: '保存',\n cancel: '取消',\n close: '关闭',\n noServers: '还没有配置 MCP 服务器,点击\"添加服务器\"开始配置。',\n loadFailed: '加载 MCP 配置失败。',\n saveFailed: '保存 MCP 配置失败。',\n saved: '配置已保存。',\n}\n","import type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport { McpSection } from './McpSection.tsx'\nimport type { McpSectionInjected } from './McpSection.tsx'\nimport { en, zh, type McpKey } from './locales.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'settings.mcp': McpKey\n }\n}\nconst NS = 'settings.mcp'\nconst NAMESPACE = 'mcp-servers'\n\ninterface McpServersConfig {\n servers: unknown[]\n}\n\nexport const inject = ['slots', 'locale', 'configForms']\n\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'ui-settings-mcp: copy dictionaries')\n const form = ctx.configForms.get<McpServersConfig>(NAMESPACE)\n const t = ctx.locale.bind(NS) as McpSectionInjected['t']\n const load = (): unknown[] => form.getSnapshot().value?.servers ?? []\n const save = async (servers: unknown[]): Promise<void> => { await form.set('servers', servers) }\n ctx.effect(() => ctx.configForms.whileServed([NAMESPACE], () => ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'mcp',\n order: 25,\n label: () => t('nav'),\n locale: NS,\n inject: (): McpSectionInjected => ({ load, save, t }),\n }, McpSection))), 'ui-settings-mcp: page')\n}\n"],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -125,7 +125,7 @@ function applyMcpBridge(ctx, getValue) {
|
|
|
125
125
|
*/
|
|
126
126
|
/** Services required: the mcp-client instances this plugin mounts inject the tool registry. */
|
|
127
127
|
const inject = ["tools"];
|
|
128
|
-
/** Config schema; the owning profile entry's id must equal
|
|
128
|
+
/** Config schema; the owning profile entry's id must equal `mcp-servers`. */
|
|
129
129
|
const Config = McpServersSchema;
|
|
130
130
|
/**
|
|
131
131
|
* Keep live mcp-client instances in sync with the resolved `mcp-servers`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpSection.d.ts","sourceRoot":"","sources":["../../../src/client/McpSection.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAa1C,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,OAAO,EAAE,CAAA;IACrB,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3C,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;CAC3B;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"McpSection.d.ts","sourceRoot":"","sources":["../../../src/client/McpSection.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAa1C,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,OAAO,EAAE,CAAA;IACrB,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3C,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;CAC3B;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;AA+CzD,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,eAAe,+BAsMhE"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useEffect, useCallback } from 'react';
|
|
3
|
-
import { Button, IconPlusOutlineRegular, IconTrashOutlineRegular, Modal } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
3
|
+
import { Button, IconEditOutlineRegular, IconPlusOutlineRegular, IconTrashOutlineRegular, Modal, Switch } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
4
|
import styles from './McpSection.module.css';
|
|
5
5
|
function serversToJson(servers) {
|
|
6
6
|
const mcpServers = {};
|
|
@@ -14,6 +14,8 @@ function serversToJson(servers) {
|
|
|
14
14
|
entry.transport = 'streamable-http';
|
|
15
15
|
if (s.url)
|
|
16
16
|
entry.url = s.url;
|
|
17
|
+
if (!s.enabled)
|
|
18
|
+
entry.enabled = false;
|
|
17
19
|
mcpServers[s.name] = entry;
|
|
18
20
|
}
|
|
19
21
|
return JSON.stringify({ mcpServers }, null, 2);
|
|
@@ -127,6 +129,10 @@ export function McpSection({ load, save, t: t_ }) {
|
|
|
127
129
|
setEditError(e instanceof Error ? e.message : String(e));
|
|
128
130
|
}
|
|
129
131
|
};
|
|
132
|
+
const handleToggle = async (index, enabled) => {
|
|
133
|
+
const newServers = servers.map((s, i) => (i === index ? { ...s, enabled } : s));
|
|
134
|
+
await saveConfig(newServers);
|
|
135
|
+
};
|
|
130
136
|
const handleDelete = async (index) => {
|
|
131
137
|
const newServers = servers.filter((_, i) => i !== index);
|
|
132
138
|
await saveConfig(newServers);
|
|
@@ -135,6 +141,6 @@ export function McpSection({ load, save, t: t_ }) {
|
|
|
135
141
|
if (loading) {
|
|
136
142
|
return _jsx("div", { className: styles.section, children: _jsx("div", { className: styles.loading, children: "Loading..." }) });
|
|
137
143
|
}
|
|
138
|
-
return (_jsxs("div", { className: styles.section, children: [_jsxs("div", { className: styles.header, children: [_jsx("h2", { className: styles.title, children: t('title') }), _jsx("p", { className: styles.intro, children: t('intro') })] }), error && _jsx("div", { className: styles.error, children: error }), _jsx("div", { className: styles.toolbar, children: _jsxs(Button, { onClick: handleAdd, disabled: saving, children: [_jsx(IconPlusOutlineRegular, {}), " ", t('add')] }) }), servers.length === 0 && (_jsx("div", { className: styles.empty, children: t('noServers') })), _jsx("div", { className: styles.list, children: servers.map((server, i) => (_jsxs("div", { className: styles.card, children: [_jsxs("div", { className: styles.cardBody, children: [_jsxs("div", { className: styles.cardName, children: [_jsx("span", { className: server.enabled ? styles.statusOn : styles.statusOff }), server.name] }), _jsx("div", { className: styles.cardMeta, children: _jsxs("code", { children: [server.command, " ", server.args.join(' ')] }) })] }), _jsxs("div", { className: styles.cardActions, children: [_jsx(
|
|
144
|
+
return (_jsxs("div", { className: styles.section, children: [_jsxs("div", { className: styles.header, children: [_jsx("h2", { className: styles.title, children: t('title') }), _jsx("p", { className: styles.intro, children: t('intro') })] }), error && _jsx("div", { className: styles.error, children: error }), _jsx("div", { className: styles.toolbar, children: _jsxs(Button, { onClick: handleAdd, disabled: saving, children: [_jsx(IconPlusOutlineRegular, {}), " ", t('add')] }) }), servers.length === 0 && (_jsx("div", { className: styles.empty, children: t('noServers') })), _jsx("div", { className: styles.list, children: servers.map((server, i) => (_jsxs("div", { className: styles.card, children: [_jsxs("div", { className: styles.cardBody, children: [_jsxs("div", { className: styles.cardName, children: [_jsx("span", { className: server.enabled ? styles.statusOn : styles.statusOff }), server.name] }), _jsx("div", { className: styles.cardMeta, children: _jsxs("code", { children: [server.command, " ", server.args.join(' ')] }) })] }), _jsxs("div", { className: styles.cardActions, children: [_jsx(Switch, { checked: server.enabled, onChange: enabled => handleToggle(i, enabled), label: `${server.name} ${server.enabled ? t('enabled') : t('disabled')}`, title: server.enabled ? t('enabled') : t('disabled'), className: styles.enableSwitch, disabled: saving }), _jsx("button", { className: styles.iconBtn, title: t('edit'), "aria-label": t('edit'), onClick: () => handleEdit(i), children: _jsx(IconEditOutlineRegular, {}) }), _jsx("button", { className: styles.deleteBtn, onClick: () => setDeleteTarget({ name: server.name, index: i }), children: _jsx(IconTrashOutlineRegular, {}) })] })] }, i))) }), showEditModal && (_jsx(Modal, { open: true, onClose: () => setShowEditModal(false), title: editIndex !== null ? t('edit') : t('add'), closeLabel: t('close'), className: styles.dialogMcp ?? '', footer: (_jsxs(_Fragment, { children: [_jsx(Button, { onClick: handleSaveJson, disabled: saving, children: t('save') }), _jsx(Button, { onClick: () => setShowEditModal(false), children: t('cancel') })] })), children: _jsxs("div", { className: styles.modalBody, children: [editError && _jsx("div", { className: styles.error, children: editError }), _jsx("textarea", { className: styles.jsonEditor, value: editJson, onChange: e => setEditJson(e.target.value), rows: 16, spellCheck: false })] }) })), deleteTarget && (_jsx(Modal, { open: true, onClose: () => setDeleteTarget(null), title: t('remove'), closeLabel: t('close'), className: styles.dialogMcp ?? '', footer: (_jsxs(_Fragment, { children: [_jsx(Button, { onClick: () => handleDelete(deleteTarget.index), children: t('remove') }), _jsx(Button, { onClick: () => setDeleteTarget(null), children: t('cancel') })] })), children: _jsxs("div", { className: styles.modalBody, children: [_jsx("p", { children: t('deleteConfirm').replace('{server}', deleteTarget.name) }), _jsx("p", { children: t('deleteDescription') })] }) }))] }));
|
|
139
145
|
}
|
|
140
146
|
//# sourceMappingURL=McpSection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpSection.js","sourceRoot":"","sources":["../../../src/client/McpSection.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACxD,OAAO,EAAE,MAAM,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,uCAAuC,CAAA;
|
|
1
|
+
{"version":3,"file":"McpSection.js","sourceRoot":"","sources":["../../../src/client/McpSection.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;CAkBd,CAAA;AACD,MAAM,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;AACpC,eAAO,MAAM,EAAE,EAAE;KAAG,GAAG,IAAI,MAAM,OAAO,EAAE,GAAG,MAAM;CAkBlD,CAAA"}
|
|
@@ -4,6 +4,8 @@ export const en = {
|
|
|
4
4
|
intro: 'Manage your MCP servers by editing the JSON configuration below.',
|
|
5
5
|
add: 'Add server',
|
|
6
6
|
edit: 'Edit MCP config',
|
|
7
|
+
enabled: 'Enabled',
|
|
8
|
+
disabled: 'Disabled',
|
|
7
9
|
remove: 'Delete',
|
|
8
10
|
deleteConfirm: 'Delete {server}?',
|
|
9
11
|
deleteDescription: 'This will remove the MCP server configuration.',
|
|
@@ -21,6 +23,8 @@ export const zh = {
|
|
|
21
23
|
intro: '通过编辑下方的 JSON 配置来管理 MCP 服务器。',
|
|
22
24
|
add: '添加服务器',
|
|
23
25
|
edit: '编辑 MCP 配置',
|
|
26
|
+
enabled: '已启用',
|
|
27
|
+
disabled: '已禁用',
|
|
24
28
|
remove: '删除',
|
|
25
29
|
deleteConfirm: '删除 {server}?',
|
|
26
30
|
deleteDescription: '这将移除 MCP 服务器配置。',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locales.js","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,GAAG,EAAE,aAAa;IAClB,KAAK,EAAE,mBAAmB;IAC1B,KAAK,EAAE,kEAAkE;IACzE,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,iBAAiB;IACvB,MAAM,EAAE,QAAQ;IAChB,aAAa,EAAE,kBAAkB;IACjC,iBAAiB,EAAE,gDAAgD;IACnE,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,+DAA+D;IAC1E,UAAU,EAAE,mCAAmC;IAC/C,UAAU,EAAE,mCAAmC;IAC/C,KAAK,EAAE,sBAAsB;CAC9B,CAAA;AAED,MAAM,CAAC,MAAM,EAAE,GAAyC;IACtD,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,6BAA6B;IACpC,GAAG,EAAE,OAAO;IACZ,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,IAAI;IACZ,aAAa,EAAE,cAAc;IAC7B,iBAAiB,EAAE,iBAAiB;IACpC,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,SAAS,EAAE,8BAA8B;IACzC,UAAU,EAAE,cAAc;IAC1B,UAAU,EAAE,cAAc;IAC1B,KAAK,EAAE,QAAQ;CAChB,CAAA"}
|
|
1
|
+
{"version":3,"file":"locales.js","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,GAAG,EAAE,aAAa;IAClB,KAAK,EAAE,mBAAmB;IAC1B,KAAK,EAAE,kEAAkE;IACzE,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,iBAAiB;IACvB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;IAChB,aAAa,EAAE,kBAAkB;IACjC,iBAAiB,EAAE,gDAAgD;IACnE,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,+DAA+D;IAC1E,UAAU,EAAE,mCAAmC;IAC/C,UAAU,EAAE,mCAAmC;IAC/C,KAAK,EAAE,sBAAsB;CAC9B,CAAA;AAED,MAAM,CAAC,MAAM,EAAE,GAAyC;IACtD,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,6BAA6B;IACpC,GAAG,EAAE,OAAO;IACZ,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,KAAK;IACf,MAAM,EAAE,IAAI;IACZ,aAAa,EAAE,cAAc;IAC7B,iBAAiB,EAAE,iBAAiB;IACpC,IAAI,EAAE,IAAI;IACV,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,SAAS,EAAE,8BAA8B;IACzC,UAAU,EAAE,cAAc;IAC1B,UAAU,EAAE,cAAc;IAC1B,KAAK,EAAE,QAAQ;CAChB,CAAA"}
|
package/lib/types/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export { MCP_SERVERS_NAMESPACE, McpServersSchema } from './mcp-servers-schema.ts
|
|
|
11
11
|
export type { McpServerConfig, McpServersSettings } from './mcp-servers-schema.ts';
|
|
12
12
|
/** Services required: the mcp-client instances this plugin mounts inject the tool registry. */
|
|
13
13
|
export declare const inject: string[];
|
|
14
|
-
/** Config schema; the owning profile entry's id must equal
|
|
14
|
+
/** Config schema; the owning profile entry's id must equal `mcp-servers`. */
|
|
15
15
|
export declare const Config: import("@deepseek-ai/schemastery").default<Schemastery.ObjectS<NoInfer<{
|
|
16
16
|
servers: import("@deepseek-ai/schemastery").default<NoInfer<({
|
|
17
17
|
name?: string | null;
|
package/lib/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAIlD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAGnE,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AACjF,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAElF,+FAA+F;AAC/F,eAAO,MAAM,MAAM,UAAY,CAAA;AAE/B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAIlD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAGnE,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AACjF,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAElF,+FAA+F;AAC/F,eAAO,MAAM,MAAM,UAAY,CAAA;AAE/B,6EAA6E;AAC7E,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAAmB,CAAA;AAEtC;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,oBAAoB,GAAG,IAAI,CActE"}
|
package/lib/types/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import { applyMcpBridge } from "./mcp-bridge.js";
|
|
|
10
10
|
export { MCP_SERVERS_NAMESPACE, McpServersSchema } from "./mcp-servers-schema.js";
|
|
11
11
|
/** Services required: the mcp-client instances this plugin mounts inject the tool registry. */
|
|
12
12
|
export const inject = ['tools'];
|
|
13
|
-
/** Config schema; the owning profile entry's id must equal
|
|
13
|
+
/** Config schema; the owning profile entry's id must equal `mcp-servers`. */
|
|
14
14
|
export const Config = McpServersSchema;
|
|
15
15
|
/**
|
|
16
16
|
* Keep live mcp-client instances in sync with the resolved `mcp-servers`
|
|
@@ -20,7 +20,7 @@ export const Config = McpServersSchema;
|
|
|
20
20
|
*/
|
|
21
21
|
export function apply(ctx, config) {
|
|
22
22
|
const bridge = applyMcpBridge(ctx, () => ({
|
|
23
|
-
servers: config.servers.get().map(
|
|
23
|
+
servers: config.servers.get().map(server => ({
|
|
24
24
|
...server,
|
|
25
25
|
args: [...server.args],
|
|
26
26
|
env: { ...server.env },
|
package/lib/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAGjF,+FAA+F;AAC/F,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,CAAA;AAE/B,6EAA6E;AAC7E,MAAM,CAAC,MAAM,MAAM,GAAG,gBAAgB,CAAA;AAEtC;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CAAC,GAAY,EAAE,MAA4B;IAC9D,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QACxC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC3C,GAAG,MAAM;YACT,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;YACtB,GAAG,EAAE,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE;SACvB,CAAC,CAAC;KACJ,CAAC,CAAC,CAAA;IACH,GAAG,CAAC,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,IAAI,EAAE,CAAA;IACf,CAAC,CAAC,CAAA;IACF,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE;QACpB,KAAK,MAAM,CAAC,OAAO,EAAE,CAAA;IACvB,CAAC,EAAE,8BAA8B,CAAC,CAAA;AACpC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@railgun52/dsh-mcp-servers",
|
|
3
3
|
"description": "MCP servers settings page for the dsh web GUI: a JSON editor over a profile-config namespace that mounts live mcp-client instances from the saved servers",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
+
"@deepseek-ai/dsh-mcp-client": "0.2.0-rc.2",
|
|
65
66
|
"@deepseek-ai/schemastery": "^3.18.4"
|
|
66
67
|
},
|
|
67
68
|
"peerDependencies": {
|
|
@@ -78,7 +79,6 @@
|
|
|
78
79
|
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.7-rc.1",
|
|
79
80
|
"@deepseek-ai/dsh-client-ui-settings": "^0.1.7-rc.1",
|
|
80
81
|
"@deepseek-ai/dsh-client-ui-slots": "^0.1.7-rc.1",
|
|
81
|
-
"@deepseek-ai/dsh-mcp-client": "^0.1.7-rc.1",
|
|
82
82
|
"@deepseek-ai/dsh-settings": "^0.1.7-rc.1",
|
|
83
83
|
"@deepseek-ai/dsh-tools": "^0.1.7-rc.1",
|
|
84
84
|
"@types/react": "~18.3.1",
|
|
@@ -59,10 +59,27 @@
|
|
|
59
59
|
}
|
|
60
60
|
.cardActions {
|
|
61
61
|
display: flex;
|
|
62
|
-
gap:
|
|
62
|
+
gap: 8px;
|
|
63
63
|
align-items: center;
|
|
64
64
|
flex-shrink: 0;
|
|
65
65
|
}
|
|
66
|
+
.enableSwitch {
|
|
67
|
+
margin-right: 4px;
|
|
68
|
+
}
|
|
69
|
+
.iconBtn {
|
|
70
|
+
background: none;
|
|
71
|
+
border: none;
|
|
72
|
+
cursor: pointer;
|
|
73
|
+
padding: 4px;
|
|
74
|
+
border-radius: 4px;
|
|
75
|
+
color: var(--text-secondary);
|
|
76
|
+
display: flex;
|
|
77
|
+
align-items: center;
|
|
78
|
+
}
|
|
79
|
+
.iconBtn:hover {
|
|
80
|
+
background: var(--bg-hover);
|
|
81
|
+
color: var(--text-primary);
|
|
82
|
+
}
|
|
66
83
|
.statusOn {
|
|
67
84
|
width: 8px;
|
|
68
85
|
height: 8px;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState, useEffect, useCallback } from 'react'
|
|
2
|
-
import { Button, IconPlusOutlineRegular, IconTrashOutlineRegular, Modal } from '@deepseek-ai/dsh-client-ui-primitives'
|
|
2
|
+
import { Button, IconEditOutlineRegular, IconPlusOutlineRegular, IconTrashOutlineRegular, Modal, Switch } from '@deepseek-ai/dsh-client-ui-primitives'
|
|
3
3
|
import type { McpKey } from './locales.ts'
|
|
4
4
|
import styles from './McpSection.module.css'
|
|
5
5
|
|
|
@@ -29,6 +29,7 @@ function serversToJson(servers: McpServer[]): string {
|
|
|
29
29
|
if (Object.keys(s.env).length > 0) entry.env = s.env
|
|
30
30
|
if (s.transport === 'streamable-http') entry.transport = 'streamable-http'
|
|
31
31
|
if (s.url) entry.url = s.url
|
|
32
|
+
if (!s.enabled) entry.enabled = false
|
|
32
33
|
mcpServers[s.name] = entry
|
|
33
34
|
}
|
|
34
35
|
return JSON.stringify({ mcpServers }, null, 2)
|
|
@@ -143,6 +144,11 @@ export function McpSection({ load, save, t: t_ }: McpSectionProps) {
|
|
|
143
144
|
}
|
|
144
145
|
}
|
|
145
146
|
|
|
147
|
+
const handleToggle = async (index: number, enabled: boolean) => {
|
|
148
|
+
const newServers = servers.map((s, i) => (i === index ? { ...s, enabled } : s))
|
|
149
|
+
await saveConfig(newServers)
|
|
150
|
+
}
|
|
151
|
+
|
|
146
152
|
const handleDelete = async (index: number) => {
|
|
147
153
|
const newServers = servers.filter((_, i) => i !== index)
|
|
148
154
|
await saveConfig(newServers)
|
|
@@ -185,7 +191,22 @@ export function McpSection({ load, save, t: t_ }: McpSectionProps) {
|
|
|
185
191
|
</div>
|
|
186
192
|
</div>
|
|
187
193
|
<div className={styles.cardActions}>
|
|
188
|
-
<
|
|
194
|
+
<Switch
|
|
195
|
+
checked={server.enabled}
|
|
196
|
+
onChange={enabled => handleToggle(i, enabled)}
|
|
197
|
+
label={`${server.name} ${server.enabled ? t('enabled') : t('disabled')}`}
|
|
198
|
+
title={server.enabled ? t('enabled') : t('disabled')}
|
|
199
|
+
className={styles.enableSwitch}
|
|
200
|
+
disabled={saving}
|
|
201
|
+
/>
|
|
202
|
+
<button
|
|
203
|
+
className={styles.iconBtn}
|
|
204
|
+
title={t('edit')}
|
|
205
|
+
aria-label={t('edit')}
|
|
206
|
+
onClick={() => handleEdit(i)}
|
|
207
|
+
>
|
|
208
|
+
<IconEditOutlineRegular />
|
|
209
|
+
</button>
|
|
189
210
|
<button className={styles.deleteBtn} onClick={() => setDeleteTarget({ name: server.name, index: i })}>
|
|
190
211
|
<IconTrashOutlineRegular />
|
|
191
212
|
</button>
|
package/src/client/locales.ts
CHANGED
|
@@ -4,6 +4,8 @@ export const en = {
|
|
|
4
4
|
intro: 'Manage your MCP servers by editing the JSON configuration below.',
|
|
5
5
|
add: 'Add server',
|
|
6
6
|
edit: 'Edit MCP config',
|
|
7
|
+
enabled: 'Enabled',
|
|
8
|
+
disabled: 'Disabled',
|
|
7
9
|
remove: 'Delete',
|
|
8
10
|
deleteConfirm: 'Delete {server}?',
|
|
9
11
|
deleteDescription: 'This will remove the MCP server configuration.',
|
|
@@ -22,6 +24,8 @@ export const zh: { [Key in keyof typeof en]: string } = {
|
|
|
22
24
|
intro: '通过编辑下方的 JSON 配置来管理 MCP 服务器。',
|
|
23
25
|
add: '添加服务器',
|
|
24
26
|
edit: '编辑 MCP 配置',
|
|
27
|
+
enabled: '已启用',
|
|
28
|
+
disabled: '已禁用',
|
|
25
29
|
remove: '删除',
|
|
26
30
|
deleteConfirm: '删除 {server}?',
|
|
27
31
|
deleteDescription: '这将移除 MCP 服务器配置。',
|