@dsh-libing/mcp-manager 0.0.0-stage → 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/lib/servers.js ADDED
@@ -0,0 +1,270 @@
1
+ import { livePresetMounts } from '@deepseek-ai/dsh-agent-preset-registry';
2
+ import { isMap, isNode, isScalar, isSeq, Scalar, visit, YAMLMap } from 'yaml';
3
+ import { MCP, configSchema } from "./shared.js";
4
+ import { document, hash, ManagerError, rowsIn } from "./storage.js";
5
+ export function record(value) {
6
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
7
+ ? value
8
+ : {};
9
+ }
10
+ export function publicConfig(raw) {
11
+ const parsed = configSchema.safeParse({
12
+ serverName: raw.serverName,
13
+ transport: raw.transport,
14
+ command: raw.command ?? '',
15
+ args: raw.args ?? [],
16
+ cwd: raw.cwd ?? '',
17
+ url: raw.url ?? '',
18
+ secrets: [],
19
+ toolCallTimeoutMs: raw.toolCallTimeoutMs ?? 60000,
20
+ reconnect: record(raw.reconnect).enabled ?? true
21
+ });
22
+ // No non-credential expression or unsupported extension is silently rewritten.
23
+ const allowed = new Set([
24
+ 'serverName',
25
+ 'transport',
26
+ 'command',
27
+ 'args',
28
+ 'cwd',
29
+ 'url',
30
+ 'env',
31
+ 'headers',
32
+ 'toolCallTimeoutMs',
33
+ 'reconnect',
34
+ 'failOnStartupError',
35
+ 'maxInstructionBytes'
36
+ ]);
37
+ return parsed.success && Object.keys(raw).every((key) => allowed.has(key)) ? parsed.data : null;
38
+ }
39
+ export async function serverRecords(ctx, text) {
40
+ const managed = rowsIn(text), rows = managed.rows?.items ?? [], result = [];
41
+ for (const node of rows) {
42
+ if (!isMap(node) || node.get('name') !== MCP || typeof node.get('id') !== 'string')
43
+ throw new ManagerError('Unsupported managed entry', 409);
44
+ const raw = record(node.get('config', true)?.toJSON()), id = String(node.get('id'));
45
+ if (!/^libing-mcp-[a-f0-9-]+$/u.test(id))
46
+ throw new ManagerError('Unsupported managed identity', 409);
47
+ const keys = Object.keys(record(raw[raw.transport === 'stdio' ? 'env' : 'headers']));
48
+ const configNode = node.get('config', true);
49
+ let unsupported = false;
50
+ if (isMap(configNode))
51
+ for (const pair of configNode.items) {
52
+ if (isScalar(pair.key) && ['env', 'headers'].includes(String(pair.key.value)))
53
+ continue;
54
+ if (isNode(pair.value))
55
+ visit(pair.value, {
56
+ Scalar(_key, value) {
57
+ if (value.tag === 'tag:yaml.org,2002:js')
58
+ unsupported = true;
59
+ }
60
+ });
61
+ }
62
+ const config = unsupported ? null : publicConfig(raw);
63
+ result.push({
64
+ patchId: id,
65
+ raw,
66
+ item: {
67
+ id: hash(`profile\0${id}`),
68
+ serverName: typeof raw.serverName === 'string' ? raw.serverName : id,
69
+ scope: 'profile',
70
+ origin: 'managed',
71
+ transport: String(raw.transport ?? ''),
72
+ enabled: node.get('disabled') !== true,
73
+ phase: null,
74
+ toolCount: null,
75
+ editable: config !== null,
76
+ toggleable: false,
77
+ config,
78
+ credentialKeys: keys,
79
+ tested: null
80
+ }
81
+ });
82
+ }
83
+ const official = await ctx.pluginManager.listPlugins();
84
+ const trees = [
85
+ { scope: 'profile', entries: [...ctx.loader.entries()] },
86
+ ...livePresetMounts(ctx.root.fiber).map((mount) => ({
87
+ scope: `preset:${mount.presetId}`,
88
+ entries: [...mount.tree.entries()]
89
+ }))
90
+ ];
91
+ const seen = new Set();
92
+ for (const tree of trees)
93
+ for (const entry of tree.entries) {
94
+ if (entry.options.name !== MCP || seen.has(entry))
95
+ continue;
96
+ seen.add(entry);
97
+ const mount = livePresetMounts(ctx.root.fiber).find((m) => [...m.tree.entries()].includes(entry));
98
+ const isPreset = mount !== undefined;
99
+ const scope = mount ? `preset:${mount.presetId}:${mount.fiber.uid}` : 'profile';
100
+ const raw = record(entry.options.config), config = publicConfig(raw), manager = official.find((row) => row.entryId === entry.id);
101
+ const owned = !isPreset ? result.find((row) => row.patchId === entry.options.id) : undefined;
102
+ const tools = entry.fiber?.ctx.get('tools'), prefix = typeof raw.serverName === 'string' ? `mcp__${raw.serverName}__` : null;
103
+ const count = tools && prefix
104
+ ? tools
105
+ .schemas(isPreset
106
+ ? livePresetMounts(ctx.root.fiber).find((m) => [...m.tree.entries()].includes(entry))?.key
107
+ : undefined)
108
+ .filter((tool) => tool.name.startsWith(prefix)).length
109
+ : null;
110
+ const item = {
111
+ id: owned?.item.id ?? hash(`${scope}\0${entry.id}`),
112
+ serverName: typeof raw.serverName === 'string' ? raw.serverName : entry.id,
113
+ scope,
114
+ origin: owned ? 'managed' : isPreset ? 'preset' : 'profile',
115
+ transport: typeof raw.transport === 'string' ? raw.transport : 'unknown',
116
+ enabled: !entry.disabled,
117
+ phase: manager?.fiberPhase ??
118
+ (entry.fiber
119
+ ? (['pending', 'loading', 'active', 'failed', null, 'unloading'][entry.fiber.state] ??
120
+ null)
121
+ : null),
122
+ toolCount: count,
123
+ editable: !!owned &&
124
+ owned.item.editable &&
125
+ config !== null &&
126
+ JSON.stringify(config) === JSON.stringify(owned.item.config),
127
+ toggleable: manager?.patchId !== undefined,
128
+ config: owned &&
129
+ owned.item.editable &&
130
+ JSON.stringify(config) === JSON.stringify(owned.item.config)
131
+ ? config
132
+ : null,
133
+ credentialKeys: Object.keys(record(raw[raw.transport === 'stdio' ? 'env' : 'headers'])),
134
+ tested: null
135
+ };
136
+ if (owned) {
137
+ owned.entry = entry;
138
+ owned.item = item;
139
+ owned.raw = raw;
140
+ }
141
+ else
142
+ result.push({ item, entry, raw, ...(mount?.key ? { scopeKey: mount.key } : {}) });
143
+ }
144
+ return result;
145
+ }
146
+ /** Keep secret nodes by default. Only constrained generated references use !!js. */
147
+ export function writeConfig(node, path, config) {
148
+ const old = node.getIn(path, true), previous = isMap(old) ? old : undefined;
149
+ const secrets = previous?.get(config.transport === 'stdio' ? 'env' : 'headers', true);
150
+ const next = new YAMLMap();
151
+ for (const [key, value] of Object.entries({
152
+ transport: config.transport,
153
+ serverName: config.serverName,
154
+ ...(config.transport === 'stdio'
155
+ ? { command: config.command, args: config.args, cwd: config.cwd }
156
+ : { url: config.url }),
157
+ toolCallTimeoutMs: config.toolCallTimeoutMs,
158
+ reconnect: { enabled: config.reconnect }
159
+ }))
160
+ next.set(key, node.createNode(value));
161
+ // Preserve official options not owned by the form, including reconnect tuning.
162
+ for (const key of ['failOnStartupError', 'maxInstructionBytes'])
163
+ if (previous?.has(key))
164
+ next.set(key, previous.get(key, true));
165
+ const reconnect = previous?.get('reconnect', true);
166
+ if (isMap(reconnect)) {
167
+ next.set('reconnect', reconnect);
168
+ reconnect.set('enabled', config.reconnect);
169
+ }
170
+ const credentials = new YAMLMap();
171
+ if (isMap(secrets))
172
+ for (const pair of secrets.items) {
173
+ if (isScalar(pair.key) && typeof pair.key.value === 'string')
174
+ credentials.set(pair.key.value, pair.value);
175
+ }
176
+ for (const secret of config.secrets) {
177
+ if (secret.action === 'keep') {
178
+ if (!credentials.has(secret.key))
179
+ throw new ManagerError('Credential no longer exists', 409);
180
+ }
181
+ else if (secret.action === 'remove')
182
+ credentials.delete(secret.key);
183
+ else if (secret.action === 'value')
184
+ credentials.set(secret.key, secret.value);
185
+ else {
186
+ const expression = new Scalar(`process.env[${JSON.stringify(secret.value)}] ?? ''`);
187
+ expression.tag = 'tag:yaml.org,2002:js';
188
+ credentials.set(secret.key, expression);
189
+ }
190
+ }
191
+ next.set(config.transport === 'stdio' ? 'env' : 'headers', credentials);
192
+ node.setIn(path, next);
193
+ }
194
+ /** Resolve only literal values or the exact ENV expression this editor emits. */
195
+ export function resolvedConfig(raw) {
196
+ const config = publicConfig(raw);
197
+ if (!config)
198
+ throw new ManagerError('This configuration cannot be tested safely; use its source', 409);
199
+ const credentials = Object.create(null);
200
+ for (const [key, value] of Object.entries(record(raw[config.transport === 'stdio' ? 'env' : 'headers']))) {
201
+ const expression = record(value).__jsExpr;
202
+ if (typeof value === 'string')
203
+ credentials[key] = value;
204
+ else if (typeof expression === 'string') {
205
+ const match = /^process\.env\["([A-Za-z_][A-Za-z0-9_]{0,127})"\] \?\? ''$/u.exec(expression);
206
+ const variable = match?.[1];
207
+ if (!variable)
208
+ throw new ManagerError('Unsupported credential expression; test from its source', 409);
209
+ credentials[key] = process.env[variable] ?? '';
210
+ }
211
+ else
212
+ throw new ManagerError('Unsupported credential configuration', 409);
213
+ }
214
+ return { ...config, credentials };
215
+ }
216
+ export function rawManaged(text, id) {
217
+ const { doc, rows } = rowsIn(text), index = rows?.items.findIndex((item) => isMap(item) && item.get('id') === id) ?? -1;
218
+ if (index < 0)
219
+ throw new ManagerError('MCP entry no longer exists', 404);
220
+ // Convert tags to inert expressions rather than evaluating foreign code.
221
+ const raw = document(String(doc));
222
+ const config = raw.getIn([0, 'insert', index, 'config'], true);
223
+ if (!isMap(config))
224
+ throw new ManagerError('Missing MCP configuration', 409);
225
+ let unsupported = false;
226
+ const initial = record(config.toJSON()), field = initial.transport === 'stdio' ? 'env' : 'headers';
227
+ for (const pair of config.items) {
228
+ if (isScalar(pair.key) && String(pair.key.value) === field)
229
+ continue;
230
+ if (isNode(pair.value))
231
+ visit(pair.value, {
232
+ Scalar(_key, value) {
233
+ if (value.tag === 'tag:yaml.org,2002:js')
234
+ unsupported = true;
235
+ }
236
+ });
237
+ }
238
+ if (unsupported)
239
+ throw new ManagerError('Unsupported configuration expression; use its source', 409);
240
+ const value = initial, keys = config.get(field, true);
241
+ if (isMap(keys)) {
242
+ const creds = {};
243
+ for (const pair of keys.items) {
244
+ if (isScalar(pair.key) && typeof pair.key.value === 'string') {
245
+ const node = pair.value;
246
+ creds[pair.key.value] =
247
+ isScalar(node) && node.tag === 'tag:yaml.org,2002:js'
248
+ ? { __jsExpr: node.value }
249
+ : isScalar(node)
250
+ ? node.value
251
+ : undefined;
252
+ }
253
+ }
254
+ value[field] = creds;
255
+ }
256
+ return value;
257
+ }
258
+ export function appendRow(text, id, config) {
259
+ const { doc, rows } = rowsIn(text);
260
+ if (!rows) {
261
+ doc.contents = doc.createNode([{ insert: [] }]);
262
+ }
263
+ const insert = doc.getIn([0, 'insert'], true);
264
+ if (!isSeq(insert))
265
+ throw new ManagerError('Invalid managed entries', 409);
266
+ const index = insert.items.length;
267
+ insert.add(doc.createNode({ id, name: MCP, disabled: true, config: {} }));
268
+ writeConfig(doc, [0, 'insert', index, 'config'], config);
269
+ return String(doc);
270
+ }
@@ -0,0 +1,314 @@
1
+ /** Authenticated protocol. Paths and raw config are never browser identities. */
2
+ import { z } from 'zod';
3
+ export declare const API = "/api/libing-mcp-manager";
4
+ export declare const MCP = "@deepseek-ai/dsh-mcp-client";
5
+ export declare const selectionSchema: z.ZodObject<{
6
+ workspaceId: z.ZodOptional<z.ZodString>;
7
+ sessionId: z.ZodOptional<z.ZodString>;
8
+ }, z.core.$strict>;
9
+ export type Selection = z.infer<typeof selectionSchema>;
10
+ export declare const secretSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
11
+ key: z.ZodString;
12
+ action: z.ZodLiteral<"keep">;
13
+ }, z.core.$strict>, z.ZodObject<{
14
+ key: z.ZodString;
15
+ action: z.ZodLiteral<"remove">;
16
+ }, z.core.$strict>, z.ZodObject<{
17
+ key: z.ZodString;
18
+ action: z.ZodLiteral<"value">;
19
+ value: z.ZodString;
20
+ }, z.core.$strict>, z.ZodObject<{
21
+ key: z.ZodString;
22
+ action: z.ZodLiteral<"env">;
23
+ value: z.ZodString;
24
+ }, z.core.$strict>], "action">;
25
+ export declare const configSchema: z.ZodObject<{
26
+ serverName: z.ZodString;
27
+ transport: z.ZodEnum<{
28
+ stdio: "stdio";
29
+ "streamable-http": "streamable-http";
30
+ }>;
31
+ command: z.ZodDefault<z.ZodString>;
32
+ args: z.ZodDefault<z.ZodArray<z.ZodString>>;
33
+ cwd: z.ZodDefault<z.ZodString>;
34
+ url: z.ZodDefault<z.ZodString>;
35
+ secrets: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
36
+ key: z.ZodString;
37
+ action: z.ZodLiteral<"keep">;
38
+ }, z.core.$strict>, z.ZodObject<{
39
+ key: z.ZodString;
40
+ action: z.ZodLiteral<"remove">;
41
+ }, z.core.$strict>, z.ZodObject<{
42
+ key: z.ZodString;
43
+ action: z.ZodLiteral<"value">;
44
+ value: z.ZodString;
45
+ }, z.core.$strict>, z.ZodObject<{
46
+ key: z.ZodString;
47
+ action: z.ZodLiteral<"env">;
48
+ value: z.ZodString;
49
+ }, z.core.$strict>], "action">>>;
50
+ toolCallTimeoutMs: z.ZodDefault<z.ZodNumber>;
51
+ reconnect: z.ZodDefault<z.ZodBoolean>;
52
+ }, z.core.$strict>;
53
+ export type ServerConfig = z.infer<typeof configSchema>;
54
+ export declare const mutationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
55
+ kind: z.ZodLiteral<"create">;
56
+ revision: z.ZodString;
57
+ config: z.ZodObject<{
58
+ serverName: z.ZodString;
59
+ transport: z.ZodEnum<{
60
+ stdio: "stdio";
61
+ "streamable-http": "streamable-http";
62
+ }>;
63
+ command: z.ZodDefault<z.ZodString>;
64
+ args: z.ZodDefault<z.ZodArray<z.ZodString>>;
65
+ cwd: z.ZodDefault<z.ZodString>;
66
+ url: z.ZodDefault<z.ZodString>;
67
+ secrets: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
68
+ key: z.ZodString;
69
+ action: z.ZodLiteral<"keep">;
70
+ }, z.core.$strict>, z.ZodObject<{
71
+ key: z.ZodString;
72
+ action: z.ZodLiteral<"remove">;
73
+ }, z.core.$strict>, z.ZodObject<{
74
+ key: z.ZodString;
75
+ action: z.ZodLiteral<"value">;
76
+ value: z.ZodString;
77
+ }, z.core.$strict>, z.ZodObject<{
78
+ key: z.ZodString;
79
+ action: z.ZodLiteral<"env">;
80
+ value: z.ZodString;
81
+ }, z.core.$strict>], "action">>>;
82
+ toolCallTimeoutMs: z.ZodDefault<z.ZodNumber>;
83
+ reconnect: z.ZodDefault<z.ZodBoolean>;
84
+ }, z.core.$strict>;
85
+ }, z.core.$strict>, z.ZodObject<{
86
+ kind: z.ZodLiteral<"update">;
87
+ id: z.ZodString;
88
+ revision: z.ZodString;
89
+ config: z.ZodObject<{
90
+ serverName: z.ZodString;
91
+ transport: z.ZodEnum<{
92
+ stdio: "stdio";
93
+ "streamable-http": "streamable-http";
94
+ }>;
95
+ command: z.ZodDefault<z.ZodString>;
96
+ args: z.ZodDefault<z.ZodArray<z.ZodString>>;
97
+ cwd: z.ZodDefault<z.ZodString>;
98
+ url: z.ZodDefault<z.ZodString>;
99
+ secrets: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
100
+ key: z.ZodString;
101
+ action: z.ZodLiteral<"keep">;
102
+ }, z.core.$strict>, z.ZodObject<{
103
+ key: z.ZodString;
104
+ action: z.ZodLiteral<"remove">;
105
+ }, z.core.$strict>, z.ZodObject<{
106
+ key: z.ZodString;
107
+ action: z.ZodLiteral<"value">;
108
+ value: z.ZodString;
109
+ }, z.core.$strict>, z.ZodObject<{
110
+ key: z.ZodString;
111
+ action: z.ZodLiteral<"env">;
112
+ value: z.ZodString;
113
+ }, z.core.$strict>], "action">>>;
114
+ toolCallTimeoutMs: z.ZodDefault<z.ZodNumber>;
115
+ reconnect: z.ZodDefault<z.ZodBoolean>;
116
+ }, z.core.$strict>;
117
+ }, z.core.$strict>, z.ZodObject<{
118
+ kind: z.ZodLiteral<"delete">;
119
+ id: z.ZodString;
120
+ revision: z.ZodString;
121
+ confirm: z.ZodLiteral<true>;
122
+ }, z.core.$strict>, z.ZodObject<{
123
+ kind: z.ZodLiteral<"enable">;
124
+ id: z.ZodString;
125
+ revision: z.ZodString;
126
+ enabled: z.ZodBoolean;
127
+ }, z.core.$strict>, z.ZodObject<{
128
+ kind: z.ZodLiteral<"policy">;
129
+ name: z.ZodString;
130
+ revision: z.ZodString;
131
+ enabled: z.ZodBoolean;
132
+ selection: z.ZodObject<{
133
+ workspaceId: z.ZodOptional<z.ZodString>;
134
+ sessionId: z.ZodOptional<z.ZodString>;
135
+ }, z.core.$strict>;
136
+ }, z.core.$strict>, z.ZodObject<{
137
+ kind: z.ZodLiteral<"probe">;
138
+ id: z.ZodString;
139
+ revision: z.ZodString;
140
+ confirm: z.ZodLiteral<true>;
141
+ }, z.core.$strict>], "kind">;
142
+ export type Mutation = z.infer<typeof mutationSchema>;
143
+ export declare const toolSchema: z.ZodObject<{
144
+ name: z.ZodString;
145
+ description: z.ZodString;
146
+ parameters: z.ZodRecord<z.ZodString, z.ZodUnknown>;
147
+ output: z.ZodNullable<z.ZodUnknown>;
148
+ source: z.ZodEnum<{
149
+ unknown: "unknown";
150
+ mcp: "mcp";
151
+ plugin: "plugin";
152
+ core: "core";
153
+ }>;
154
+ owner: z.ZodNullable<z.ZodString>;
155
+ visible: z.ZodNullable<z.ZodBoolean>;
156
+ allowed: z.ZodBoolean;
157
+ protected: z.ZodBoolean;
158
+ }, z.core.$strip>;
159
+ export declare const serverSchema: z.ZodObject<{
160
+ id: z.ZodString;
161
+ serverName: z.ZodString;
162
+ scope: z.ZodString;
163
+ origin: z.ZodEnum<{
164
+ managed: "managed";
165
+ profile: "profile";
166
+ preset: "preset";
167
+ }>;
168
+ transport: z.ZodString;
169
+ enabled: z.ZodBoolean;
170
+ phase: z.ZodNullable<z.ZodString>;
171
+ toolCount: z.ZodNullable<z.ZodNumber>;
172
+ editable: z.ZodBoolean;
173
+ toggleable: z.ZodBoolean;
174
+ config: z.ZodNullable<z.ZodObject<{
175
+ serverName: z.ZodString;
176
+ transport: z.ZodEnum<{
177
+ stdio: "stdio";
178
+ "streamable-http": "streamable-http";
179
+ }>;
180
+ command: z.ZodDefault<z.ZodString>;
181
+ args: z.ZodDefault<z.ZodArray<z.ZodString>>;
182
+ cwd: z.ZodDefault<z.ZodString>;
183
+ url: z.ZodDefault<z.ZodString>;
184
+ secrets: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
185
+ key: z.ZodString;
186
+ action: z.ZodLiteral<"keep">;
187
+ }, z.core.$strict>, z.ZodObject<{
188
+ key: z.ZodString;
189
+ action: z.ZodLiteral<"remove">;
190
+ }, z.core.$strict>, z.ZodObject<{
191
+ key: z.ZodString;
192
+ action: z.ZodLiteral<"value">;
193
+ value: z.ZodString;
194
+ }, z.core.$strict>, z.ZodObject<{
195
+ key: z.ZodString;
196
+ action: z.ZodLiteral<"env">;
197
+ value: z.ZodString;
198
+ }, z.core.$strict>], "action">>>;
199
+ toolCallTimeoutMs: z.ZodDefault<z.ZodNumber>;
200
+ reconnect: z.ZodDefault<z.ZodBoolean>;
201
+ }, z.core.$strict>>;
202
+ credentialKeys: z.ZodArray<z.ZodString>;
203
+ tested: z.ZodNullable<z.ZodObject<{
204
+ ok: z.ZodBoolean;
205
+ at: z.ZodString;
206
+ durationMs: z.ZodNumber;
207
+ toolCount: z.ZodOptional<z.ZodNumber>;
208
+ }, z.core.$strip>>;
209
+ }, z.core.$strip>;
210
+ export declare const stateSchema: z.ZodObject<{
211
+ profile: z.ZodString;
212
+ patchRevision: z.ZodString;
213
+ policyRevision: z.ZodString;
214
+ workspaceId: z.ZodString;
215
+ workspaces: z.ZodArray<z.ZodObject<{
216
+ id: z.ZodString;
217
+ title: z.ZodString;
218
+ path: z.ZodString;
219
+ }, z.core.$strip>>;
220
+ sessions: z.ZodArray<z.ZodObject<{
221
+ id: z.ZodString;
222
+ title: z.ZodString;
223
+ cwd: z.ZodString;
224
+ }, z.core.$strip>>;
225
+ selectedSessionId: z.ZodNullable<z.ZodString>;
226
+ scopeKind: z.ZodEnum<{
227
+ preset: "preset";
228
+ live: "live";
229
+ global: "global";
230
+ }>;
231
+ presetId: z.ZodNullable<z.ZodString>;
232
+ tools: z.ZodArray<z.ZodObject<{
233
+ name: z.ZodString;
234
+ description: z.ZodString;
235
+ parameters: z.ZodRecord<z.ZodString, z.ZodUnknown>;
236
+ output: z.ZodNullable<z.ZodUnknown>;
237
+ source: z.ZodEnum<{
238
+ unknown: "unknown";
239
+ mcp: "mcp";
240
+ plugin: "plugin";
241
+ core: "core";
242
+ }>;
243
+ owner: z.ZodNullable<z.ZodString>;
244
+ visible: z.ZodNullable<z.ZodBoolean>;
245
+ allowed: z.ZodBoolean;
246
+ protected: z.ZodBoolean;
247
+ }, z.core.$strip>>;
248
+ servers: z.ZodArray<z.ZodObject<{
249
+ id: z.ZodString;
250
+ serverName: z.ZodString;
251
+ scope: z.ZodString;
252
+ origin: z.ZodEnum<{
253
+ managed: "managed";
254
+ profile: "profile";
255
+ preset: "preset";
256
+ }>;
257
+ transport: z.ZodString;
258
+ enabled: z.ZodBoolean;
259
+ phase: z.ZodNullable<z.ZodString>;
260
+ toolCount: z.ZodNullable<z.ZodNumber>;
261
+ editable: z.ZodBoolean;
262
+ toggleable: z.ZodBoolean;
263
+ config: z.ZodNullable<z.ZodObject<{
264
+ serverName: z.ZodString;
265
+ transport: z.ZodEnum<{
266
+ stdio: "stdio";
267
+ "streamable-http": "streamable-http";
268
+ }>;
269
+ command: z.ZodDefault<z.ZodString>;
270
+ args: z.ZodDefault<z.ZodArray<z.ZodString>>;
271
+ cwd: z.ZodDefault<z.ZodString>;
272
+ url: z.ZodDefault<z.ZodString>;
273
+ secrets: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
274
+ key: z.ZodString;
275
+ action: z.ZodLiteral<"keep">;
276
+ }, z.core.$strict>, z.ZodObject<{
277
+ key: z.ZodString;
278
+ action: z.ZodLiteral<"remove">;
279
+ }, z.core.$strict>, z.ZodObject<{
280
+ key: z.ZodString;
281
+ action: z.ZodLiteral<"value">;
282
+ value: z.ZodString;
283
+ }, z.core.$strict>, z.ZodObject<{
284
+ key: z.ZodString;
285
+ action: z.ZodLiteral<"env">;
286
+ value: z.ZodString;
287
+ }, z.core.$strict>], "action">>>;
288
+ toolCallTimeoutMs: z.ZodDefault<z.ZodNumber>;
289
+ reconnect: z.ZodDefault<z.ZodBoolean>;
290
+ }, z.core.$strict>>;
291
+ credentialKeys: z.ZodArray<z.ZodString>;
292
+ tested: z.ZodNullable<z.ZodObject<{
293
+ ok: z.ZodBoolean;
294
+ at: z.ZodString;
295
+ durationMs: z.ZodNumber;
296
+ toolCount: z.ZodOptional<z.ZodNumber>;
297
+ }, z.core.$strip>>;
298
+ }, z.core.$strip>>;
299
+ notices: z.ZodArray<z.ZodString>;
300
+ }, z.core.$strip>;
301
+ export type State = z.infer<typeof stateSchema>;
302
+ export type ToolItem = z.infer<typeof toolSchema>;
303
+ export type ServerItem = z.infer<typeof serverSchema>;
304
+ export declare const outcomeSchema: z.ZodObject<{
305
+ application: z.ZodEnum<{
306
+ tested: "tested";
307
+ applied: "applied";
308
+ "restart-required": "restart-required";
309
+ overridden: "overridden";
310
+ failed: "failed";
311
+ }>;
312
+ notice: z.ZodOptional<z.ZodString>;
313
+ }, z.core.$strip>;
314
+ export type Outcome = z.infer<typeof outcomeSchema>;