@railgun52/dsh-mcp-servers 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +64 -0
- package/README.zh.md +64 -0
- package/cordis.patch.yml +3 -0
- package/icon.svg +5 -0
- package/lib/client.js +357 -0
- package/lib/client.js.map +1 -0
- package/lib/index.js +150 -0
- package/lib/invariant.js +8 -0
- package/lib/types/client/McpSection.d.ts +9 -0
- package/lib/types/client/McpSection.d.ts.map +1 -0
- package/lib/types/client/McpSection.js +140 -0
- package/lib/types/client/McpSection.js.map +1 -0
- package/lib/types/client/index.d.ts +10 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/index.js +21 -0
- package/lib/types/client/index.js.map +1 -0
- package/lib/types/client/locales.d.ts +22 -0
- package/lib/types/client/locales.d.ts.map +1 -0
- package/lib/types/client/locales.js +35 -0
- package/lib/types/client/locales.js.map +1 -0
- package/lib/types/index.d.ts +59 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +36 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/invariant.d.ts +5 -0
- package/lib/types/invariant.d.ts.map +1 -0
- package/lib/types/invariant.js +6 -0
- package/lib/types/invariant.js.map +1 -0
- package/lib/types/mcp-bridge.d.ts +20 -0
- package/lib/types/mcp-bridge.d.ts.map +1 -0
- package/lib/types/mcp-bridge.js +100 -0
- package/lib/types/mcp-bridge.js.map +1 -0
- package/lib/types/mcp-servers-schema.d.ts +66 -0
- package/lib/types/mcp-servers-schema.d.ts.map +1 -0
- package/lib/types/mcp-servers-schema.js +22 -0
- package/lib/types/mcp-servers-schema.js.map +1 -0
- package/package.json +96 -0
- package/src/client/McpSection.module.css +143 -0
- package/src/client/McpSection.tsx +248 -0
- package/src/client/index.ts +38 -0
- package/src/client/locales.ts +35 -0
- package/src/css-modules.d.ts +4 -0
- package/src/index.ts +45 -0
- package/src/invariant.ts +8 -0
- package/src/mcp-bridge.ts +111 -0
- package/src/mcp-servers-schema.ts +45 -0
package/lib/index.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import z from "@deepseek-ai/schemastery";
|
|
2
|
+
import * as McpClient from "@deepseek-ai/dsh-mcp-client";
|
|
3
|
+
//#region lib/types/mcp-servers-schema.js
|
|
4
|
+
/** MCP servers settings schema (host + browser shared). */
|
|
5
|
+
/** Settings namespace owned by the MCP servers settings bridge. */
|
|
6
|
+
const MCP_SERVERS_NAMESPACE = "mcp-servers";
|
|
7
|
+
const McpServerSchema = z.object({
|
|
8
|
+
name: z.string().required(),
|
|
9
|
+
command: z.string(),
|
|
10
|
+
args: z.array(String).default([]),
|
|
11
|
+
env: z.dict(String).default({}),
|
|
12
|
+
transport: z.union(["stdio", "streamable-http"]).default("stdio"),
|
|
13
|
+
url: z.string().default(""),
|
|
14
|
+
enabled: z.boolean().default(true)
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Durable MCP servers schema. `servers` is volatile so the profile-config
|
|
18
|
+
* settings model exposes it as a live-editable field (the plugin is not
|
|
19
|
+
* remounted on edit; the bridge re-syncs on `loader/volatile-update`).
|
|
20
|
+
*/
|
|
21
|
+
const McpServersSchema = z.object({ servers: z.array(McpServerSchema).default([]).volatile() });
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region lib/types/mcp-bridge.js
|
|
24
|
+
/** Settings -> mcp-client bridge: live-mounts MCP servers from the settings document. */
|
|
25
|
+
/**
|
|
26
|
+
* Build one mcp-client config from a settings entry. The settings service
|
|
27
|
+
* deeply freezes published values, while Schemastery's config parse fills
|
|
28
|
+
* defaults into the args array and env dict, so both are cloned first.
|
|
29
|
+
* @param server - one entry of the mcp-servers settings value.
|
|
30
|
+
* @returns validated mcp-client config for that server.
|
|
31
|
+
*/
|
|
32
|
+
function toClientConfig(server) {
|
|
33
|
+
if (server.transport === "streamable-http") return McpClient.Config({
|
|
34
|
+
transport: "streamable-http",
|
|
35
|
+
serverName: server.name,
|
|
36
|
+
url: server.url,
|
|
37
|
+
headers: {},
|
|
38
|
+
failOnStartupError: false
|
|
39
|
+
});
|
|
40
|
+
return McpClient.Config({
|
|
41
|
+
transport: "stdio",
|
|
42
|
+
serverName: server.name,
|
|
43
|
+
command: server.command,
|
|
44
|
+
args: [...server.args],
|
|
45
|
+
env: { ...server.env },
|
|
46
|
+
cwd: "",
|
|
47
|
+
failOnStartupError: false
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Mount and keep live mcp-client instances in sync with the `mcp-servers` settings
|
|
52
|
+
* namespace. Creates, rebuilds, and disposes instances by `serverName` so editing the
|
|
53
|
+
* settings page takes effect without a restart. All sync work is serialized on one
|
|
54
|
+
* promise chain so concurrent settings writes cannot race the instance map.
|
|
55
|
+
* @param ctx - Host context carrying the tool registry required by mcp-client.
|
|
56
|
+
* @param getValue - accessor for the resolved settings value (called at sync time).
|
|
57
|
+
* @returns a sync trigger (call on settings change) and a dispose that drains the chain
|
|
58
|
+
* and tears down every live instance.
|
|
59
|
+
*/
|
|
60
|
+
function applyMcpBridge(ctx, getValue) {
|
|
61
|
+
const instances = /* @__PURE__ */ new Map();
|
|
62
|
+
let chain = Promise.resolve();
|
|
63
|
+
const syncOnce = async () => {
|
|
64
|
+
const servers = getValue()?.servers ?? [];
|
|
65
|
+
const next = /* @__PURE__ */ new Map();
|
|
66
|
+
for (const server of servers) {
|
|
67
|
+
if (!server.enabled) continue;
|
|
68
|
+
if (next.has(server.name)) continue;
|
|
69
|
+
next.set(server.name, server);
|
|
70
|
+
}
|
|
71
|
+
for (const [name, server] of next) {
|
|
72
|
+
const signature = JSON.stringify(server);
|
|
73
|
+
const existing = instances.get(name);
|
|
74
|
+
if (existing !== void 0 && existing.signature === signature) continue;
|
|
75
|
+
if (existing !== void 0) {
|
|
76
|
+
await existing.fiber.dispose();
|
|
77
|
+
instances.delete(name);
|
|
78
|
+
}
|
|
79
|
+
let config;
|
|
80
|
+
try {
|
|
81
|
+
config = toClientConfig(server);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
ctx.logger.warn("mcp-bridge: invalid server config for \"%s\": %s", name, String(error));
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const fiber = ctx.plugin(McpClient, config);
|
|
87
|
+
instances.set(name, {
|
|
88
|
+
fiber,
|
|
89
|
+
signature
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
for (const [name, { fiber }] of instances) if (!next.has(name)) {
|
|
93
|
+
await fiber.dispose();
|
|
94
|
+
instances.delete(name);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const sync = () => {
|
|
98
|
+
chain = chain.then(syncOnce).catch((error) => {
|
|
99
|
+
ctx.logger.warn("mcp-bridge: sync failed: %s", String(error));
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
const dispose = async () => {
|
|
103
|
+
chain = chain.finally(async () => {
|
|
104
|
+
for (const [, { fiber }] of instances) try {
|
|
105
|
+
await fiber.dispose();
|
|
106
|
+
} catch {}
|
|
107
|
+
instances.clear();
|
|
108
|
+
});
|
|
109
|
+
await chain;
|
|
110
|
+
};
|
|
111
|
+
sync();
|
|
112
|
+
return {
|
|
113
|
+
sync,
|
|
114
|
+
dispose
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region lib/types/index.js
|
|
119
|
+
/**
|
|
120
|
+
* Host registration: the `mcp-servers` settings namespace and the live
|
|
121
|
+
* mcp-client bridge it feeds. Under the profile-config settings model the
|
|
122
|
+
* plugin's Config schema IS the namespace, so the owning profile entry id must
|
|
123
|
+
* equal `mcp-servers`. `servers` is volatile, so edits reload the value without
|
|
124
|
+
* remounting this plugin; the bridge re-syncs on `loader/volatile-update`.
|
|
125
|
+
*/
|
|
126
|
+
/** Services required: the mcp-client instances this plugin mounts inject the tool registry. */
|
|
127
|
+
const inject = ["tools"];
|
|
128
|
+
/** Config schema; the owning profile entry's id must equal {@link MCP_SERVERS_NAMESPACE}. */
|
|
129
|
+
const Config = McpServersSchema;
|
|
130
|
+
/**
|
|
131
|
+
* Keep live mcp-client instances in sync with the resolved `mcp-servers`
|
|
132
|
+
* config, so the Settings page's MCP edits take effect without a restart.
|
|
133
|
+
* @param ctx - Host context whose tool registry the mounted mcp-client instances need.
|
|
134
|
+
* @param config - resolved `mcp-servers` section; `servers` is a live volatile reference.
|
|
135
|
+
*/
|
|
136
|
+
function apply(ctx, config) {
|
|
137
|
+
const bridge = applyMcpBridge(ctx, () => ({ servers: config.servers.get().map((server) => ({
|
|
138
|
+
...server,
|
|
139
|
+
args: [...server.args],
|
|
140
|
+
env: { ...server.env }
|
|
141
|
+
})) }));
|
|
142
|
+
ctx.on("loader/volatile-update", () => {
|
|
143
|
+
bridge.sync();
|
|
144
|
+
});
|
|
145
|
+
ctx.effect(() => () => {
|
|
146
|
+
bridge.dispose();
|
|
147
|
+
}, "mcp-servers: settings bridge");
|
|
148
|
+
}
|
|
149
|
+
//#endregion
|
|
150
|
+
export { Config, MCP_SERVERS_NAMESPACE, McpServersSchema, apply, inject };
|
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region lib/types/invariant.js
|
|
2
|
+
const PACKAGE_NAME = "@deepseek-ai/dsh-client-ui-settings-mcp";
|
|
3
|
+
const name = "client-ui-settings-mcp-invariant";
|
|
4
|
+
const inject = ["invariants"];
|
|
5
|
+
const install = () => {};
|
|
6
|
+
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
7
|
+
//#endregion
|
|
8
|
+
export { apply, inject, name };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { McpKey } from './locales.ts';
|
|
2
|
+
export interface McpSectionInjected {
|
|
3
|
+
load: () => unknown[];
|
|
4
|
+
save: (servers: unknown[]) => Promise<void>;
|
|
5
|
+
t: (key: McpKey) => string;
|
|
6
|
+
}
|
|
7
|
+
export type McpSectionProps = Partial<McpSectionInjected>;
|
|
8
|
+
export declare function McpSection({ load, save, t: t_ }: McpSectionProps): import("react").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=McpSection.d.ts.map
|
|
@@ -0,0 +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;AA8CzD,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,eAAe,+BAkLhE"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
3
|
+
import { Button, IconPlusOutlineRegular, IconTrashOutlineRegular, Modal } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
|
+
import styles from './McpSection.module.css';
|
|
5
|
+
function serversToJson(servers) {
|
|
6
|
+
const mcpServers = {};
|
|
7
|
+
for (const s of servers) {
|
|
8
|
+
const entry = { command: s.command };
|
|
9
|
+
if (s.args.length > 0)
|
|
10
|
+
entry.args = s.args;
|
|
11
|
+
if (Object.keys(s.env).length > 0)
|
|
12
|
+
entry.env = s.env;
|
|
13
|
+
if (s.transport === 'streamable-http')
|
|
14
|
+
entry.transport = 'streamable-http';
|
|
15
|
+
if (s.url)
|
|
16
|
+
entry.url = s.url;
|
|
17
|
+
mcpServers[s.name] = entry;
|
|
18
|
+
}
|
|
19
|
+
return JSON.stringify({ mcpServers }, null, 2);
|
|
20
|
+
}
|
|
21
|
+
function jsonToServers(text) {
|
|
22
|
+
const parsed = JSON.parse(text);
|
|
23
|
+
const map = parsed.mcpServers;
|
|
24
|
+
if (!map || typeof map !== 'object')
|
|
25
|
+
throw new Error('Missing "mcpServers" key');
|
|
26
|
+
return Object.entries(map).map(([name, config]) => {
|
|
27
|
+
const c = config;
|
|
28
|
+
const args = Array.isArray(c.args) ? c.args.map(String) : [];
|
|
29
|
+
const env = c.env && typeof c.env === 'object'
|
|
30
|
+
? Object.fromEntries(Object.entries(c.env).map(([k, v]) => [k, String(v)]))
|
|
31
|
+
: {};
|
|
32
|
+
return {
|
|
33
|
+
name,
|
|
34
|
+
command: String(c.command ?? ''),
|
|
35
|
+
args,
|
|
36
|
+
env,
|
|
37
|
+
transport: c.transport === 'streamable-http' ? 'streamable-http' : 'stdio',
|
|
38
|
+
url: String(c.url ?? ''),
|
|
39
|
+
enabled: c.enabled !== false,
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const EMPTY_TEMPLATE = JSON.stringify({
|
|
44
|
+
mcpServers: {
|
|
45
|
+
'my-server': {
|
|
46
|
+
command: 'npx',
|
|
47
|
+
args: ['-y', '@modelcontextprotocol/server-filesystem', '/path'],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
}, null, 2);
|
|
51
|
+
export function McpSection({ load, save, t: t_ }) {
|
|
52
|
+
const t = t_ ?? ((key) => key);
|
|
53
|
+
const [servers, setServers] = useState([]);
|
|
54
|
+
const [loading, setLoading] = useState(true);
|
|
55
|
+
const [saving, setSaving] = useState(false);
|
|
56
|
+
const [error, setError] = useState(null);
|
|
57
|
+
const [editJson, setEditJson] = useState('');
|
|
58
|
+
const [editIndex, setEditIndex] = useState(null);
|
|
59
|
+
const [showEditModal, setShowEditModal] = useState(false);
|
|
60
|
+
const [editError, setEditError] = useState(null);
|
|
61
|
+
const [deleteTarget, setDeleteTarget] = useState(null);
|
|
62
|
+
const loadConfig = useCallback(() => {
|
|
63
|
+
setLoading(true);
|
|
64
|
+
setError(null);
|
|
65
|
+
try {
|
|
66
|
+
const loaded = load?.() ?? [];
|
|
67
|
+
setServers(loaded);
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
setError(t('loadFailed'));
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
setLoading(false);
|
|
74
|
+
}
|
|
75
|
+
}, [load, t]);
|
|
76
|
+
useEffect(() => { loadConfig(); }, [loadConfig]);
|
|
77
|
+
const saveConfig = async (newServers) => {
|
|
78
|
+
setSaving(true);
|
|
79
|
+
setError(null);
|
|
80
|
+
try {
|
|
81
|
+
await save?.(newServers);
|
|
82
|
+
setServers(newServers);
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
setError(t('saveFailed'));
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
setSaving(false);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const handleAdd = () => {
|
|
92
|
+
setEditJson(EMPTY_TEMPLATE);
|
|
93
|
+
setEditIndex(null);
|
|
94
|
+
setEditError(null);
|
|
95
|
+
setShowEditModal(true);
|
|
96
|
+
};
|
|
97
|
+
const handleEdit = (index) => {
|
|
98
|
+
const server = servers[index];
|
|
99
|
+
if (!server)
|
|
100
|
+
return;
|
|
101
|
+
setEditJson(serversToJson([server]));
|
|
102
|
+
setEditIndex(index);
|
|
103
|
+
setEditError(null);
|
|
104
|
+
setShowEditModal(true);
|
|
105
|
+
};
|
|
106
|
+
const handleSaveJson = async () => {
|
|
107
|
+
try {
|
|
108
|
+
const parsed = jsonToServers(editJson);
|
|
109
|
+
if (parsed.length === 0) {
|
|
110
|
+
setEditError('No servers found in JSON');
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (editIndex !== null) {
|
|
114
|
+
const newServers = [...servers];
|
|
115
|
+
newServers[editIndex] = parsed[0];
|
|
116
|
+
await saveConfig(newServers);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
const merged = new Map(servers.map(s => [s.name, s]));
|
|
120
|
+
for (const s of parsed)
|
|
121
|
+
merged.set(s.name, s);
|
|
122
|
+
await saveConfig(Array.from(merged.values()).filter((s) => s !== undefined));
|
|
123
|
+
}
|
|
124
|
+
setShowEditModal(false);
|
|
125
|
+
}
|
|
126
|
+
catch (e) {
|
|
127
|
+
setEditError(e instanceof Error ? e.message : String(e));
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
const handleDelete = async (index) => {
|
|
131
|
+
const newServers = servers.filter((_, i) => i !== index);
|
|
132
|
+
await saveConfig(newServers);
|
|
133
|
+
setDeleteTarget(null);
|
|
134
|
+
};
|
|
135
|
+
if (loading) {
|
|
136
|
+
return _jsx("div", { className: styles.section, children: _jsx("div", { className: styles.loading, children: "Loading..." }) });
|
|
137
|
+
}
|
|
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(Button, { onClick: () => handleEdit(i), children: t('edit') }), _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
|
+
}
|
|
140
|
+
//# sourceMappingURL=McpSection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"McpSection.js","sourceRoot":"","sources":["../../../src/client/McpSection.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
2
|
+
import { type McpKey } from './locales.ts';
|
|
3
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
4
|
+
interface LocaleNamespaceMap {
|
|
5
|
+
'settings.mcp': McpKey;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export declare const inject: string[];
|
|
9
|
+
export declare function apply(ctx: ClientContext): void;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAOnE,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,cAAc,CAAA;AAElD,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,cAAc,EAAE,MAAM,CAAA;KACvB;CACF;AAQD,eAAO,MAAM,MAAM,UAAqC,CAAA;AAExD,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAc9C"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { McpSection } from "./McpSection.js";
|
|
2
|
+
import { en, zh } from "./locales.js";
|
|
3
|
+
const NS = 'settings.mcp';
|
|
4
|
+
const NAMESPACE = 'mcp-servers';
|
|
5
|
+
export const inject = ['slots', 'locale', 'configForms'];
|
|
6
|
+
export function apply(ctx) {
|
|
7
|
+
ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'ui-settings-mcp: copy dictionaries');
|
|
8
|
+
const form = ctx.configForms.get(NAMESPACE);
|
|
9
|
+
const t = ctx.locale.bind(NS);
|
|
10
|
+
const load = () => form.getSnapshot().value?.servers ?? [];
|
|
11
|
+
const save = async (servers) => { await form.set('servers', servers); };
|
|
12
|
+
ctx.effect(() => ctx.configForms.whileServed([NAMESPACE], () => ctx.slots.inject('settings.section', () => ctx.slots.register({
|
|
13
|
+
name: 'settings.section',
|
|
14
|
+
id: 'mcp',
|
|
15
|
+
order: 25,
|
|
16
|
+
label: () => t('nav'),
|
|
17
|
+
locale: NS,
|
|
18
|
+
inject: () => ({ load, save, t }),
|
|
19
|
+
}, McpSection))), 'ui-settings-mcp: page');
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAkB,CAAA;AAE7C,OAAO,EAAE,EAAE,EAAE,EAAE,EAAe,MAAM,cAAc,CAAA;AAOlD,MAAM,EAAE,GAAG,cAAc,CAAA;AACzB,MAAM,SAAS,GAAG,aAAa,CAAA;AAM/B,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAA;AAExD,MAAM,UAAU,KAAK,CAAC,GAAkB;IACtC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,oCAAoC,CAAC,CAAA;IAC3F,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAmB,SAAS,CAAC,CAAA;IAC7D,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAA4B,CAAA;IACxD,MAAM,IAAI,GAAG,GAAc,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,IAAI,EAAE,CAAA;IACrE,MAAM,IAAI,GAAG,KAAK,EAAE,OAAkB,EAAiB,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA,CAAC,CAAC,CAAA;IAChG,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;QAC5H,IAAI,EAAE,kBAAkB;QACxB,EAAE,EAAE,KAAK;QACT,KAAK,EAAE,EAAE;QACT,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QACrB,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,GAAuB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;KACtD,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAA;AAC5C,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const en: {
|
|
2
|
+
nav: string;
|
|
3
|
+
title: string;
|
|
4
|
+
intro: string;
|
|
5
|
+
add: string;
|
|
6
|
+
edit: string;
|
|
7
|
+
remove: string;
|
|
8
|
+
deleteConfirm: string;
|
|
9
|
+
deleteDescription: string;
|
|
10
|
+
save: string;
|
|
11
|
+
cancel: string;
|
|
12
|
+
close: string;
|
|
13
|
+
noServers: string;
|
|
14
|
+
loadFailed: string;
|
|
15
|
+
saveFailed: string;
|
|
16
|
+
saved: string;
|
|
17
|
+
};
|
|
18
|
+
export type McpKey = keyof typeof en;
|
|
19
|
+
export declare const zh: {
|
|
20
|
+
[Key in keyof typeof en]: string;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;CAgBd,CAAA;AACD,MAAM,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;AACpC,eAAO,MAAM,EAAE,EAAE;KAAG,GAAG,IAAI,MAAM,OAAO,EAAE,GAAG,MAAM;CAgBlD,CAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const en = {
|
|
2
|
+
nav: 'MCP Servers',
|
|
3
|
+
title: 'MCP Configuration',
|
|
4
|
+
intro: 'Manage your MCP servers by editing the JSON configuration below.',
|
|
5
|
+
add: 'Add server',
|
|
6
|
+
edit: 'Edit MCP config',
|
|
7
|
+
remove: 'Delete',
|
|
8
|
+
deleteConfirm: 'Delete {server}?',
|
|
9
|
+
deleteDescription: 'This will remove the MCP server configuration.',
|
|
10
|
+
save: 'Save',
|
|
11
|
+
cancel: 'Cancel',
|
|
12
|
+
close: 'Close',
|
|
13
|
+
noServers: 'No MCP servers configured. Click "Add server" to get started.',
|
|
14
|
+
loadFailed: 'Failed to load MCP configuration.',
|
|
15
|
+
saveFailed: 'Failed to save MCP configuration.',
|
|
16
|
+
saved: 'Configuration saved.',
|
|
17
|
+
};
|
|
18
|
+
export const zh = {
|
|
19
|
+
nav: 'MCP 服务器',
|
|
20
|
+
title: 'MCP 配置',
|
|
21
|
+
intro: '通过编辑下方的 JSON 配置来管理 MCP 服务器。',
|
|
22
|
+
add: '添加服务器',
|
|
23
|
+
edit: '编辑 MCP 配置',
|
|
24
|
+
remove: '删除',
|
|
25
|
+
deleteConfirm: '删除 {server}?',
|
|
26
|
+
deleteDescription: '这将移除 MCP 服务器配置。',
|
|
27
|
+
save: '保存',
|
|
28
|
+
cancel: '取消',
|
|
29
|
+
close: '关闭',
|
|
30
|
+
noServers: '还没有配置 MCP 服务器,点击"添加服务器"开始配置。',
|
|
31
|
+
loadFailed: '加载 MCP 配置失败。',
|
|
32
|
+
saveFailed: '保存 MCP 配置失败。',
|
|
33
|
+
saved: '配置已保存。',
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=locales.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host registration: the `mcp-servers` settings namespace and the live
|
|
3
|
+
* mcp-client bridge it feeds. Under the profile-config settings model the
|
|
4
|
+
* plugin's Config schema IS the namespace, so the owning profile entry id must
|
|
5
|
+
* equal `mcp-servers`. `servers` is volatile, so edits reload the value without
|
|
6
|
+
* remounting this plugin; the bridge re-syncs on `loader/volatile-update`.
|
|
7
|
+
*/
|
|
8
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
9
|
+
import type { McpServersHostConfig } from './mcp-servers-schema.ts';
|
|
10
|
+
export { MCP_SERVERS_NAMESPACE, McpServersSchema } from './mcp-servers-schema.ts';
|
|
11
|
+
export type { McpServerConfig, McpServersSettings } from './mcp-servers-schema.ts';
|
|
12
|
+
/** Services required: the mcp-client instances this plugin mounts inject the tool registry. */
|
|
13
|
+
export declare const inject: string[];
|
|
14
|
+
/** Config schema; the owning profile entry's id must equal {@link MCP_SERVERS_NAMESPACE}. */
|
|
15
|
+
export declare const Config: import("@deepseek-ai/schemastery").default<Schemastery.ObjectS<NoInfer<{
|
|
16
|
+
servers: import("@deepseek-ai/schemastery").default<NoInfer<({
|
|
17
|
+
name?: string | null;
|
|
18
|
+
command?: string | null;
|
|
19
|
+
args?: string[] | null;
|
|
20
|
+
env?: import("@deepseek-ai/cosmokit").Dict<string, string> | null;
|
|
21
|
+
transport?: "stdio" | "streamable-http" | null;
|
|
22
|
+
url?: string | null;
|
|
23
|
+
enabled?: boolean | null;
|
|
24
|
+
} & import("@deepseek-ai/cosmokit").Dict)[]>, NoInfer<Schemastery.ObjectT<NoInfer<{
|
|
25
|
+
name: import("@deepseek-ai/schemastery").default<string, string, "defined">;
|
|
26
|
+
command: import("@deepseek-ai/schemastery").default<string, string, "plain">;
|
|
27
|
+
args: import("@deepseek-ai/schemastery").default<string[], string[], "defined">;
|
|
28
|
+
env: import("@deepseek-ai/schemastery").default<import("@deepseek-ai/cosmokit").Dict<string, string>, import("@deepseek-ai/cosmokit").Dict<string, string>, "defined">;
|
|
29
|
+
transport: import("@deepseek-ai/schemastery").default<"stdio" | "streamable-http", "stdio" | "streamable-http", "defined">;
|
|
30
|
+
url: import("@deepseek-ai/schemastery").default<string, string, "defined">;
|
|
31
|
+
enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
|
|
32
|
+
}>>[]>, "volatile-defined">;
|
|
33
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
34
|
+
servers: import("@deepseek-ai/schemastery").default<NoInfer<({
|
|
35
|
+
name?: string | null;
|
|
36
|
+
command?: string | null;
|
|
37
|
+
args?: string[] | null;
|
|
38
|
+
env?: import("@deepseek-ai/cosmokit").Dict<string, string> | null;
|
|
39
|
+
transport?: "stdio" | "streamable-http" | null;
|
|
40
|
+
url?: string | null;
|
|
41
|
+
enabled?: boolean | null;
|
|
42
|
+
} & import("@deepseek-ai/cosmokit").Dict)[]>, NoInfer<Schemastery.ObjectT<NoInfer<{
|
|
43
|
+
name: import("@deepseek-ai/schemastery").default<string, string, "defined">;
|
|
44
|
+
command: import("@deepseek-ai/schemastery").default<string, string, "plain">;
|
|
45
|
+
args: import("@deepseek-ai/schemastery").default<string[], string[], "defined">;
|
|
46
|
+
env: import("@deepseek-ai/schemastery").default<import("@deepseek-ai/cosmokit").Dict<string, string>, import("@deepseek-ai/cosmokit").Dict<string, string>, "defined">;
|
|
47
|
+
transport: import("@deepseek-ai/schemastery").default<"stdio" | "streamable-http", "stdio" | "streamable-http", "defined">;
|
|
48
|
+
url: import("@deepseek-ai/schemastery").default<string, string, "defined">;
|
|
49
|
+
enabled: import("@deepseek-ai/schemastery").default<boolean, boolean, "defined">;
|
|
50
|
+
}>>[]>, "volatile-defined">;
|
|
51
|
+
}>>, "plain">;
|
|
52
|
+
/**
|
|
53
|
+
* Keep live mcp-client instances in sync with the resolved `mcp-servers`
|
|
54
|
+
* config, so the Settings page's MCP edits take effect without a restart.
|
|
55
|
+
* @param ctx - Host context whose tool registry the mounted mcp-client instances need.
|
|
56
|
+
* @param config - resolved `mcp-servers` section; `servers` is a live volatile reference.
|
|
57
|
+
*/
|
|
58
|
+
export declare function apply(ctx: Context, config: McpServersHostConfig): void;
|
|
59
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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,6FAA6F;AAC7F,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAAmB,CAAA;AAEtC;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,oBAAoB,GAAG,IAAI,CActE"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host registration: the `mcp-servers` settings namespace and the live
|
|
3
|
+
* mcp-client bridge it feeds. Under the profile-config settings model the
|
|
4
|
+
* plugin's Config schema IS the namespace, so the owning profile entry id must
|
|
5
|
+
* equal `mcp-servers`. `servers` is volatile, so edits reload the value without
|
|
6
|
+
* remounting this plugin; the bridge re-syncs on `loader/volatile-update`.
|
|
7
|
+
*/
|
|
8
|
+
import { McpServersSchema } from "./mcp-servers-schema.js";
|
|
9
|
+
import { applyMcpBridge } from "./mcp-bridge.js";
|
|
10
|
+
export { MCP_SERVERS_NAMESPACE, McpServersSchema } from "./mcp-servers-schema.js";
|
|
11
|
+
/** Services required: the mcp-client instances this plugin mounts inject the tool registry. */
|
|
12
|
+
export const inject = ['tools'];
|
|
13
|
+
/** Config schema; the owning profile entry's id must equal {@link MCP_SERVERS_NAMESPACE}. */
|
|
14
|
+
export const Config = McpServersSchema;
|
|
15
|
+
/**
|
|
16
|
+
* Keep live mcp-client instances in sync with the resolved `mcp-servers`
|
|
17
|
+
* config, so the Settings page's MCP edits take effect without a restart.
|
|
18
|
+
* @param ctx - Host context whose tool registry the mounted mcp-client instances need.
|
|
19
|
+
* @param config - resolved `mcp-servers` section; `servers` is a live volatile reference.
|
|
20
|
+
*/
|
|
21
|
+
export function apply(ctx, config) {
|
|
22
|
+
const bridge = applyMcpBridge(ctx, () => ({
|
|
23
|
+
servers: config.servers.get().map((server) => ({
|
|
24
|
+
...server,
|
|
25
|
+
args: [...server.args],
|
|
26
|
+
env: { ...server.env },
|
|
27
|
+
})),
|
|
28
|
+
}));
|
|
29
|
+
ctx.on('loader/volatile-update', () => {
|
|
30
|
+
bridge.sync();
|
|
31
|
+
});
|
|
32
|
+
ctx.effect(() => () => {
|
|
33
|
+
void bridge.dispose();
|
|
34
|
+
}, 'mcp-servers: settings bridge');
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAyB,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAEjF,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,6FAA6F;AAC7F,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,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC7C,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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invariant.d.ts","sourceRoot":"","sources":["../../src/invariant.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,eAAO,MAAM,IAAI,qCAAqC,CAAA;AACtD,eAAO,MAAM,MAAM,UAAiB,CAAA;AAEpC,eAAO,MAAM,KAAK,GAAI,KAAK,OAAO,KAAG,OAAO,CAAC,MAAM,IAAI,CACU,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-settings-mcp';
|
|
2
|
+
export const name = 'client-ui-settings-mcp-invariant';
|
|
3
|
+
export const inject = ['invariants'];
|
|
4
|
+
const install = () => { };
|
|
5
|
+
export const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
6
|
+
//# sourceMappingURL=invariant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invariant.js","sourceRoot":"","sources":["../../src/invariant.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAAG,yCAAyC,CAAA;AAC9D,MAAM,CAAC,MAAM,IAAI,GAAG,kCAAkC,CAAA;AACtD,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,YAAY,CAAC,CAAA;AACpC,MAAM,OAAO,GAAuB,GAAG,EAAE,GAAE,CAAC,CAAA;AAC5C,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,GAAY,EAAuB,EAAE,CACzD,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Settings -> mcp-client bridge: live-mounts MCP servers from the settings document. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { McpServerConfig } from './mcp-servers-schema.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Mount and keep live mcp-client instances in sync with the `mcp-servers` settings
|
|
6
|
+
* namespace. Creates, rebuilds, and disposes instances by `serverName` so editing the
|
|
7
|
+
* settings page takes effect without a restart. All sync work is serialized on one
|
|
8
|
+
* promise chain so concurrent settings writes cannot race the instance map.
|
|
9
|
+
* @param ctx - Host context carrying the tool registry required by mcp-client.
|
|
10
|
+
* @param getValue - accessor for the resolved settings value (called at sync time).
|
|
11
|
+
* @returns a sync trigger (call on settings change) and a dispose that drains the chain
|
|
12
|
+
* and tears down every live instance.
|
|
13
|
+
*/
|
|
14
|
+
export declare function applyMcpBridge(ctx: Context, getValue: () => {
|
|
15
|
+
servers: McpServerConfig[];
|
|
16
|
+
} | undefined): {
|
|
17
|
+
sync: () => void;
|
|
18
|
+
dispose: () => Promise<void>;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=mcp-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-bridge.d.ts","sourceRoot":"","sources":["../../src/mcp-bridge.ts"],"names":[],"mappings":"AAAA,yFAAyF;AAEzF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAqC9D;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,MAAM;IAAE,OAAO,EAAE,eAAe,EAAE,CAAA;CAAE,GAAG,SAAS,GACzD;IAAE,IAAI,EAAE,MAAM,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAwDpD"}
|