agents 0.0.0-5ebaeb2 → 0.0.0-629836

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.
Files changed (62) hide show
  1. package/README.md +103 -5
  2. package/dist/_esm-LV5FJ3HK.js +3922 -0
  3. package/dist/_esm-LV5FJ3HK.js.map +1 -0
  4. package/dist/ai-chat-agent.d.ts +3 -1
  5. package/dist/ai-chat-agent.js +375 -58
  6. package/dist/ai-chat-agent.js.map +1 -1
  7. package/dist/ai-chat-v5-migration.js +1 -0
  8. package/dist/ai-react.d.ts +8 -1
  9. package/dist/ai-react.js +151 -111
  10. package/dist/ai-react.js.map +1 -1
  11. package/dist/ai-types.d.ts +1 -0
  12. package/dist/ai-types.js +2 -1
  13. package/dist/ccip-CMBYN64O.js +15 -0
  14. package/dist/ccip-CMBYN64O.js.map +1 -0
  15. package/dist/chunk-5Y6BEZDY.js +276 -0
  16. package/dist/chunk-5Y6BEZDY.js.map +1 -0
  17. package/dist/{chunk-AVYJQSLW.js → chunk-BER7KXUJ.js} +2 -1
  18. package/dist/chunk-BER7KXUJ.js.map +1 -0
  19. package/dist/{chunk-LL2AFX7V.js → chunk-C2OEBJZ2.js} +10 -6
  20. package/dist/chunk-C2OEBJZ2.js.map +1 -0
  21. package/dist/chunk-JJBFIGUC.js +5202 -0
  22. package/dist/chunk-JJBFIGUC.js.map +1 -0
  23. package/dist/chunk-PR4QN5HX.js +43 -0
  24. package/dist/chunk-PR4QN5HX.js.map +1 -0
  25. package/dist/chunk-TYAY6AU6.js +159 -0
  26. package/dist/chunk-TYAY6AU6.js.map +1 -0
  27. package/dist/{chunk-IJPBZOSS.js → chunk-XGMKNUJA.js} +97 -50
  28. package/dist/chunk-XGMKNUJA.js.map +1 -0
  29. package/dist/{chunk-VYENMKFS.js → chunk-ZMMHNOMZ.js} +400 -70
  30. package/dist/chunk-ZMMHNOMZ.js.map +1 -0
  31. package/dist/{client-CcIORE73.d.ts → client-C8tswVoM.d.ts} +891 -250
  32. package/dist/client.js +2 -1
  33. package/dist/codemode/ai.d.ts +25 -0
  34. package/dist/codemode/ai.js +5200 -0
  35. package/dist/codemode/ai.js.map +1 -0
  36. package/dist/index.d.ts +25 -32
  37. package/dist/index.js +5 -4
  38. package/dist/mcp/client.d.ts +2 -1
  39. package/dist/mcp/client.js +2 -1
  40. package/dist/mcp/do-oauth-client-provider.js +2 -1
  41. package/dist/mcp/index.d.ts +16 -34
  42. package/dist/mcp/index.js +253 -183
  43. package/dist/mcp/index.js.map +1 -1
  44. package/dist/mcp/x402.d.ts +39 -0
  45. package/dist/mcp/x402.js +3195 -0
  46. package/dist/mcp/x402.js.map +1 -0
  47. package/dist/mcp-BH1fJeiU.d.ts +58 -0
  48. package/dist/observability/index.d.ts +12 -24
  49. package/dist/observability/index.js +5 -4
  50. package/dist/react.d.ts +10 -6
  51. package/dist/react.js +101 -3
  52. package/dist/react.js.map +1 -1
  53. package/dist/schedule.js +2 -0
  54. package/dist/schedule.js.map +1 -1
  55. package/dist/secp256k1-M22GZP2U.js +2193 -0
  56. package/dist/secp256k1-M22GZP2U.js.map +1 -0
  57. package/package.json +27 -10
  58. package/src/index.ts +141 -57
  59. package/dist/chunk-AVYJQSLW.js.map +0 -1
  60. package/dist/chunk-IJPBZOSS.js.map +0 -1
  61. package/dist/chunk-LL2AFX7V.js.map +0 -1
  62. package/dist/chunk-VYENMKFS.js.map +0 -1
@@ -1,15 +1,72 @@
1
1
  // src/mcp/client.ts
2
2
  import { jsonSchema } from "ai";
3
- import { nanoid } from "nanoid";
3
+ import { nanoid as nanoid2 } from "nanoid";
4
+
5
+ // src/core/events.ts
6
+ function toDisposable(fn) {
7
+ return { dispose: fn };
8
+ }
9
+ var DisposableStore = class {
10
+ constructor() {
11
+ this._items = [];
12
+ }
13
+ add(d) {
14
+ this._items.push(d);
15
+ return d;
16
+ }
17
+ dispose() {
18
+ while (this._items.length) {
19
+ try {
20
+ this._items.pop().dispose();
21
+ } catch {
22
+ }
23
+ }
24
+ }
25
+ };
26
+ var Emitter = class {
27
+ constructor() {
28
+ this._listeners = /* @__PURE__ */ new Set();
29
+ this.event = (listener) => {
30
+ this._listeners.add(listener);
31
+ return toDisposable(() => this._listeners.delete(listener));
32
+ };
33
+ }
34
+ fire(data) {
35
+ for (const listener of [...this._listeners]) {
36
+ try {
37
+ listener(data);
38
+ } catch (err) {
39
+ console.error("Emitter listener error:", err);
40
+ }
41
+ }
42
+ }
43
+ dispose() {
44
+ this._listeners.clear();
45
+ }
46
+ };
4
47
 
5
48
  // src/mcp/client-connection.ts
6
49
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
7
50
  import {
51
+ ElicitRequestSchema,
8
52
  PromptListChangedNotificationSchema,
9
53
  ResourceListChangedNotificationSchema,
10
- ToolListChangedNotificationSchema,
11
- ElicitRequestSchema
54
+ ToolListChangedNotificationSchema
12
55
  } from "@modelcontextprotocol/sdk/types.js";
56
+ import { nanoid } from "nanoid";
57
+
58
+ // src/mcp/errors.ts
59
+ function toErrorMessage(error) {
60
+ return error instanceof Error ? error.message : String(error);
61
+ }
62
+ function isUnauthorized(error) {
63
+ const msg = toErrorMessage(error);
64
+ return msg.includes("Unauthorized") || msg.includes("401");
65
+ }
66
+ function isTransportNotImplemented(error) {
67
+ const msg = toErrorMessage(error);
68
+ return msg.includes("404") || msg.includes("405") || msg.includes("Not Implemented") || msg.includes("not implemented");
69
+ }
13
70
 
14
71
  // src/mcp/sse-edge.ts
15
72
  import {
@@ -118,6 +175,8 @@ var MCPClientConnection = class {
118
175
  this.prompts = [];
119
176
  this.resources = [];
120
177
  this.resourceTemplates = [];
178
+ this._onObservabilityEvent = new Emitter();
179
+ this.onObservabilityEvent = this._onObservabilityEvent.event;
121
180
  const clientOptions = {
122
181
  ...options.client,
123
182
  capabilities: {
@@ -130,23 +189,112 @@ var MCPClientConnection = class {
130
189
  /**
131
190
  * Initialize a client connection
132
191
  *
133
- * @param code Optional OAuth code to initialize the connection with if auth hasn't been initialized
134
192
  * @returns
135
193
  */
136
- async init(code) {
194
+ async init() {
195
+ const transportType = this.options.transport.type;
196
+ if (!transportType) {
197
+ throw new Error("Transport type must be specified");
198
+ }
137
199
  try {
138
- const transportType = this.options.transport.type || "streamable-http";
139
- await this.tryConnect(transportType, code);
200
+ await this.tryConnect(transportType);
140
201
  } catch (e) {
141
- if (e.toString().includes("Unauthorized")) {
202
+ if (isUnauthorized(e)) {
142
203
  this.connectionState = "authenticating";
143
204
  return;
144
205
  }
206
+ this._onObservabilityEvent.fire({
207
+ type: "mcp:client:connect",
208
+ displayMessage: `Connection initialization failed for ${this.url.toString()}`,
209
+ payload: {
210
+ url: this.url.toString(),
211
+ transport: transportType,
212
+ state: this.connectionState,
213
+ error: toErrorMessage(e)
214
+ },
215
+ timestamp: Date.now(),
216
+ id: nanoid()
217
+ });
145
218
  this.connectionState = "failed";
219
+ return;
220
+ }
221
+ await this.discoverAndRegister();
222
+ }
223
+ /**
224
+ * Finish OAuth by probing transports based on configured type.
225
+ * - Explicit: finish on that transport
226
+ * - Auto: try streamable-http, then sse on 404/405/Not Implemented
227
+ */
228
+ async finishAuthProbe(code) {
229
+ if (!this.options.transport.authProvider) {
230
+ throw new Error("No auth provider configured");
231
+ }
232
+ const configuredType = this.options.transport.type;
233
+ if (!configuredType) {
234
+ throw new Error("Transport type must be specified");
235
+ }
236
+ const finishAuth = async (base) => {
237
+ const transport = this.getTransport(base);
238
+ await transport.finishAuth(code);
239
+ };
240
+ if (configuredType === "sse" || configuredType === "streamable-http") {
241
+ await finishAuth(configuredType);
242
+ return;
243
+ }
244
+ try {
245
+ await finishAuth("streamable-http");
246
+ } catch (e) {
247
+ if (isTransportNotImplemented(e)) {
248
+ await finishAuth("sse");
249
+ return;
250
+ }
146
251
  throw e;
147
252
  }
253
+ }
254
+ /**
255
+ * Complete OAuth authorization
256
+ */
257
+ async completeAuthorization(code) {
258
+ if (this.connectionState !== "authenticating") {
259
+ throw new Error(
260
+ "Connection must be in authenticating state to complete authorization"
261
+ );
262
+ }
263
+ try {
264
+ await this.finishAuthProbe(code);
265
+ this.connectionState = "connecting";
266
+ } catch (error) {
267
+ this.connectionState = "failed";
268
+ throw error;
269
+ }
270
+ }
271
+ /**
272
+ * Establish connection after successful authorization
273
+ */
274
+ async establishConnection() {
275
+ if (this.connectionState !== "connecting") {
276
+ throw new Error(
277
+ "Connection must be in connecting state to establish connection"
278
+ );
279
+ }
280
+ try {
281
+ const transportType = this.options.transport.type;
282
+ if (!transportType) {
283
+ throw new Error("Transport type must be specified");
284
+ }
285
+ await this.tryConnect(transportType);
286
+ await this.discoverAndRegister();
287
+ } catch (error) {
288
+ this.connectionState = "failed";
289
+ throw error;
290
+ }
291
+ }
292
+ /**
293
+ * Discover server capabilities and register tools, resources, prompts, and templates
294
+ */
295
+ async discoverAndRegister() {
148
296
  this.connectionState = "discovering";
149
- this.serverCapabilities = await this.client.getServerCapabilities();
297
+ this.serverCapabilities = this.client.getServerCapabilities();
150
298
  if (!this.serverCapabilities) {
151
299
  throw new Error("The MCP Server failed to return server capabilities");
152
300
  }
@@ -172,7 +320,18 @@ var MCPClientConnection = class {
172
320
  ];
173
321
  for (const { name, result } of operations) {
174
322
  if (result.status === "rejected") {
175
- console.error(`Failed to initialize ${name}:`, result.reason);
323
+ const url = this.url.toString();
324
+ this._onObservabilityEvent.fire({
325
+ type: "mcp:client:discover",
326
+ displayMessage: `Failed to discover ${name} for ${url}`,
327
+ payload: {
328
+ url,
329
+ capability: name,
330
+ error: result.reason
331
+ },
332
+ timestamp: Date.now(),
333
+ id: nanoid()
334
+ });
176
335
  }
177
336
  }
178
337
  this.instructions = instructionsResult.status === "fulfilled" ? instructionsResult.value : void 0;
@@ -239,7 +398,7 @@ var MCPClientConnection = class {
239
398
  do {
240
399
  toolsResult = await this.client.listTools({
241
400
  cursor: toolsResult.nextCursor
242
- }).catch(capabilityErrorHandler({ tools: [] }, "tools/list"));
401
+ }).catch(this._capabilityErrorHandler({ tools: [] }, "tools/list"));
243
402
  toolsAgg = toolsAgg.concat(toolsResult.tools);
244
403
  } while (toolsResult.nextCursor);
245
404
  return toolsAgg;
@@ -250,7 +409,9 @@ var MCPClientConnection = class {
250
409
  do {
251
410
  resourcesResult = await this.client.listResources({
252
411
  cursor: resourcesResult.nextCursor
253
- }).catch(capabilityErrorHandler({ resources: [] }, "resources/list"));
412
+ }).catch(
413
+ this._capabilityErrorHandler({ resources: [] }, "resources/list")
414
+ );
254
415
  resourcesAgg = resourcesAgg.concat(resourcesResult.resources);
255
416
  } while (resourcesResult.nextCursor);
256
417
  return resourcesAgg;
@@ -261,7 +422,7 @@ var MCPClientConnection = class {
261
422
  do {
262
423
  promptsResult = await this.client.listPrompts({
263
424
  cursor: promptsResult.nextCursor
264
- }).catch(capabilityErrorHandler({ prompts: [] }, "prompts/list"));
425
+ }).catch(this._capabilityErrorHandler({ prompts: [] }, "prompts/list"));
265
426
  promptsAgg = promptsAgg.concat(promptsResult.prompts);
266
427
  } while (promptsResult.nextCursor);
267
428
  return promptsAgg;
@@ -275,7 +436,7 @@ var MCPClientConnection = class {
275
436
  templatesResult = await this.client.listResourceTemplates({
276
437
  cursor: templatesResult.nextCursor
277
438
  }).catch(
278
- capabilityErrorHandler(
439
+ this._capabilityErrorHandler(
279
440
  { resourceTemplates: [] },
280
441
  "resources/templates/list"
281
442
  )
@@ -314,21 +475,46 @@ var MCPClientConnection = class {
314
475
  throw new Error(`Unsupported transport type: ${transportType}`);
315
476
  }
316
477
  }
317
- async tryConnect(transportType, code) {
478
+ async tryConnect(transportType) {
318
479
  const transports = transportType === "auto" ? ["streamable-http", "sse"] : [transportType];
319
480
  for (const currentTransportType of transports) {
320
481
  const isLastTransport = currentTransportType === transports[transports.length - 1];
321
482
  const hasFallback = transportType === "auto" && currentTransportType === "streamable-http" && !isLastTransport;
322
- const transport = await this.getTransport(currentTransportType);
323
- if (code) {
324
- await transport.finishAuth(code);
325
- }
483
+ const transport = this.getTransport(currentTransportType);
326
484
  try {
327
485
  await this.client.connect(transport);
486
+ this.lastConnectedTransport = currentTransportType;
487
+ const url = this.url.toString();
488
+ this._onObservabilityEvent.fire({
489
+ type: "mcp:client:connect",
490
+ displayMessage: `Connected successfully using ${currentTransportType} transport for ${url}`,
491
+ payload: {
492
+ url,
493
+ transport: currentTransportType,
494
+ state: this.connectionState
495
+ },
496
+ timestamp: Date.now(),
497
+ id: nanoid()
498
+ });
328
499
  break;
329
500
  } catch (e) {
330
501
  const error = e instanceof Error ? e : new Error(String(e));
331
- if (hasFallback && (error.message.includes("404") || error.message.includes("405"))) {
502
+ if (isUnauthorized(error)) {
503
+ throw e;
504
+ }
505
+ if (hasFallback && isTransportNotImplemented(error)) {
506
+ const url = this.url.toString();
507
+ this._onObservabilityEvent.fire({
508
+ type: "mcp:client:connect",
509
+ displayMessage: `${currentTransportType} transport not available, trying ${transports[transports.indexOf(currentTransportType) + 1]} for ${url}`,
510
+ payload: {
511
+ url,
512
+ transport: currentTransportType,
513
+ state: this.connectionState
514
+ },
515
+ timestamp: Date.now(),
516
+ id: nanoid()
517
+ });
332
518
  continue;
333
519
  }
334
520
  throw e;
@@ -341,18 +527,27 @@ var MCPClientConnection = class {
341
527
  }
342
528
  );
343
529
  }
530
+ _capabilityErrorHandler(empty, method) {
531
+ return (e) => {
532
+ if (e.code === -32601) {
533
+ const url = this.url.toString();
534
+ this._onObservabilityEvent.fire({
535
+ type: "mcp:client:discover",
536
+ displayMessage: `The server advertised support for the capability ${method.split("/")[0]}, but returned "Method not found" for '${method}' for ${url}`,
537
+ payload: {
538
+ url,
539
+ capability: method.split("/")[0],
540
+ error: toErrorMessage(e)
541
+ },
542
+ timestamp: Date.now(),
543
+ id: nanoid()
544
+ });
545
+ return empty;
546
+ }
547
+ throw e;
548
+ };
549
+ }
344
550
  };
345
- function capabilityErrorHandler(empty, method) {
346
- return (e) => {
347
- if (e.code === -32601) {
348
- console.error(
349
- `The server advertised support for the capability ${method.split("/")[0]}, but returned "Method not found" for '${method}'.`
350
- );
351
- return empty;
352
- }
353
- throw e;
354
- };
355
- }
356
551
 
357
552
  // src/mcp/client.ts
358
553
  var MCPClientManager = class {
@@ -367,6 +562,11 @@ var MCPClientManager = class {
367
562
  this.mcpConnections = {};
368
563
  this._callbackUrls = [];
369
564
  this._didWarnAboutUnstableGetAITools = false;
565
+ this._connectionDisposables = /* @__PURE__ */ new Map();
566
+ this._onObservabilityEvent = new Emitter();
567
+ this.onObservabilityEvent = this._onObservabilityEvent.event;
568
+ this._onConnected = new Emitter();
569
+ this.onConnected = this._onConnected.event;
370
570
  }
371
571
  /**
372
572
  * Connect to and register an MCP server
@@ -376,31 +576,64 @@ var MCPClientManager = class {
376
576
  * @param capabilities Client capabilities (i.e. if the client supports roots/sampling)
377
577
  */
378
578
  async connect(url, options = {}) {
379
- const id = options.reconnect?.id ?? nanoid(8);
380
- if (!options.transport?.authProvider) {
381
- console.warn(
382
- "No authProvider provided in the transport options. This client will only support unauthenticated remote MCP Servers"
383
- );
384
- } else {
579
+ const id = options.reconnect?.id ?? nanoid2(8);
580
+ if (options.transport?.authProvider) {
385
581
  options.transport.authProvider.serverId = id;
386
582
  if (options.reconnect?.oauthClientId) {
387
583
  options.transport.authProvider.clientId = options.reconnect?.oauthClientId;
388
584
  }
389
585
  }
390
- this.mcpConnections[id] = new MCPClientConnection(
391
- new URL(url),
392
- {
393
- name: this._name,
394
- version: this._version
395
- },
396
- {
397
- client: options.client ?? {},
398
- transport: options.transport ?? {}
586
+ if (!options.reconnect?.oauthCode || !this.mcpConnections[id]) {
587
+ const normalizedTransport = {
588
+ ...options.transport,
589
+ type: options.transport?.type ?? "auto"
590
+ };
591
+ this.mcpConnections[id] = new MCPClientConnection(
592
+ new URL(url),
593
+ {
594
+ name: this._name,
595
+ version: this._version
596
+ },
597
+ {
598
+ client: options.client ?? {},
599
+ transport: normalizedTransport
600
+ }
601
+ );
602
+ const store = new DisposableStore();
603
+ const existing = this._connectionDisposables.get(id);
604
+ if (existing) existing.dispose();
605
+ this._connectionDisposables.set(id, store);
606
+ store.add(
607
+ this.mcpConnections[id].onObservabilityEvent((event) => {
608
+ this._onObservabilityEvent.fire(event);
609
+ })
610
+ );
611
+ }
612
+ await this.mcpConnections[id].init();
613
+ if (options.reconnect?.oauthCode) {
614
+ try {
615
+ await this.mcpConnections[id].completeAuthorization(
616
+ options.reconnect.oauthCode
617
+ );
618
+ await this.mcpConnections[id].establishConnection();
619
+ } catch (error) {
620
+ this._onObservabilityEvent.fire({
621
+ type: "mcp:client:connect",
622
+ displayMessage: `Failed to complete OAuth reconnection for ${id} for ${url}`,
623
+ payload: {
624
+ url,
625
+ transport: options.transport?.type ?? "auto",
626
+ state: this.mcpConnections[id].connectionState,
627
+ error: toErrorMessage(error)
628
+ },
629
+ timestamp: Date.now(),
630
+ id
631
+ });
632
+ throw error;
399
633
  }
400
- );
401
- await this.mcpConnections[id].init(options.reconnect?.oauthCode);
634
+ }
402
635
  const authUrl = options.transport?.authProvider?.authUrl;
403
- if (authUrl && options.transport?.authProvider?.redirectUrl) {
636
+ if (this.mcpConnections[id].connectionState === "authenticating" && authUrl && options.transport?.authProvider?.redirectUrl) {
404
637
  this._callbackUrls.push(
405
638
  options.transport.authProvider.redirectUrl.toString()
406
639
  );
@@ -430,13 +663,13 @@ var MCPClientManager = class {
430
663
  );
431
664
  }
432
665
  const code = url.searchParams.get("code");
433
- const clientId = url.searchParams.get("state");
666
+ const state = url.searchParams.get("state");
434
667
  const urlParams = urlMatch.split("/");
435
668
  const serverId = urlParams[urlParams.length - 1];
436
669
  if (!code) {
437
670
  throw new Error("Unauthorized: no code provided");
438
671
  }
439
- if (!clientId) {
672
+ if (!state) {
440
673
  throw new Error("Unauthorized: no state provided");
441
674
  }
442
675
  if (this.mcpConnections[serverId] === void 0) {
@@ -453,21 +686,91 @@ var MCPClientManager = class {
453
686
  "Trying to finalize authentication for a server connection without an authProvider"
454
687
  );
455
688
  }
689
+ const clientId = conn.options.transport.authProvider.clientId || state;
456
690
  conn.options.transport.authProvider.clientId = clientId;
457
691
  conn.options.transport.authProvider.serverId = serverId;
458
- const serverUrl = conn.url.toString();
459
- await this.connect(serverUrl, {
460
- reconnect: {
461
- id: serverId,
462
- oauthClientId: clientId,
463
- oauthCode: code
464
- },
465
- ...conn.options
466
- });
467
- if (this.mcpConnections[serverId].connectionState === "authenticating") {
468
- throw new Error("Failed to authenticate: client failed to initialize");
692
+ try {
693
+ await conn.completeAuthorization(code);
694
+ return {
695
+ serverId,
696
+ authSuccess: true
697
+ };
698
+ } catch (error) {
699
+ const errorMessage = error instanceof Error ? error.message : String(error);
700
+ return {
701
+ serverId,
702
+ authSuccess: false,
703
+ authError: errorMessage
704
+ };
469
705
  }
470
- return { serverId };
706
+ }
707
+ /**
708
+ * Establish connection in the background after OAuth completion
709
+ * This method is called asynchronously and doesn't block the OAuth callback response
710
+ * @param serverId The server ID to establish connection for
711
+ */
712
+ async establishConnection(serverId) {
713
+ const conn = this.mcpConnections[serverId];
714
+ if (!conn) {
715
+ this._onObservabilityEvent.fire({
716
+ type: "mcp:client:preconnect",
717
+ displayMessage: `Connection not found for serverId: ${serverId}`,
718
+ payload: { serverId },
719
+ timestamp: Date.now(),
720
+ id: nanoid2()
721
+ });
722
+ return;
723
+ }
724
+ try {
725
+ await conn.establishConnection();
726
+ this._onConnected.fire(serverId);
727
+ } catch (error) {
728
+ const url = conn.url.toString();
729
+ this._onObservabilityEvent.fire({
730
+ type: "mcp:client:connect",
731
+ displayMessage: `Failed to establish connection to server ${serverId} with url ${url}`,
732
+ payload: {
733
+ url,
734
+ transport: conn.options.transport.type ?? "auto",
735
+ state: conn.connectionState,
736
+ error: toErrorMessage(error)
737
+ },
738
+ timestamp: Date.now(),
739
+ id: nanoid2()
740
+ });
741
+ }
742
+ }
743
+ /**
744
+ * Register a callback URL for OAuth handling
745
+ * @param url The callback URL to register
746
+ */
747
+ registerCallbackUrl(url) {
748
+ if (!this._callbackUrls.includes(url)) {
749
+ this._callbackUrls.push(url);
750
+ }
751
+ }
752
+ /**
753
+ * Unregister a callback URL
754
+ * @param serverId The server ID whose callback URL should be removed
755
+ */
756
+ unregisterCallbackUrl(serverId) {
757
+ this._callbackUrls = this._callbackUrls.filter(
758
+ (url) => !url.endsWith(`/${serverId}`)
759
+ );
760
+ }
761
+ /**
762
+ * Configure OAuth callback handling
763
+ * @param config OAuth callback configuration
764
+ */
765
+ configureOAuthCallback(config) {
766
+ this._oauthCallbackConfig = config;
767
+ }
768
+ /**
769
+ * Get the current OAuth callback configuration
770
+ * @returns The current OAuth callback configuration
771
+ */
772
+ getOAuthCallbackConfig() {
773
+ return this._oauthCallbackConfig;
471
774
  }
472
775
  /**
473
776
  * @returns namespaced list of tools
@@ -482,7 +785,7 @@ var MCPClientManager = class {
482
785
  return Object.fromEntries(
483
786
  getNamespacedData(this.mcpConnections, "tools").map((tool) => {
484
787
  return [
485
- `tool_${tool.serverId}_${tool.name}`,
788
+ `tool_${tool.serverId.replace(/-/g, "")}_${tool.name}`,
486
789
  {
487
790
  description: tool.description,
488
791
  execute: async (args) => {
@@ -496,7 +799,12 @@ var MCPClientManager = class {
496
799
  }
497
800
  return result;
498
801
  },
499
- inputSchema: jsonSchema(tool.inputSchema)
802
+ // @ts-expect-error drift between ai and mcp types
803
+ inputSchema: jsonSchema(tool.inputSchema),
804
+ outputSchema: tool.outputSchema ? (
805
+ // @ts-expect-error drift between ai and mcp types
806
+ jsonSchema(tool.outputSchema)
807
+ ) : void 0
500
808
  }
501
809
  ];
502
810
  })
@@ -519,11 +827,18 @@ var MCPClientManager = class {
519
827
  * Closes all connections to MCP servers
520
828
  */
521
829
  async closeAllConnections() {
522
- return Promise.all(
523
- Object.values(this.mcpConnections).map(async (connection) => {
524
- await connection.client.close();
830
+ const ids = Object.keys(this.mcpConnections);
831
+ await Promise.all(
832
+ ids.map(async (id) => {
833
+ await this.mcpConnections[id].client.close();
525
834
  })
526
835
  );
836
+ for (const id of ids) {
837
+ const store = this._connectionDisposables.get(id);
838
+ if (store) store.dispose();
839
+ this._connectionDisposables.delete(id);
840
+ delete this.mcpConnections[id];
841
+ }
527
842
  }
528
843
  /**
529
844
  * Closes a connection to an MCP server
@@ -535,6 +850,20 @@ var MCPClientManager = class {
535
850
  }
536
851
  await this.mcpConnections[id].client.close();
537
852
  delete this.mcpConnections[id];
853
+ const store = this._connectionDisposables.get(id);
854
+ if (store) store.dispose();
855
+ this._connectionDisposables.delete(id);
856
+ }
857
+ /**
858
+ * Dispose the manager and all resources.
859
+ */
860
+ async dispose() {
861
+ try {
862
+ await this.closeAllConnections();
863
+ } finally {
864
+ this._onConnected.dispose();
865
+ this._onObservabilityEvent.dispose();
866
+ }
538
867
  }
539
868
  /**
540
869
  * @returns namespaced list of prompts
@@ -557,7 +886,7 @@ var MCPClientManager = class {
557
886
  /**
558
887
  * Namespaced version of callTool
559
888
  */
560
- callTool(params, resultSchema, options) {
889
+ async callTool(params, resultSchema, options) {
561
890
  const unqualifiedName = params.name.replace(`${params.serverId}.`, "");
562
891
  return this.mcpConnections[params.serverId].client.callTool(
563
892
  {
@@ -604,9 +933,10 @@ function getNamespacedData(mcpClients, type) {
604
933
  }
605
934
 
606
935
  export {
936
+ DisposableStore,
607
937
  SSEEdgeClientTransport,
608
938
  StreamableHTTPEdgeClientTransport,
609
939
  MCPClientManager,
610
940
  getNamespacedData
611
941
  };
612
- //# sourceMappingURL=chunk-VYENMKFS.js.map
942
+ //# sourceMappingURL=chunk-ZMMHNOMZ.js.map