agents 0.0.0-293b546 → 0.0.0-29938d4
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 +121 -0
- package/dist/ai-chat-agent.d.ts +158 -24
- package/dist/ai-chat-agent.js +380 -60
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-chat-v5-migration.js +154 -2
- package/dist/ai-chat-v5-migration.js.map +1 -0
- package/dist/ai-react.d.ts +136 -16
- package/dist/ai-react.js +252 -74
- package/dist/ai-react.js.map +1 -1
- package/dist/{ai-types-81H_-Uxh.d.ts → ai-types-0OnT3FHg.d.ts} +26 -2
- package/dist/{ai-types-CrMqkwc_.js → ai-types-DEtF_8Km.js} +5 -1
- package/dist/ai-types-DEtF_8Km.js.map +1 -0
- package/dist/ai-types.d.ts +1 -1
- package/dist/ai-types.js +1 -1
- package/dist/cli/index.d.ts +1 -0
- package/dist/{cli.js → cli/index.js} +7 -6
- package/dist/cli/index.js.map +1 -0
- package/dist/{client-BAQA84dr.d.ts → client-CdM5I962.d.ts} +2 -2
- package/dist/client-DFotUKH_.d.ts +834 -0
- package/dist/{client-B3SR12TQ.js → client-DjTPRM8-.js} +2 -2
- package/dist/{client-B3SR12TQ.js.map → client-DjTPRM8-.js.map} +1 -1
- package/dist/{client-C8VrzljV.js → client-QZa2Rq0l.js} +371 -187
- package/dist/client-QZa2Rq0l.js.map +1 -0
- package/dist/client.d.ts +1 -2
- package/dist/client.js +1 -2
- package/dist/codemode/ai.js +6 -6
- package/dist/codemode/ai.js.map +1 -1
- package/dist/context-BkKbAa1R.js +8 -0
- package/dist/context-BkKbAa1R.js.map +1 -0
- package/dist/context-DcbQ8o7k.d.ts +24 -0
- package/dist/context.d.ts +6 -0
- package/dist/context.js +3 -0
- package/dist/{do-oauth-client-provider-C2CHH5x-.d.ts → do-oauth-client-provider--To1Tsjj.d.ts} +20 -5
- package/dist/{do-oauth-client-provider-CwqK5SXm.js → do-oauth-client-provider-B1fVIshX.js} +69 -8
- package/dist/do-oauth-client-provider-B1fVIshX.js.map +1 -0
- package/dist/{index-7kI1zprE.d.ts → index-CT2tCrLr.d.ts} +59 -60
- package/dist/{index-BUle9RiP.d.ts → index-DLuxm_9W.d.ts} +2 -2
- package/dist/index.d.ts +31 -34
- package/dist/index.js +5 -5
- package/dist/mcp/client.d.ts +2 -4
- package/dist/mcp/client.js +2 -2
- package/dist/mcp/do-oauth-client-provider.d.ts +1 -1
- package/dist/mcp/do-oauth-client-provider.js +1 -1
- package/dist/mcp/index.d.ts +19 -12
- package/dist/mcp/index.js +55 -60
- package/dist/mcp/index.js.map +1 -1
- package/dist/{mcp-BwPscEiF.d.ts → mcp-CPSfGUgd.d.ts} +1 -1
- package/dist/observability/index.d.ts +1 -2
- package/dist/observability/index.js +5 -5
- package/dist/react.d.ts +134 -10
- package/dist/react.js +56 -56
- package/dist/react.js.map +1 -1
- package/dist/schedule.d.ts +18 -72
- package/dist/{serializable-faDkMCai.d.ts → serializable-Crsj26mx.d.ts} +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/{src-xjQt2wBU.js → src-BZDh910Z.js} +26 -25
- package/dist/src-BZDh910Z.js.map +1 -0
- package/package.json +29 -14
- package/dist/ai-chat-v5-migration-BSiGZmYU.js +0 -155
- package/dist/ai-chat-v5-migration-BSiGZmYU.js.map +0 -1
- package/dist/ai-types-CrMqkwc_.js.map +0 -1
- package/dist/cli.d.ts +0 -8
- package/dist/cli.js.map +0 -1
- package/dist/client-BG2wUgN5.d.ts +0 -1462
- package/dist/client-C8VrzljV.js.map +0 -1
- package/dist/do-oauth-client-provider-CwqK5SXm.js.map +0 -1
- package/dist/react-9nVfoERh.d.ts +0 -113
- package/dist/src-xjQt2wBU.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as DurableObjectOAuthClientProvider } from "./do-oauth-client-provider-
|
|
1
|
+
import { t as DurableObjectOAuthClientProvider } from "./do-oauth-client-provider-B1fVIshX.js";
|
|
2
2
|
import { nanoid } from "nanoid";
|
|
3
3
|
import { CfWorkerJsonSchemaValidator } from "@modelcontextprotocol/sdk/validation/cfworker-provider.js";
|
|
4
4
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
@@ -60,6 +60,22 @@ function isTransportNotImplemented(error) {
|
|
|
60
60
|
|
|
61
61
|
//#endregion
|
|
62
62
|
//#region src/mcp/client-connection.ts
|
|
63
|
+
/**
|
|
64
|
+
* Connection state machine for MCP client connections.
|
|
65
|
+
*
|
|
66
|
+
* State transitions:
|
|
67
|
+
* - Non-OAuth: init() → CONNECTING → DISCOVERING → READY
|
|
68
|
+
* - OAuth: init() → AUTHENTICATING → (callback) → CONNECTING → DISCOVERING → READY
|
|
69
|
+
* - Any state can transition to FAILED on error
|
|
70
|
+
*/
|
|
71
|
+
const MCPConnectionState = {
|
|
72
|
+
AUTHENTICATING: "authenticating",
|
|
73
|
+
CONNECTING: "connecting",
|
|
74
|
+
CONNECTED: "connected",
|
|
75
|
+
DISCOVERING: "discovering",
|
|
76
|
+
READY: "ready",
|
|
77
|
+
FAILED: "failed"
|
|
78
|
+
};
|
|
63
79
|
var MCPClientConnection = class {
|
|
64
80
|
constructor(url, info, options = {
|
|
65
81
|
client: {},
|
|
@@ -67,7 +83,7 @@ var MCPClientConnection = class {
|
|
|
67
83
|
}) {
|
|
68
84
|
this.url = url;
|
|
69
85
|
this.options = options;
|
|
70
|
-
this.connectionState =
|
|
86
|
+
this.connectionState = MCPConnectionState.CONNECTING;
|
|
71
87
|
this.tools = [];
|
|
72
88
|
this.prompts = [];
|
|
73
89
|
this.resources = [];
|
|
@@ -83,36 +99,49 @@ var MCPClientConnection = class {
|
|
|
83
99
|
});
|
|
84
100
|
}
|
|
85
101
|
/**
|
|
86
|
-
* Initialize a client connection
|
|
102
|
+
* Initialize a client connection, if authentication is required, the connection will be in the AUTHENTICATING state
|
|
103
|
+
* Sets connection state based on the result and emits observability events
|
|
87
104
|
*
|
|
88
|
-
* @returns
|
|
105
|
+
* @returns Error message if connection failed, undefined otherwise
|
|
89
106
|
*/
|
|
90
107
|
async init() {
|
|
91
108
|
const transportType = this.options.transport.type;
|
|
92
109
|
if (!transportType) throw new Error("Transport type must be specified");
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
this.
|
|
98
|
-
|
|
99
|
-
|
|
110
|
+
const res = await this.tryConnect(transportType);
|
|
111
|
+
this.connectionState = res.state;
|
|
112
|
+
if (res.state === MCPConnectionState.CONNECTED && res.transport) {
|
|
113
|
+
this.client.setRequestHandler(ElicitRequestSchema, async (request) => {
|
|
114
|
+
return await this.handleElicitationRequest(request);
|
|
115
|
+
});
|
|
116
|
+
this.lastConnectedTransport = res.transport;
|
|
100
117
|
this._onObservabilityEvent.fire({
|
|
101
118
|
type: "mcp:client:connect",
|
|
102
|
-
displayMessage: `
|
|
119
|
+
displayMessage: `Connected successfully using ${res.transport} transport for ${this.url.toString()}`,
|
|
120
|
+
payload: {
|
|
121
|
+
url: this.url.toString(),
|
|
122
|
+
transport: res.transport,
|
|
123
|
+
state: this.connectionState
|
|
124
|
+
},
|
|
125
|
+
timestamp: Date.now(),
|
|
126
|
+
id: nanoid()
|
|
127
|
+
});
|
|
128
|
+
return;
|
|
129
|
+
} else if (res.state === MCPConnectionState.FAILED && res.error) {
|
|
130
|
+
const errorMessage = toErrorMessage(res.error);
|
|
131
|
+
this._onObservabilityEvent.fire({
|
|
132
|
+
type: "mcp:client:connect",
|
|
133
|
+
displayMessage: `Failed to connect to ${this.url.toString()}: ${errorMessage}`,
|
|
103
134
|
payload: {
|
|
104
135
|
url: this.url.toString(),
|
|
105
136
|
transport: transportType,
|
|
106
137
|
state: this.connectionState,
|
|
107
|
-
error:
|
|
138
|
+
error: errorMessage
|
|
108
139
|
},
|
|
109
140
|
timestamp: Date.now(),
|
|
110
141
|
id: nanoid()
|
|
111
142
|
});
|
|
112
|
-
|
|
113
|
-
return;
|
|
143
|
+
return errorMessage;
|
|
114
144
|
}
|
|
115
|
-
await this.discoverAndRegister();
|
|
116
145
|
}
|
|
117
146
|
/**
|
|
118
147
|
* Finish OAuth by probing transports based on configured type.
|
|
@@ -144,113 +173,189 @@ var MCPClientConnection = class {
|
|
|
144
173
|
* Complete OAuth authorization
|
|
145
174
|
*/
|
|
146
175
|
async completeAuthorization(code) {
|
|
147
|
-
if (this.connectionState !==
|
|
176
|
+
if (this.connectionState !== MCPConnectionState.AUTHENTICATING) throw new Error("Connection must be in authenticating state to complete authorization");
|
|
148
177
|
try {
|
|
149
178
|
await this.finishAuthProbe(code);
|
|
150
|
-
this.connectionState =
|
|
179
|
+
this.connectionState = MCPConnectionState.CONNECTING;
|
|
151
180
|
} catch (error) {
|
|
152
|
-
this.connectionState =
|
|
181
|
+
this.connectionState = MCPConnectionState.FAILED;
|
|
153
182
|
throw error;
|
|
154
183
|
}
|
|
155
184
|
}
|
|
156
185
|
/**
|
|
157
|
-
*
|
|
186
|
+
* Discover server capabilities and register tools, resources, prompts, and templates.
|
|
187
|
+
* This method does the work but does not manage connection state - that's handled by discover().
|
|
158
188
|
*/
|
|
159
|
-
async
|
|
160
|
-
|
|
189
|
+
async discoverAndRegister() {
|
|
190
|
+
this.serverCapabilities = this.client.getServerCapabilities();
|
|
191
|
+
if (!this.serverCapabilities) throw new Error("The MCP Server failed to return server capabilities");
|
|
192
|
+
const operations = [];
|
|
193
|
+
const operationNames = [];
|
|
194
|
+
operations.push(Promise.resolve(this.client.getInstructions()));
|
|
195
|
+
operationNames.push("instructions");
|
|
196
|
+
if (this.serverCapabilities.tools) {
|
|
197
|
+
operations.push(this.registerTools());
|
|
198
|
+
operationNames.push("tools");
|
|
199
|
+
}
|
|
200
|
+
if (this.serverCapabilities.resources) {
|
|
201
|
+
operations.push(this.registerResources());
|
|
202
|
+
operationNames.push("resources");
|
|
203
|
+
}
|
|
204
|
+
if (this.serverCapabilities.prompts) {
|
|
205
|
+
operations.push(this.registerPrompts());
|
|
206
|
+
operationNames.push("prompts");
|
|
207
|
+
}
|
|
208
|
+
if (this.serverCapabilities.resources) {
|
|
209
|
+
operations.push(this.registerResourceTemplates());
|
|
210
|
+
operationNames.push("resource templates");
|
|
211
|
+
}
|
|
161
212
|
try {
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
213
|
+
const results = await Promise.all(operations);
|
|
214
|
+
for (let i = 0; i < results.length; i++) {
|
|
215
|
+
const result = results[i];
|
|
216
|
+
switch (operationNames[i]) {
|
|
217
|
+
case "instructions":
|
|
218
|
+
this.instructions = result;
|
|
219
|
+
break;
|
|
220
|
+
case "tools":
|
|
221
|
+
this.tools = result;
|
|
222
|
+
break;
|
|
223
|
+
case "resources":
|
|
224
|
+
this.resources = result;
|
|
225
|
+
break;
|
|
226
|
+
case "prompts":
|
|
227
|
+
this.prompts = result;
|
|
228
|
+
break;
|
|
229
|
+
case "resource templates":
|
|
230
|
+
this.resourceTemplates = result;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
166
234
|
} catch (error) {
|
|
167
|
-
this.
|
|
235
|
+
this._onObservabilityEvent.fire({
|
|
236
|
+
type: "mcp:client:discover",
|
|
237
|
+
displayMessage: `Failed to discover capabilities for ${this.url.toString()}: ${toErrorMessage(error)}`,
|
|
238
|
+
payload: {
|
|
239
|
+
url: this.url.toString(),
|
|
240
|
+
error: toErrorMessage(error)
|
|
241
|
+
},
|
|
242
|
+
timestamp: Date.now(),
|
|
243
|
+
id: nanoid()
|
|
244
|
+
});
|
|
168
245
|
throw error;
|
|
169
246
|
}
|
|
170
247
|
}
|
|
171
248
|
/**
|
|
172
|
-
* Discover server capabilities
|
|
249
|
+
* Discover server capabilities with timeout and cancellation support.
|
|
250
|
+
* If called while a previous discovery is in-flight, the previous discovery will be aborted.
|
|
251
|
+
*
|
|
252
|
+
* @param options Optional configuration
|
|
253
|
+
* @param options.timeoutMs Timeout in milliseconds (default: 15000)
|
|
254
|
+
* @returns Result indicating success/failure with optional error message
|
|
173
255
|
*/
|
|
174
|
-
async
|
|
175
|
-
|
|
176
|
-
this.
|
|
177
|
-
if (!this.serverCapabilities) throw new Error("The MCP Server failed to return server capabilities");
|
|
178
|
-
const [instructionsResult, toolsResult, resourcesResult, promptsResult, resourceTemplatesResult] = await Promise.allSettled([
|
|
179
|
-
this.client.getInstructions(),
|
|
180
|
-
this.registerTools(),
|
|
181
|
-
this.registerResources(),
|
|
182
|
-
this.registerPrompts(),
|
|
183
|
-
this.registerResourceTemplates()
|
|
184
|
-
]);
|
|
185
|
-
const operations = [
|
|
186
|
-
{
|
|
187
|
-
name: "instructions",
|
|
188
|
-
result: instructionsResult
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
name: "tools",
|
|
192
|
-
result: toolsResult
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
name: "resources",
|
|
196
|
-
result: resourcesResult
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
name: "prompts",
|
|
200
|
-
result: promptsResult
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
name: "resource templates",
|
|
204
|
-
result: resourceTemplatesResult
|
|
205
|
-
}
|
|
206
|
-
];
|
|
207
|
-
for (const { name, result } of operations) if (result.status === "rejected") {
|
|
208
|
-
const url = this.url.toString();
|
|
256
|
+
async discover(options = {}) {
|
|
257
|
+
const { timeoutMs = 15e3 } = options;
|
|
258
|
+
if (this.connectionState !== MCPConnectionState.CONNECTED && this.connectionState !== MCPConnectionState.READY) {
|
|
209
259
|
this._onObservabilityEvent.fire({
|
|
210
260
|
type: "mcp:client:discover",
|
|
211
|
-
displayMessage: `
|
|
261
|
+
displayMessage: `Discovery skipped for ${this.url.toString()}, state is ${this.connectionState}`,
|
|
212
262
|
payload: {
|
|
213
|
-
url,
|
|
214
|
-
|
|
215
|
-
error: result.reason
|
|
263
|
+
url: this.url.toString(),
|
|
264
|
+
state: this.connectionState
|
|
216
265
|
},
|
|
217
266
|
timestamp: Date.now(),
|
|
218
267
|
id: nanoid()
|
|
219
268
|
});
|
|
269
|
+
return {
|
|
270
|
+
success: false,
|
|
271
|
+
error: `Discovery skipped - connection in ${this.connectionState} state`
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
if (this._discoveryAbortController) {
|
|
275
|
+
this._discoveryAbortController.abort();
|
|
276
|
+
this._discoveryAbortController = void 0;
|
|
277
|
+
}
|
|
278
|
+
const abortController = new AbortController();
|
|
279
|
+
this._discoveryAbortController = abortController;
|
|
280
|
+
this.connectionState = MCPConnectionState.DISCOVERING;
|
|
281
|
+
let timeoutId;
|
|
282
|
+
try {
|
|
283
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
284
|
+
timeoutId = setTimeout(() => reject(/* @__PURE__ */ new Error(`Discovery timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
285
|
+
});
|
|
286
|
+
if (abortController.signal.aborted) throw new Error("Discovery was cancelled");
|
|
287
|
+
const abortPromise = new Promise((_, reject) => {
|
|
288
|
+
abortController.signal.addEventListener("abort", () => {
|
|
289
|
+
reject(/* @__PURE__ */ new Error("Discovery was cancelled"));
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
await Promise.race([
|
|
293
|
+
this.discoverAndRegister(),
|
|
294
|
+
timeoutPromise,
|
|
295
|
+
abortPromise
|
|
296
|
+
]);
|
|
297
|
+
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
298
|
+
this.connectionState = MCPConnectionState.READY;
|
|
299
|
+
this._onObservabilityEvent.fire({
|
|
300
|
+
type: "mcp:client:discover",
|
|
301
|
+
displayMessage: `Discovery completed for ${this.url.toString()}`,
|
|
302
|
+
payload: { url: this.url.toString() },
|
|
303
|
+
timestamp: Date.now(),
|
|
304
|
+
id: nanoid()
|
|
305
|
+
});
|
|
306
|
+
return { success: true };
|
|
307
|
+
} catch (e) {
|
|
308
|
+
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
309
|
+
this.connectionState = MCPConnectionState.CONNECTED;
|
|
310
|
+
return {
|
|
311
|
+
success: false,
|
|
312
|
+
error: e instanceof Error ? e.message : String(e)
|
|
313
|
+
};
|
|
314
|
+
} finally {
|
|
315
|
+
this._discoveryAbortController = void 0;
|
|
220
316
|
}
|
|
221
|
-
this.instructions = instructionsResult.status === "fulfilled" ? instructionsResult.value : void 0;
|
|
222
|
-
this.tools = toolsResult.status === "fulfilled" ? toolsResult.value : [];
|
|
223
|
-
this.resources = resourcesResult.status === "fulfilled" ? resourcesResult.value : [];
|
|
224
|
-
this.prompts = promptsResult.status === "fulfilled" ? promptsResult.value : [];
|
|
225
|
-
this.resourceTemplates = resourceTemplatesResult.status === "fulfilled" ? resourceTemplatesResult.value : [];
|
|
226
|
-
this.connectionState = "ready";
|
|
227
317
|
}
|
|
228
318
|
/**
|
|
229
|
-
*
|
|
319
|
+
* Cancel any in-flight discovery operation.
|
|
320
|
+
* Called when closing the connection.
|
|
321
|
+
*/
|
|
322
|
+
cancelDiscovery() {
|
|
323
|
+
if (this._discoveryAbortController) {
|
|
324
|
+
this._discoveryAbortController.abort();
|
|
325
|
+
this._discoveryAbortController = void 0;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Notification handler registration for tools
|
|
330
|
+
* Should only be called if serverCapabilities.tools exists
|
|
230
331
|
*/
|
|
231
332
|
async registerTools() {
|
|
232
|
-
if (
|
|
233
|
-
if (this.serverCapabilities.tools.listChanged) this.client.setNotificationHandler(ToolListChangedNotificationSchema, async (_notification) => {
|
|
333
|
+
if (this.serverCapabilities?.tools?.listChanged) this.client.setNotificationHandler(ToolListChangedNotificationSchema, async (_notification) => {
|
|
234
334
|
this.tools = await this.fetchTools();
|
|
235
335
|
});
|
|
236
336
|
return this.fetchTools();
|
|
237
337
|
}
|
|
338
|
+
/**
|
|
339
|
+
* Notification handler registration for resources
|
|
340
|
+
* Should only be called if serverCapabilities.resources exists
|
|
341
|
+
*/
|
|
238
342
|
async registerResources() {
|
|
239
|
-
if (
|
|
240
|
-
if (this.serverCapabilities.resources.listChanged) this.client.setNotificationHandler(ResourceListChangedNotificationSchema, async (_notification) => {
|
|
343
|
+
if (this.serverCapabilities?.resources?.listChanged) this.client.setNotificationHandler(ResourceListChangedNotificationSchema, async (_notification) => {
|
|
241
344
|
this.resources = await this.fetchResources();
|
|
242
345
|
});
|
|
243
346
|
return this.fetchResources();
|
|
244
347
|
}
|
|
348
|
+
/**
|
|
349
|
+
* Notification handler registration for prompts
|
|
350
|
+
* Should only be called if serverCapabilities.prompts exists
|
|
351
|
+
*/
|
|
245
352
|
async registerPrompts() {
|
|
246
|
-
if (
|
|
247
|
-
if (this.serverCapabilities.prompts.listChanged) this.client.setNotificationHandler(PromptListChangedNotificationSchema, async (_notification) => {
|
|
353
|
+
if (this.serverCapabilities?.prompts?.listChanged) this.client.setNotificationHandler(PromptListChangedNotificationSchema, async (_notification) => {
|
|
248
354
|
this.prompts = await this.fetchPrompts();
|
|
249
355
|
});
|
|
250
356
|
return this.fetchPrompts();
|
|
251
357
|
}
|
|
252
358
|
async registerResourceTemplates() {
|
|
253
|
-
if (!this.serverCapabilities || !this.serverCapabilities.resources) return [];
|
|
254
359
|
return this.fetchResourceTemplates();
|
|
255
360
|
}
|
|
256
361
|
async fetchTools() {
|
|
@@ -316,44 +421,24 @@ var MCPClientConnection = class {
|
|
|
316
421
|
const transport = this.getTransport(currentTransportType);
|
|
317
422
|
try {
|
|
318
423
|
await this.client.connect(transport);
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
displayMessage: `Connected successfully using ${currentTransportType} transport for ${url}`,
|
|
324
|
-
payload: {
|
|
325
|
-
url,
|
|
326
|
-
transport: currentTransportType,
|
|
327
|
-
state: this.connectionState
|
|
328
|
-
},
|
|
329
|
-
timestamp: Date.now(),
|
|
330
|
-
id: nanoid()
|
|
331
|
-
});
|
|
332
|
-
break;
|
|
424
|
+
return {
|
|
425
|
+
state: MCPConnectionState.CONNECTED,
|
|
426
|
+
transport: currentTransportType
|
|
427
|
+
};
|
|
333
428
|
} catch (e) {
|
|
334
429
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
335
|
-
if (isUnauthorized(error))
|
|
336
|
-
if (
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
payload: {
|
|
342
|
-
url,
|
|
343
|
-
transport: currentTransportType,
|
|
344
|
-
state: this.connectionState
|
|
345
|
-
},
|
|
346
|
-
timestamp: Date.now(),
|
|
347
|
-
id: nanoid()
|
|
348
|
-
});
|
|
349
|
-
continue;
|
|
350
|
-
}
|
|
351
|
-
throw e;
|
|
430
|
+
if (isUnauthorized(error)) return { state: MCPConnectionState.AUTHENTICATING };
|
|
431
|
+
if (isTransportNotImplemented(error) && hasFallback) continue;
|
|
432
|
+
return {
|
|
433
|
+
state: MCPConnectionState.FAILED,
|
|
434
|
+
error
|
|
435
|
+
};
|
|
352
436
|
}
|
|
353
437
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
438
|
+
return {
|
|
439
|
+
state: MCPConnectionState.FAILED,
|
|
440
|
+
error: /* @__PURE__ */ new Error("No transports available")
|
|
441
|
+
};
|
|
357
442
|
}
|
|
358
443
|
_capabilityErrorHandler(empty, method) {
|
|
359
444
|
return (e) => {
|
|
@@ -447,12 +532,12 @@ var MCPClientManager = class {
|
|
|
447
532
|
for (const server of servers) {
|
|
448
533
|
const existingConn = this.mcpConnections[server.id];
|
|
449
534
|
if (existingConn) {
|
|
450
|
-
if (existingConn.connectionState ===
|
|
535
|
+
if (existingConn.connectionState === MCPConnectionState.READY) {
|
|
451
536
|
console.warn(`[MCPClientManager] Server ${server.id} already has a ready connection. Skipping recreation.`);
|
|
452
537
|
continue;
|
|
453
538
|
}
|
|
454
|
-
if (existingConn.connectionState ===
|
|
455
|
-
if (existingConn.connectionState ===
|
|
539
|
+
if (existingConn.connectionState === MCPConnectionState.AUTHENTICATING || existingConn.connectionState === MCPConnectionState.CONNECTING || existingConn.connectionState === MCPConnectionState.DISCOVERING) continue;
|
|
540
|
+
if (existingConn.connectionState === MCPConnectionState.FAILED) {
|
|
456
541
|
try {
|
|
457
542
|
await existingConn.client.close();
|
|
458
543
|
} catch (error) {
|
|
@@ -465,7 +550,7 @@ var MCPClientManager = class {
|
|
|
465
550
|
}
|
|
466
551
|
const parsedOptions = server.server_options ? JSON.parse(server.server_options) : null;
|
|
467
552
|
const authProvider = this.createAuthProvider(server.id, server.callback_url, clientName, server.client_id ?? void 0);
|
|
468
|
-
this.createConnection(server.id, server.server_url, {
|
|
553
|
+
const conn = this.createConnection(server.id, server.server_url, {
|
|
469
554
|
client: parsedOptions?.client ?? {},
|
|
470
555
|
transport: {
|
|
471
556
|
...parsedOptions?.transport ?? {},
|
|
@@ -473,13 +558,27 @@ var MCPClientManager = class {
|
|
|
473
558
|
authProvider
|
|
474
559
|
}
|
|
475
560
|
});
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
561
|
+
if (server.auth_url) {
|
|
562
|
+
conn.connectionState = MCPConnectionState.AUTHENTICATING;
|
|
563
|
+
continue;
|
|
564
|
+
}
|
|
565
|
+
this._restoreServer(server.id);
|
|
479
566
|
}
|
|
480
567
|
this._isRestored = true;
|
|
481
568
|
}
|
|
482
569
|
/**
|
|
570
|
+
* Internal method to restore a single server connection and discovery
|
|
571
|
+
*/
|
|
572
|
+
async _restoreServer(serverId) {
|
|
573
|
+
if ((await this.connectToServer(serverId).catch((error) => {
|
|
574
|
+
console.error(`Error connecting to ${serverId}:`, error);
|
|
575
|
+
return null;
|
|
576
|
+
}))?.state === MCPConnectionState.CONNECTED) {
|
|
577
|
+
const discoverResult = await this.discoverIfConnected(serverId);
|
|
578
|
+
if (discoverResult && !discoverResult.success) console.error(`Error discovering ${serverId}:`, discoverResult.error);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
483
582
|
* Connect to and register an MCP server
|
|
484
583
|
*
|
|
485
584
|
* @deprecated This method is maintained for backward compatibility.
|
|
@@ -526,7 +625,7 @@ var MCPClientManager = class {
|
|
|
526
625
|
await this.mcpConnections[id].init();
|
|
527
626
|
if (options.reconnect?.oauthCode) try {
|
|
528
627
|
await this.mcpConnections[id].completeAuthorization(options.reconnect.oauthCode);
|
|
529
|
-
await this.mcpConnections[id].
|
|
628
|
+
await this.mcpConnections[id].init();
|
|
530
629
|
} catch (error) {
|
|
531
630
|
this._onObservabilityEvent.fire({
|
|
532
631
|
type: "mcp:client:connect",
|
|
@@ -543,19 +642,22 @@ var MCPClientManager = class {
|
|
|
543
642
|
throw error;
|
|
544
643
|
}
|
|
545
644
|
const authUrl = options.transport?.authProvider?.authUrl;
|
|
546
|
-
if (this.mcpConnections[id].connectionState ===
|
|
645
|
+
if (this.mcpConnections[id].connectionState === MCPConnectionState.AUTHENTICATING && authUrl && options.transport?.authProvider?.redirectUrl) return {
|
|
547
646
|
authUrl,
|
|
548
647
|
clientId: options.transport?.authProvider?.clientId,
|
|
549
648
|
id
|
|
550
649
|
};
|
|
650
|
+
const discoverResult = await this.discoverIfConnected(id);
|
|
651
|
+
if (discoverResult && !discoverResult.success) throw new Error(`Failed to discover server capabilities: ${discoverResult.error}`);
|
|
551
652
|
return { id };
|
|
552
653
|
}
|
|
553
654
|
/**
|
|
554
655
|
* Create an in-memory connection object and set up observability
|
|
555
656
|
* Does NOT save to storage - use registerServer() for that
|
|
657
|
+
* @returns The connection object (existing or newly created)
|
|
556
658
|
*/
|
|
557
659
|
createConnection(id, url, options) {
|
|
558
|
-
if (this.mcpConnections[id]) return;
|
|
660
|
+
if (this.mcpConnections[id]) return this.mcpConnections[id];
|
|
559
661
|
const normalizedTransport = {
|
|
560
662
|
...options.transport,
|
|
561
663
|
type: options.transport?.type ?? "auto"
|
|
@@ -577,6 +679,7 @@ var MCPClientManager = class {
|
|
|
577
679
|
store.add(this.mcpConnections[id].onObservabilityEvent((event) => {
|
|
578
680
|
this._onObservabilityEvent.fire(event);
|
|
579
681
|
}));
|
|
682
|
+
return this.mcpConnections[id];
|
|
580
683
|
}
|
|
581
684
|
/**
|
|
582
685
|
* Register an MCP server connection without connecting
|
|
@@ -613,14 +716,13 @@ var MCPClientManager = class {
|
|
|
613
716
|
/**
|
|
614
717
|
* Connect to an already registered MCP server and initialize the connection.
|
|
615
718
|
*
|
|
616
|
-
* For OAuth servers,
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
*
|
|
620
|
-
* For non-OAuth servers, this establishes the connection immediately and returns
|
|
621
|
-
* `{ state: "ready" }`.
|
|
719
|
+
* For OAuth servers, returns `{ state: "authenticating", authUrl, clientId? }`.
|
|
720
|
+
* The user must complete the OAuth flow via the authUrl, which triggers a
|
|
721
|
+
* callback handled by `handleCallbackRequest()`.
|
|
622
722
|
*
|
|
623
|
-
*
|
|
723
|
+
* For non-OAuth servers, establishes the transport connection and returns
|
|
724
|
+
* `{ state: "connected" }`. Call `discoverIfConnected()` afterwards to
|
|
725
|
+
* discover capabilities and transition to "ready" state.
|
|
624
726
|
*
|
|
625
727
|
* @param id Server ID (must be registered first via registerServer())
|
|
626
728
|
* @returns Connection result with current state and OAuth info (if applicable)
|
|
@@ -628,70 +730,99 @@ var MCPClientManager = class {
|
|
|
628
730
|
async connectToServer(id) {
|
|
629
731
|
const conn = this.mcpConnections[id];
|
|
630
732
|
if (!conn) throw new Error(`Server ${id} is not registered. Call registerServer() first.`);
|
|
631
|
-
await conn.init();
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
clientId
|
|
733
|
+
const error = await conn.init();
|
|
734
|
+
this._onServerStateChanged.fire();
|
|
735
|
+
switch (conn.connectionState) {
|
|
736
|
+
case MCPConnectionState.FAILED: return {
|
|
737
|
+
state: conn.connectionState,
|
|
738
|
+
error: error ?? "Unknown connection error"
|
|
739
|
+
};
|
|
740
|
+
case MCPConnectionState.AUTHENTICATING: {
|
|
741
|
+
const authUrl = conn.options.transport.authProvider?.authUrl;
|
|
742
|
+
const redirectUrl = conn.options.transport.authProvider?.redirectUrl;
|
|
743
|
+
if (!authUrl || !redirectUrl) return {
|
|
744
|
+
state: MCPConnectionState.FAILED,
|
|
745
|
+
error: `OAuth configuration incomplete: missing ${!authUrl ? "authUrl" : "redirectUrl"}`
|
|
746
|
+
};
|
|
747
|
+
const clientId = conn.options.transport.authProvider?.clientId;
|
|
748
|
+
const serverRow = this.getServersFromStorage().find((s) => s.id === id);
|
|
749
|
+
if (serverRow) {
|
|
750
|
+
this.saveServerToStorage({
|
|
751
|
+
...serverRow,
|
|
752
|
+
auth_url: authUrl,
|
|
753
|
+
client_id: clientId ?? null
|
|
754
|
+
});
|
|
755
|
+
this._onServerStateChanged.fire();
|
|
756
|
+
}
|
|
757
|
+
return {
|
|
758
|
+
state: conn.connectionState,
|
|
759
|
+
authUrl,
|
|
760
|
+
clientId
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
case MCPConnectionState.CONNECTED: return { state: conn.connectionState };
|
|
764
|
+
default: return {
|
|
765
|
+
state: MCPConnectionState.FAILED,
|
|
766
|
+
error: `Unexpected connection state after init: ${conn.connectionState}`
|
|
646
767
|
};
|
|
647
768
|
}
|
|
648
|
-
|
|
649
|
-
|
|
769
|
+
}
|
|
770
|
+
extractServerIdFromState(state) {
|
|
771
|
+
if (!state) return null;
|
|
772
|
+
const parts = state.split(".");
|
|
773
|
+
return parts.length === 2 ? parts[1] : null;
|
|
650
774
|
}
|
|
651
775
|
isCallbackRequest(req) {
|
|
652
776
|
if (req.method !== "GET") return false;
|
|
653
777
|
if (!req.url.includes("/callback")) return false;
|
|
654
|
-
|
|
778
|
+
const state = new URL(req.url).searchParams.get("state");
|
|
779
|
+
const serverId = this.extractServerIdFromState(state);
|
|
780
|
+
if (!serverId) return false;
|
|
781
|
+
return this.getServersFromStorage().some((server) => server.id === serverId);
|
|
655
782
|
}
|
|
656
783
|
async handleCallbackRequest(req) {
|
|
657
784
|
const url = new URL(req.url);
|
|
658
|
-
const matchingServer = this.getServersFromStorage().find((server) => {
|
|
659
|
-
return server.callback_url && req.url.startsWith(server.callback_url);
|
|
660
|
-
});
|
|
661
|
-
if (!matchingServer) throw new Error(`No callback URI match found for the request url: ${req.url}. Was the request matched with \`isCallbackRequest()\`?`);
|
|
662
|
-
const serverId = matchingServer.id;
|
|
663
785
|
const code = url.searchParams.get("code");
|
|
664
786
|
const state = url.searchParams.get("state");
|
|
665
787
|
const error = url.searchParams.get("error");
|
|
666
788
|
const errorDescription = url.searchParams.get("error_description");
|
|
789
|
+
if (!state) throw new Error("Unauthorized: no state provided");
|
|
790
|
+
const serverId = this.extractServerIdFromState(state);
|
|
791
|
+
if (!serverId) throw new Error("No serverId found in state parameter. Expected format: {nonce}.{serverId}");
|
|
792
|
+
if (!this.getServersFromStorage().some((server) => server.id === serverId)) throw new Error(`No server found with id "${serverId}". Was the request matched with \`isCallbackRequest()\`?`);
|
|
793
|
+
if (this.mcpConnections[serverId] === void 0) throw new Error(`Could not find serverId: ${serverId}`);
|
|
794
|
+
const conn = this.mcpConnections[serverId];
|
|
795
|
+
if (!conn.options.transport.authProvider) throw new Error("Trying to finalize authentication for a server connection without an authProvider");
|
|
796
|
+
const authProvider = conn.options.transport.authProvider;
|
|
797
|
+
authProvider.serverId = serverId;
|
|
798
|
+
const stateValidation = await authProvider.checkState(state);
|
|
799
|
+
if (!stateValidation.valid) throw new Error(`Invalid state: ${stateValidation.error}`);
|
|
667
800
|
if (error) return {
|
|
668
801
|
serverId,
|
|
669
802
|
authSuccess: false,
|
|
670
803
|
authError: errorDescription || error
|
|
671
804
|
};
|
|
672
805
|
if (!code) throw new Error("Unauthorized: no code provided");
|
|
673
|
-
if (
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
if (!conn.options.transport.authProvider) throw new Error("Trying to finalize authentication for a server connection without an authProvider");
|
|
682
|
-
const clientId = conn.options.transport.authProvider.clientId || state;
|
|
683
|
-
conn.options.transport.authProvider.clientId = clientId;
|
|
684
|
-
conn.options.transport.authProvider.serverId = serverId;
|
|
806
|
+
if (this.mcpConnections[serverId].connectionState === MCPConnectionState.READY || this.mcpConnections[serverId].connectionState === MCPConnectionState.CONNECTED) {
|
|
807
|
+
this.clearServerAuthUrl(serverId);
|
|
808
|
+
return {
|
|
809
|
+
serverId,
|
|
810
|
+
authSuccess: true
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
if (this.mcpConnections[serverId].connectionState !== MCPConnectionState.AUTHENTICATING) throw new Error(`Failed to authenticate: the client is in "${this.mcpConnections[serverId].connectionState}" state, expected "authenticating"`);
|
|
685
814
|
try {
|
|
815
|
+
await authProvider.consumeState(state);
|
|
686
816
|
await conn.completeAuthorization(code);
|
|
817
|
+
await authProvider.deleteCodeVerifier();
|
|
687
818
|
this.clearServerAuthUrl(serverId);
|
|
688
819
|
this._onServerStateChanged.fire();
|
|
689
820
|
return {
|
|
690
821
|
serverId,
|
|
691
822
|
authSuccess: true
|
|
692
823
|
};
|
|
693
|
-
} catch (
|
|
694
|
-
const errorMessage =
|
|
824
|
+
} catch (authError) {
|
|
825
|
+
const errorMessage = authError instanceof Error ? authError.message : String(authError);
|
|
695
826
|
this._onServerStateChanged.fire();
|
|
696
827
|
return {
|
|
697
828
|
serverId,
|
|
@@ -701,8 +832,40 @@ var MCPClientManager = class {
|
|
|
701
832
|
}
|
|
702
833
|
}
|
|
703
834
|
/**
|
|
835
|
+
* Discover server capabilities if connection is in CONNECTED or READY state.
|
|
836
|
+
* Transitions to DISCOVERING then READY (or CONNECTED on error).
|
|
837
|
+
* Can be called to refresh server capabilities (e.g., from a UI refresh button).
|
|
838
|
+
*
|
|
839
|
+
* If called while a previous discovery is in-flight for the same server,
|
|
840
|
+
* the previous discovery will be aborted.
|
|
841
|
+
*
|
|
842
|
+
* @param serverId The server ID to discover
|
|
843
|
+
* @param options Optional configuration
|
|
844
|
+
* @param options.timeoutMs Timeout in milliseconds (default: 30000)
|
|
845
|
+
* @returns Result with current state and optional error, or undefined if connection not found
|
|
846
|
+
*/
|
|
847
|
+
async discoverIfConnected(serverId, options = {}) {
|
|
848
|
+
const conn = this.mcpConnections[serverId];
|
|
849
|
+
if (!conn) {
|
|
850
|
+
this._onObservabilityEvent.fire({
|
|
851
|
+
type: "mcp:client:discover",
|
|
852
|
+
displayMessage: `Connection not found for ${serverId}`,
|
|
853
|
+
payload: {},
|
|
854
|
+
timestamp: Date.now(),
|
|
855
|
+
id: nanoid()
|
|
856
|
+
});
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
const result = await conn.discover(options);
|
|
860
|
+
this._onServerStateChanged.fire();
|
|
861
|
+
return {
|
|
862
|
+
...result,
|
|
863
|
+
state: conn.connectionState
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
704
867
|
* Establish connection in the background after OAuth completion
|
|
705
|
-
* This method
|
|
868
|
+
* This method connects to the server and discovers its capabilities
|
|
706
869
|
* @param serverId The server ID to establish connection for
|
|
707
870
|
*/
|
|
708
871
|
async establishConnection(serverId) {
|
|
@@ -717,25 +880,34 @@ var MCPClientManager = class {
|
|
|
717
880
|
});
|
|
718
881
|
return;
|
|
719
882
|
}
|
|
720
|
-
|
|
721
|
-
await conn.establishConnection();
|
|
722
|
-
this._onServerStateChanged.fire();
|
|
723
|
-
} catch (error) {
|
|
724
|
-
const url = conn.url.toString();
|
|
883
|
+
if (conn.connectionState === MCPConnectionState.DISCOVERING || conn.connectionState === MCPConnectionState.READY) {
|
|
725
884
|
this._onObservabilityEvent.fire({
|
|
726
885
|
type: "mcp:client:connect",
|
|
727
|
-
displayMessage: `
|
|
886
|
+
displayMessage: `establishConnection skipped for ${serverId}, already in ${conn.connectionState} state`,
|
|
728
887
|
payload: {
|
|
729
|
-
url,
|
|
730
|
-
transport: conn.options.transport.type
|
|
731
|
-
state: conn.connectionState
|
|
732
|
-
error: toErrorMessage(error)
|
|
888
|
+
url: conn.url.toString(),
|
|
889
|
+
transport: conn.options.transport.type || "unknown",
|
|
890
|
+
state: conn.connectionState
|
|
733
891
|
},
|
|
734
892
|
timestamp: Date.now(),
|
|
735
893
|
id: nanoid()
|
|
736
894
|
});
|
|
737
|
-
|
|
895
|
+
return;
|
|
738
896
|
}
|
|
897
|
+
const connectResult = await this.connectToServer(serverId);
|
|
898
|
+
this._onServerStateChanged.fire();
|
|
899
|
+
if (connectResult.state === MCPConnectionState.CONNECTED) await this.discoverIfConnected(serverId);
|
|
900
|
+
this._onObservabilityEvent.fire({
|
|
901
|
+
type: "mcp:client:connect",
|
|
902
|
+
displayMessage: `establishConnection completed for ${serverId}, final state: ${conn.connectionState}`,
|
|
903
|
+
payload: {
|
|
904
|
+
url: conn.url.toString(),
|
|
905
|
+
transport: conn.options.transport.type || "unknown",
|
|
906
|
+
state: conn.connectionState
|
|
907
|
+
},
|
|
908
|
+
timestamp: Date.now(),
|
|
909
|
+
id: nanoid()
|
|
910
|
+
});
|
|
739
911
|
}
|
|
740
912
|
/**
|
|
741
913
|
* Configure OAuth callback handling
|
|
@@ -779,7 +951,7 @@ var MCPClientManager = class {
|
|
|
779
951
|
*/
|
|
780
952
|
getAITools() {
|
|
781
953
|
if (!this.jsonSchema) throw new Error("jsonSchema not initialized.");
|
|
782
|
-
for (const [id, conn] of Object.entries(this.mcpConnections)) if (conn.connectionState !==
|
|
954
|
+
for (const [id, conn] of Object.entries(this.mcpConnections)) if (conn.connectionState !== MCPConnectionState.READY && conn.connectionState !== MCPConnectionState.AUTHENTICATING) console.warn(`[getAITools] WARNING: Reading tools from connection ${id} in state "${conn.connectionState}". Tools may not be loaded yet.`);
|
|
783
955
|
return Object.fromEntries(getNamespacedData(this.mcpConnections, "tools").map((tool) => {
|
|
784
956
|
return [`tool_${tool.serverId.replace(/-/g, "")}_${tool.name}`, {
|
|
785
957
|
description: tool.description,
|
|
@@ -809,10 +981,18 @@ var MCPClientManager = class {
|
|
|
809
981
|
return this.getAITools();
|
|
810
982
|
}
|
|
811
983
|
/**
|
|
812
|
-
* Closes all connections to MCP servers
|
|
984
|
+
* Closes all active in-memory connections to MCP servers.
|
|
985
|
+
*
|
|
986
|
+
* Note: This only closes the transport connections - it does NOT remove
|
|
987
|
+
* servers from storage. Servers will still be listed and their callback
|
|
988
|
+
* URLs will still match incoming OAuth requests.
|
|
989
|
+
*
|
|
990
|
+
* Use removeServer() instead if you want to fully clean up a server
|
|
991
|
+
* (closes connection AND removes from storage).
|
|
813
992
|
*/
|
|
814
993
|
async closeAllConnections() {
|
|
815
994
|
const ids = Object.keys(this.mcpConnections);
|
|
995
|
+
for (const id of ids) this.mcpConnections[id].cancelDiscovery();
|
|
816
996
|
await Promise.all(ids.map(async (id) => {
|
|
817
997
|
await this.mcpConnections[id].client.close();
|
|
818
998
|
}));
|
|
@@ -829,6 +1009,7 @@ var MCPClientManager = class {
|
|
|
829
1009
|
*/
|
|
830
1010
|
async closeConnection(id) {
|
|
831
1011
|
if (!this.mcpConnections[id]) throw new Error(`Connection with id "${id}" does not exist.`);
|
|
1012
|
+
this.mcpConnections[id].cancelDiscovery();
|
|
832
1013
|
await this.mcpConnections[id].client.close();
|
|
833
1014
|
delete this.mcpConnections[id];
|
|
834
1015
|
const store = this._connectionDisposables.get(id);
|
|
@@ -836,9 +1017,12 @@ var MCPClientManager = class {
|
|
|
836
1017
|
this._connectionDisposables.delete(id);
|
|
837
1018
|
}
|
|
838
1019
|
/**
|
|
839
|
-
* Remove an MCP server from storage
|
|
1020
|
+
* Remove an MCP server - closes connection if active and removes from storage.
|
|
840
1021
|
*/
|
|
841
|
-
removeServer(serverId) {
|
|
1022
|
+
async removeServer(serverId) {
|
|
1023
|
+
if (this.mcpConnections[serverId]) try {
|
|
1024
|
+
await this.closeConnection(serverId);
|
|
1025
|
+
} catch (_e) {}
|
|
842
1026
|
this.removeServerFromStorage(serverId);
|
|
843
1027
|
this._onServerStateChanged.fire();
|
|
844
1028
|
}
|
|
@@ -917,5 +1101,5 @@ function getNamespacedData(mcpClients, type) {
|
|
|
917
1101
|
}
|
|
918
1102
|
|
|
919
1103
|
//#endregion
|
|
920
|
-
export { getNamespacedData as n,
|
|
921
|
-
//# sourceMappingURL=client-
|
|
1104
|
+
export { DisposableStore as i, getNamespacedData as n, MCPConnectionState as r, MCPClientManager as t };
|
|
1105
|
+
//# sourceMappingURL=client-QZa2Rq0l.js.map
|