agents 0.2.10 → 0.2.12

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 (94) hide show
  1. package/dist/ai-chat-agent.d.ts +15 -18
  2. package/dist/ai-chat-agent.js +528 -675
  3. package/dist/ai-chat-agent.js.map +1 -1
  4. package/dist/ai-chat-v5-migration-gdyLiTd8.js +155 -0
  5. package/dist/ai-chat-v5-migration-gdyLiTd8.js.map +1 -0
  6. package/dist/ai-chat-v5-migration.d.ts +7 -4
  7. package/dist/ai-chat-v5-migration.js +3 -20
  8. package/dist/ai-react.d.ts +14 -24
  9. package/dist/ai-react.js +257 -343
  10. package/dist/ai-react.js.map +1 -1
  11. package/dist/ai-types-BWW4umHY.d.ts +95 -0
  12. package/dist/ai-types-UZlfLOYP.js +20 -0
  13. package/dist/ai-types-UZlfLOYP.js.map +1 -0
  14. package/dist/ai-types.d.ts +6 -92
  15. package/dist/ai-types.js +3 -8
  16. package/dist/client-CZBVDDoO.js +786 -0
  17. package/dist/client-CZBVDDoO.js.map +1 -0
  18. package/dist/client-CmMi85Sj.d.ts +104 -0
  19. package/dist/client-CrWcaPgn.d.ts +5313 -0
  20. package/dist/client-DjR-lC16.js +117 -0
  21. package/dist/client-DjR-lC16.js.map +1 -0
  22. package/dist/client.d.ts +11 -92
  23. package/dist/client.js +4 -13
  24. package/dist/codemode/ai.d.ts +19 -17
  25. package/dist/codemode/ai.js +90 -5139
  26. package/dist/codemode/ai.js.map +1 -1
  27. package/dist/do-oauth-client-provider-B2jr6UNq.js +93 -0
  28. package/dist/do-oauth-client-provider-B2jr6UNq.js.map +1 -0
  29. package/dist/do-oauth-client-provider-CCwGwnrA.d.ts +55 -0
  30. package/dist/index-Daqy_D9E.d.ts +558 -0
  31. package/dist/index-W4JUkafc.d.ts +54 -0
  32. package/dist/index.d.ts +55 -542
  33. package/dist/index.js +7 -32
  34. package/dist/mcp/client.d.ts +4 -12
  35. package/dist/mcp/client.js +3 -10
  36. package/dist/mcp/do-oauth-client-provider.d.ts +2 -42
  37. package/dist/mcp/do-oauth-client-provider.js +3 -8
  38. package/dist/mcp/index.d.ts +72 -76
  39. package/dist/mcp/index.js +830 -1098
  40. package/dist/mcp/index.js.map +1 -1
  41. package/dist/mcp/x402.d.ts +22 -27
  42. package/dist/mcp/x402.js +186 -3187
  43. package/dist/mcp/x402.js.map +1 -1
  44. package/dist/{mcp-BH1fJeiU.d.ts → mcp-BEwaCsxO.d.ts} +6 -3
  45. package/dist/observability/index.d.ts +3 -34
  46. package/dist/observability/index.js +7 -12
  47. package/dist/react-Cl4ZPPhW.d.ts +113 -0
  48. package/dist/react.d.ts +10 -127
  49. package/dist/react.js +173 -200
  50. package/dist/react.js.map +1 -1
  51. package/dist/schedule.d.ts +13 -10
  52. package/dist/schedule.js +43 -33
  53. package/dist/schedule.js.map +1 -1
  54. package/dist/serializable-gtr9YMhp.d.ts +34 -0
  55. package/dist/serializable.d.ts +7 -32
  56. package/dist/serializable.js +1 -1
  57. package/dist/src-COfG--3R.js +1179 -0
  58. package/dist/src-COfG--3R.js.map +1 -0
  59. package/package.json +9 -3
  60. package/dist/_esm-LV5FJ3HK.js +0 -3922
  61. package/dist/_esm-LV5FJ3HK.js.map +0 -1
  62. package/dist/ai-chat-v5-migration.js.map +0 -1
  63. package/dist/ai-types.js.map +0 -1
  64. package/dist/ccip-CMBYN64O.js +0 -15
  65. package/dist/ccip-CMBYN64O.js.map +0 -1
  66. package/dist/chunk-2Y6KNRNP.js +0 -1343
  67. package/dist/chunk-2Y6KNRNP.js.map +0 -1
  68. package/dist/chunk-5Y6BEZDY.js +0 -276
  69. package/dist/chunk-5Y6BEZDY.js.map +0 -1
  70. package/dist/chunk-BER7KXUJ.js +0 -18
  71. package/dist/chunk-BER7KXUJ.js.map +0 -1
  72. package/dist/chunk-C2OEBJZ2.js +0 -113
  73. package/dist/chunk-C2OEBJZ2.js.map +0 -1
  74. package/dist/chunk-JJBFIGUC.js +0 -5202
  75. package/dist/chunk-JJBFIGUC.js.map +0 -1
  76. package/dist/chunk-PR4QN5HX.js +0 -43
  77. package/dist/chunk-PR4QN5HX.js.map +0 -1
  78. package/dist/chunk-QEVM4BVL.js +0 -116
  79. package/dist/chunk-QEVM4BVL.js.map +0 -1
  80. package/dist/chunk-QUOGV3WN.js +0 -949
  81. package/dist/chunk-QUOGV3WN.js.map +0 -1
  82. package/dist/chunk-TYAY6AU6.js +0 -159
  83. package/dist/chunk-TYAY6AU6.js.map +0 -1
  84. package/dist/chunk-UJVEAURM.js +0 -150
  85. package/dist/chunk-UJVEAURM.js.map +0 -1
  86. package/dist/client-C8tswVoM.d.ts +0 -5248
  87. package/dist/client.js.map +0 -1
  88. package/dist/index.js.map +0 -1
  89. package/dist/mcp/client.js.map +0 -1
  90. package/dist/mcp/do-oauth-client-provider.js.map +0 -1
  91. package/dist/observability/index.js.map +0 -1
  92. package/dist/secp256k1-M22GZP2U.js +0 -2193
  93. package/dist/secp256k1-M22GZP2U.js.map +0 -1
  94. package/dist/serializable.js.map +0 -1
@@ -0,0 +1,786 @@
1
+ import { nanoid } from "nanoid";
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+ import { ElicitRequestSchema, PromptListChangedNotificationSchema, ResourceListChangedNotificationSchema, ToolListChangedNotificationSchema } from "@modelcontextprotocol/sdk/types.js";
4
+ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
5
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
6
+
7
+ //#region src/core/events.ts
8
+ function toDisposable(fn) {
9
+ return { dispose: fn };
10
+ }
11
+ var DisposableStore = class {
12
+ constructor() {
13
+ this._items = [];
14
+ }
15
+ add(d) {
16
+ this._items.push(d);
17
+ return d;
18
+ }
19
+ dispose() {
20
+ while (this._items.length) try {
21
+ this._items.pop().dispose();
22
+ } catch {}
23
+ }
24
+ };
25
+ var Emitter = class {
26
+ constructor() {
27
+ this._listeners = /* @__PURE__ */ new Set();
28
+ this.event = (listener) => {
29
+ this._listeners.add(listener);
30
+ return toDisposable(() => this._listeners.delete(listener));
31
+ };
32
+ }
33
+ fire(data) {
34
+ for (const listener of [...this._listeners]) try {
35
+ listener(data);
36
+ } catch (err) {
37
+ console.error("Emitter listener error:", err);
38
+ }
39
+ }
40
+ dispose() {
41
+ this._listeners.clear();
42
+ }
43
+ };
44
+
45
+ //#endregion
46
+ //#region src/mcp/errors.ts
47
+ function toErrorMessage(error) {
48
+ return error instanceof Error ? error.message : String(error);
49
+ }
50
+ function isUnauthorized(error) {
51
+ const msg = toErrorMessage(error);
52
+ return msg.includes("Unauthorized") || msg.includes("401");
53
+ }
54
+ function isTransportNotImplemented(error) {
55
+ const msg = toErrorMessage(error);
56
+ return msg.includes("404") || msg.includes("405") || msg.includes("Not Implemented") || msg.includes("not implemented");
57
+ }
58
+
59
+ //#endregion
60
+ //#region src/mcp/sse-edge.ts
61
+ var SSEEdgeClientTransport = class extends SSEClientTransport {
62
+ /**
63
+ * Creates a new EdgeSSEClientTransport, which overrides fetch to be compatible with the CF workers environment
64
+ */
65
+ constructor(url, options) {
66
+ const fetchOverride = async (fetchUrl, fetchInit = {}) => {
67
+ const headers = await this.authHeaders();
68
+ const workerOptions = {
69
+ ...fetchInit,
70
+ headers: {
71
+ ...options.requestInit?.headers,
72
+ ...fetchInit?.headers,
73
+ ...headers
74
+ }
75
+ };
76
+ delete workerOptions.mode;
77
+ return options.eventSourceInit?.fetch?.(fetchUrl, workerOptions) || fetch(fetchUrl, workerOptions);
78
+ };
79
+ super(url, {
80
+ ...options,
81
+ eventSourceInit: {
82
+ ...options.eventSourceInit,
83
+ fetch: fetchOverride
84
+ }
85
+ });
86
+ this.authProvider = options.authProvider;
87
+ }
88
+ async authHeaders() {
89
+ if (this.authProvider) {
90
+ const tokens = await this.authProvider.tokens();
91
+ if (tokens) return { Authorization: `Bearer ${tokens.access_token}` };
92
+ }
93
+ }
94
+ };
95
+
96
+ //#endregion
97
+ //#region src/mcp/streamable-http-edge.ts
98
+ var StreamableHTTPEdgeClientTransport = class extends StreamableHTTPClientTransport {
99
+ /**
100
+ * Creates a new StreamableHTTPEdgeClientTransport, which overrides fetch to be compatible with the CF workers environment
101
+ */
102
+ constructor(url, options) {
103
+ const fetchOverride = async (fetchUrl, fetchInit = {}) => {
104
+ const headers = await this.authHeaders();
105
+ const workerOptions = {
106
+ ...fetchInit,
107
+ headers: {
108
+ ...options.requestInit?.headers,
109
+ ...fetchInit?.headers,
110
+ ...headers
111
+ }
112
+ };
113
+ delete workerOptions.mode;
114
+ return options.requestInit?.fetch?.(fetchUrl, workerOptions) || fetch(fetchUrl, workerOptions);
115
+ };
116
+ super(url, {
117
+ ...options,
118
+ requestInit: {
119
+ ...options.requestInit,
120
+ fetch: fetchOverride
121
+ }
122
+ });
123
+ this.authProvider = options.authProvider;
124
+ }
125
+ async authHeaders() {
126
+ if (this.authProvider) {
127
+ const tokens = await this.authProvider.tokens();
128
+ if (tokens) return { Authorization: `Bearer ${tokens.access_token}` };
129
+ }
130
+ }
131
+ };
132
+
133
+ //#endregion
134
+ //#region src/mcp/client-connection.ts
135
+ var MCPClientConnection = class {
136
+ constructor(url, info, options = {
137
+ client: {},
138
+ transport: {}
139
+ }) {
140
+ this.url = url;
141
+ this.options = options;
142
+ this.connectionState = "connecting";
143
+ this.tools = [];
144
+ this.prompts = [];
145
+ this.resources = [];
146
+ this.resourceTemplates = [];
147
+ this._onObservabilityEvent = new Emitter();
148
+ this.onObservabilityEvent = this._onObservabilityEvent.event;
149
+ this.client = new Client(info, {
150
+ ...options.client,
151
+ capabilities: {
152
+ ...options.client?.capabilities,
153
+ elicitation: {}
154
+ }
155
+ });
156
+ }
157
+ /**
158
+ * Initialize a client connection
159
+ *
160
+ * @returns
161
+ */
162
+ async init() {
163
+ const transportType = this.options.transport.type;
164
+ if (!transportType) throw new Error("Transport type must be specified");
165
+ try {
166
+ await this.tryConnect(transportType);
167
+ } catch (e) {
168
+ if (isUnauthorized(e)) {
169
+ this.connectionState = "authenticating";
170
+ return;
171
+ }
172
+ this._onObservabilityEvent.fire({
173
+ type: "mcp:client:connect",
174
+ displayMessage: `Connection initialization failed for ${this.url.toString()}`,
175
+ payload: {
176
+ url: this.url.toString(),
177
+ transport: transportType,
178
+ state: this.connectionState,
179
+ error: toErrorMessage(e)
180
+ },
181
+ timestamp: Date.now(),
182
+ id: nanoid()
183
+ });
184
+ this.connectionState = "failed";
185
+ return;
186
+ }
187
+ await this.discoverAndRegister();
188
+ }
189
+ /**
190
+ * Finish OAuth by probing transports based on configured type.
191
+ * - Explicit: finish on that transport
192
+ * - Auto: try streamable-http, then sse on 404/405/Not Implemented
193
+ */
194
+ async finishAuthProbe(code) {
195
+ if (!this.options.transport.authProvider) throw new Error("No auth provider configured");
196
+ const configuredType = this.options.transport.type;
197
+ if (!configuredType) throw new Error("Transport type must be specified");
198
+ const finishAuth = async (base) => {
199
+ await this.getTransport(base).finishAuth(code);
200
+ };
201
+ if (configuredType === "sse" || configuredType === "streamable-http") {
202
+ await finishAuth(configuredType);
203
+ return;
204
+ }
205
+ try {
206
+ await finishAuth("streamable-http");
207
+ } catch (e) {
208
+ if (isTransportNotImplemented(e)) {
209
+ await finishAuth("sse");
210
+ return;
211
+ }
212
+ throw e;
213
+ }
214
+ }
215
+ /**
216
+ * Complete OAuth authorization
217
+ */
218
+ async completeAuthorization(code) {
219
+ if (this.connectionState !== "authenticating") throw new Error("Connection must be in authenticating state to complete authorization");
220
+ try {
221
+ await this.finishAuthProbe(code);
222
+ this.connectionState = "connecting";
223
+ } catch (error) {
224
+ this.connectionState = "failed";
225
+ throw error;
226
+ }
227
+ }
228
+ /**
229
+ * Establish connection after successful authorization
230
+ */
231
+ async establishConnection() {
232
+ if (this.connectionState !== "connecting") throw new Error("Connection must be in connecting state to establish connection");
233
+ try {
234
+ const transportType = this.options.transport.type;
235
+ if (!transportType) throw new Error("Transport type must be specified");
236
+ await this.tryConnect(transportType);
237
+ await this.discoverAndRegister();
238
+ } catch (error) {
239
+ this.connectionState = "failed";
240
+ throw error;
241
+ }
242
+ }
243
+ /**
244
+ * Discover server capabilities and register tools, resources, prompts, and templates
245
+ */
246
+ async discoverAndRegister() {
247
+ this.connectionState = "discovering";
248
+ this.serverCapabilities = this.client.getServerCapabilities();
249
+ if (!this.serverCapabilities) throw new Error("The MCP Server failed to return server capabilities");
250
+ const [instructionsResult, toolsResult, resourcesResult, promptsResult, resourceTemplatesResult] = await Promise.allSettled([
251
+ this.client.getInstructions(),
252
+ this.registerTools(),
253
+ this.registerResources(),
254
+ this.registerPrompts(),
255
+ this.registerResourceTemplates()
256
+ ]);
257
+ const operations = [
258
+ {
259
+ name: "instructions",
260
+ result: instructionsResult
261
+ },
262
+ {
263
+ name: "tools",
264
+ result: toolsResult
265
+ },
266
+ {
267
+ name: "resources",
268
+ result: resourcesResult
269
+ },
270
+ {
271
+ name: "prompts",
272
+ result: promptsResult
273
+ },
274
+ {
275
+ name: "resource templates",
276
+ result: resourceTemplatesResult
277
+ }
278
+ ];
279
+ for (const { name, result } of operations) if (result.status === "rejected") {
280
+ const url = this.url.toString();
281
+ this._onObservabilityEvent.fire({
282
+ type: "mcp:client:discover",
283
+ displayMessage: `Failed to discover ${name} for ${url}`,
284
+ payload: {
285
+ url,
286
+ capability: name,
287
+ error: result.reason
288
+ },
289
+ timestamp: Date.now(),
290
+ id: nanoid()
291
+ });
292
+ }
293
+ this.instructions = instructionsResult.status === "fulfilled" ? instructionsResult.value : void 0;
294
+ this.tools = toolsResult.status === "fulfilled" ? toolsResult.value : [];
295
+ this.resources = resourcesResult.status === "fulfilled" ? resourcesResult.value : [];
296
+ this.prompts = promptsResult.status === "fulfilled" ? promptsResult.value : [];
297
+ this.resourceTemplates = resourceTemplatesResult.status === "fulfilled" ? resourceTemplatesResult.value : [];
298
+ this.connectionState = "ready";
299
+ }
300
+ /**
301
+ * Notification handler registration
302
+ */
303
+ async registerTools() {
304
+ if (!this.serverCapabilities || !this.serverCapabilities.tools) return [];
305
+ if (this.serverCapabilities.tools.listChanged) this.client.setNotificationHandler(ToolListChangedNotificationSchema, async (_notification) => {
306
+ this.tools = await this.fetchTools();
307
+ });
308
+ return this.fetchTools();
309
+ }
310
+ async registerResources() {
311
+ if (!this.serverCapabilities || !this.serverCapabilities.resources) return [];
312
+ if (this.serverCapabilities.resources.listChanged) this.client.setNotificationHandler(ResourceListChangedNotificationSchema, async (_notification) => {
313
+ this.resources = await this.fetchResources();
314
+ });
315
+ return this.fetchResources();
316
+ }
317
+ async registerPrompts() {
318
+ if (!this.serverCapabilities || !this.serverCapabilities.prompts) return [];
319
+ if (this.serverCapabilities.prompts.listChanged) this.client.setNotificationHandler(PromptListChangedNotificationSchema, async (_notification) => {
320
+ this.prompts = await this.fetchPrompts();
321
+ });
322
+ return this.fetchPrompts();
323
+ }
324
+ async registerResourceTemplates() {
325
+ if (!this.serverCapabilities || !this.serverCapabilities.resources) return [];
326
+ return this.fetchResourceTemplates();
327
+ }
328
+ async fetchTools() {
329
+ let toolsAgg = [];
330
+ let toolsResult = { tools: [] };
331
+ do {
332
+ toolsResult = await this.client.listTools({ cursor: toolsResult.nextCursor }).catch(this._capabilityErrorHandler({ tools: [] }, "tools/list"));
333
+ toolsAgg = toolsAgg.concat(toolsResult.tools);
334
+ } while (toolsResult.nextCursor);
335
+ return toolsAgg;
336
+ }
337
+ async fetchResources() {
338
+ let resourcesAgg = [];
339
+ let resourcesResult = { resources: [] };
340
+ do {
341
+ resourcesResult = await this.client.listResources({ cursor: resourcesResult.nextCursor }).catch(this._capabilityErrorHandler({ resources: [] }, "resources/list"));
342
+ resourcesAgg = resourcesAgg.concat(resourcesResult.resources);
343
+ } while (resourcesResult.nextCursor);
344
+ return resourcesAgg;
345
+ }
346
+ async fetchPrompts() {
347
+ let promptsAgg = [];
348
+ let promptsResult = { prompts: [] };
349
+ do {
350
+ promptsResult = await this.client.listPrompts({ cursor: promptsResult.nextCursor }).catch(this._capabilityErrorHandler({ prompts: [] }, "prompts/list"));
351
+ promptsAgg = promptsAgg.concat(promptsResult.prompts);
352
+ } while (promptsResult.nextCursor);
353
+ return promptsAgg;
354
+ }
355
+ async fetchResourceTemplates() {
356
+ let templatesAgg = [];
357
+ let templatesResult = { resourceTemplates: [] };
358
+ do {
359
+ templatesResult = await this.client.listResourceTemplates({ cursor: templatesResult.nextCursor }).catch(this._capabilityErrorHandler({ resourceTemplates: [] }, "resources/templates/list"));
360
+ templatesAgg = templatesAgg.concat(templatesResult.resourceTemplates);
361
+ } while (templatesResult.nextCursor);
362
+ return templatesAgg;
363
+ }
364
+ /**
365
+ * Handle elicitation request from server
366
+ * Automatically uses the Agent's built-in elicitation handling if available
367
+ */
368
+ async handleElicitationRequest(_request) {
369
+ throw new Error("Elicitation handler must be implemented for your platform. Override handleElicitationRequest method.");
370
+ }
371
+ /**
372
+ * Get the transport for the client
373
+ * @param transportType - The transport type to get
374
+ * @returns The transport for the client
375
+ */
376
+ getTransport(transportType) {
377
+ switch (transportType) {
378
+ case "streamable-http": return new StreamableHTTPEdgeClientTransport(this.url, this.options.transport);
379
+ case "sse": return new SSEEdgeClientTransport(this.url, this.options.transport);
380
+ default: throw new Error(`Unsupported transport type: ${transportType}`);
381
+ }
382
+ }
383
+ async tryConnect(transportType) {
384
+ const transports = transportType === "auto" ? ["streamable-http", "sse"] : [transportType];
385
+ for (const currentTransportType of transports) {
386
+ const isLastTransport = currentTransportType === transports[transports.length - 1];
387
+ const hasFallback = transportType === "auto" && currentTransportType === "streamable-http" && !isLastTransport;
388
+ const transport = this.getTransport(currentTransportType);
389
+ try {
390
+ await this.client.connect(transport);
391
+ this.lastConnectedTransport = currentTransportType;
392
+ const url = this.url.toString();
393
+ this._onObservabilityEvent.fire({
394
+ type: "mcp:client:connect",
395
+ displayMessage: `Connected successfully using ${currentTransportType} transport for ${url}`,
396
+ payload: {
397
+ url,
398
+ transport: currentTransportType,
399
+ state: this.connectionState
400
+ },
401
+ timestamp: Date.now(),
402
+ id: nanoid()
403
+ });
404
+ break;
405
+ } catch (e) {
406
+ const error = e instanceof Error ? e : new Error(String(e));
407
+ if (isUnauthorized(error)) throw e;
408
+ if (hasFallback && isTransportNotImplemented(error)) {
409
+ const url = this.url.toString();
410
+ this._onObservabilityEvent.fire({
411
+ type: "mcp:client:connect",
412
+ displayMessage: `${currentTransportType} transport not available, trying ${transports[transports.indexOf(currentTransportType) + 1]} for ${url}`,
413
+ payload: {
414
+ url,
415
+ transport: currentTransportType,
416
+ state: this.connectionState
417
+ },
418
+ timestamp: Date.now(),
419
+ id: nanoid()
420
+ });
421
+ continue;
422
+ }
423
+ throw e;
424
+ }
425
+ }
426
+ this.client.setRequestHandler(ElicitRequestSchema, async (request) => {
427
+ return await this.handleElicitationRequest(request);
428
+ });
429
+ }
430
+ _capabilityErrorHandler(empty, method) {
431
+ return (e) => {
432
+ if (e.code === -32601) {
433
+ const url = this.url.toString();
434
+ this._onObservabilityEvent.fire({
435
+ type: "mcp:client:discover",
436
+ displayMessage: `The server advertised support for the capability ${method.split("/")[0]}, but returned "Method not found" for '${method}' for ${url}`,
437
+ payload: {
438
+ url,
439
+ capability: method.split("/")[0],
440
+ error: toErrorMessage(e)
441
+ },
442
+ timestamp: Date.now(),
443
+ id: nanoid()
444
+ });
445
+ return empty;
446
+ }
447
+ throw e;
448
+ };
449
+ }
450
+ };
451
+
452
+ //#endregion
453
+ //#region src/mcp/client.ts
454
+ /**
455
+ * Utility class that aggregates multiple MCP clients into one
456
+ */
457
+ var MCPClientManager = class {
458
+ /**
459
+ * @param _name Name of the MCP client
460
+ * @param _version Version of the MCP Client
461
+ * @param auth Auth paramters if being used to create a DurableObjectOAuthClientProvider
462
+ */
463
+ constructor(_name, _version) {
464
+ this._name = _name;
465
+ this._version = _version;
466
+ this.mcpConnections = {};
467
+ this._callbackUrls = [];
468
+ this._didWarnAboutUnstableGetAITools = false;
469
+ this._connectionDisposables = /* @__PURE__ */ new Map();
470
+ this._onObservabilityEvent = new Emitter();
471
+ this.onObservabilityEvent = this._onObservabilityEvent.event;
472
+ this._onConnected = new Emitter();
473
+ this.onConnected = this._onConnected.event;
474
+ }
475
+ /**
476
+ * Connect to and register an MCP server
477
+ *
478
+ * @param transportConfig Transport config
479
+ * @param clientConfig Client config
480
+ * @param capabilities Client capabilities (i.e. if the client supports roots/sampling)
481
+ */
482
+ async connect(url, options = {}) {
483
+ /**
484
+ * We need to delay loading ai sdk, because putting it in module scope is
485
+ * causing issues with startup time.
486
+ * The only place it's used is in getAITools, which only matters after
487
+ * .connect() is called on at least one server.
488
+ * So it's safe to delay loading it until .connect() is called.
489
+ */
490
+ if (!this.jsonSchema) {
491
+ const { jsonSchema } = await import("ai");
492
+ this.jsonSchema = jsonSchema;
493
+ }
494
+ const id = options.reconnect?.id ?? nanoid(8);
495
+ if (options.transport?.authProvider) {
496
+ options.transport.authProvider.serverId = id;
497
+ if (options.reconnect?.oauthClientId) options.transport.authProvider.clientId = options.reconnect?.oauthClientId;
498
+ }
499
+ if (!options.reconnect?.oauthCode || !this.mcpConnections[id]) {
500
+ const normalizedTransport = {
501
+ ...options.transport,
502
+ type: options.transport?.type ?? "auto"
503
+ };
504
+ this.mcpConnections[id] = new MCPClientConnection(new URL(url), {
505
+ name: this._name,
506
+ version: this._version
507
+ }, {
508
+ client: options.client ?? {},
509
+ transport: normalizedTransport
510
+ });
511
+ const store = new DisposableStore();
512
+ const existing = this._connectionDisposables.get(id);
513
+ if (existing) existing.dispose();
514
+ this._connectionDisposables.set(id, store);
515
+ store.add(this.mcpConnections[id].onObservabilityEvent((event) => {
516
+ this._onObservabilityEvent.fire(event);
517
+ }));
518
+ }
519
+ await this.mcpConnections[id].init();
520
+ if (options.reconnect?.oauthCode) try {
521
+ await this.mcpConnections[id].completeAuthorization(options.reconnect.oauthCode);
522
+ await this.mcpConnections[id].establishConnection();
523
+ } catch (error) {
524
+ this._onObservabilityEvent.fire({
525
+ type: "mcp:client:connect",
526
+ displayMessage: `Failed to complete OAuth reconnection for ${id} for ${url}`,
527
+ payload: {
528
+ url,
529
+ transport: options.transport?.type ?? "auto",
530
+ state: this.mcpConnections[id].connectionState,
531
+ error: toErrorMessage(error)
532
+ },
533
+ timestamp: Date.now(),
534
+ id
535
+ });
536
+ throw error;
537
+ }
538
+ const authUrl = options.transport?.authProvider?.authUrl;
539
+ if (this.mcpConnections[id].connectionState === "authenticating" && authUrl && options.transport?.authProvider?.redirectUrl) {
540
+ this._callbackUrls.push(options.transport.authProvider.redirectUrl.toString());
541
+ return {
542
+ authUrl,
543
+ clientId: options.transport?.authProvider?.clientId,
544
+ id
545
+ };
546
+ }
547
+ return { id };
548
+ }
549
+ isCallbackRequest(req) {
550
+ return req.method === "GET" && !!this._callbackUrls.find((url) => {
551
+ return req.url.startsWith(url);
552
+ });
553
+ }
554
+ async handleCallbackRequest(req) {
555
+ const url = new URL(req.url);
556
+ const urlMatch = this._callbackUrls.find((url$1) => {
557
+ return req.url.startsWith(url$1);
558
+ });
559
+ if (!urlMatch) throw new Error(`No callback URI match found for the request url: ${req.url}. Was the request matched with \`isCallbackRequest()\`?`);
560
+ const code = url.searchParams.get("code");
561
+ const state = url.searchParams.get("state");
562
+ const urlParams = urlMatch.split("/");
563
+ const serverId = urlParams[urlParams.length - 1];
564
+ if (!code) throw new Error("Unauthorized: no code provided");
565
+ if (!state) throw new Error("Unauthorized: no state provided");
566
+ if (this.mcpConnections[serverId] === void 0) throw new Error(`Could not find serverId: ${serverId}`);
567
+ if (this.mcpConnections[serverId].connectionState !== "authenticating") throw new Error("Failed to authenticate: the client isn't in the `authenticating` state");
568
+ const conn = this.mcpConnections[serverId];
569
+ if (!conn.options.transport.authProvider) throw new Error("Trying to finalize authentication for a server connection without an authProvider");
570
+ const clientId = conn.options.transport.authProvider.clientId || state;
571
+ conn.options.transport.authProvider.clientId = clientId;
572
+ conn.options.transport.authProvider.serverId = serverId;
573
+ try {
574
+ await conn.completeAuthorization(code);
575
+ return {
576
+ serverId,
577
+ authSuccess: true
578
+ };
579
+ } catch (error) {
580
+ return {
581
+ serverId,
582
+ authSuccess: false,
583
+ authError: error instanceof Error ? error.message : String(error)
584
+ };
585
+ }
586
+ }
587
+ /**
588
+ * Establish connection in the background after OAuth completion
589
+ * This method is called asynchronously and doesn't block the OAuth callback response
590
+ * @param serverId The server ID to establish connection for
591
+ */
592
+ async establishConnection(serverId) {
593
+ const conn = this.mcpConnections[serverId];
594
+ if (!conn) {
595
+ this._onObservabilityEvent.fire({
596
+ type: "mcp:client:preconnect",
597
+ displayMessage: `Connection not found for serverId: ${serverId}`,
598
+ payload: { serverId },
599
+ timestamp: Date.now(),
600
+ id: nanoid()
601
+ });
602
+ return;
603
+ }
604
+ try {
605
+ await conn.establishConnection();
606
+ this._onConnected.fire(serverId);
607
+ } catch (error) {
608
+ const url = conn.url.toString();
609
+ this._onObservabilityEvent.fire({
610
+ type: "mcp:client:connect",
611
+ displayMessage: `Failed to establish connection to server ${serverId} with url ${url}`,
612
+ payload: {
613
+ url,
614
+ transport: conn.options.transport.type ?? "auto",
615
+ state: conn.connectionState,
616
+ error: toErrorMessage(error)
617
+ },
618
+ timestamp: Date.now(),
619
+ id: nanoid()
620
+ });
621
+ }
622
+ }
623
+ /**
624
+ * Register a callback URL for OAuth handling
625
+ * @param url The callback URL to register
626
+ */
627
+ registerCallbackUrl(url) {
628
+ if (!this._callbackUrls.includes(url)) this._callbackUrls.push(url);
629
+ }
630
+ /**
631
+ * Unregister a callback URL
632
+ * @param serverId The server ID whose callback URL should be removed
633
+ */
634
+ unregisterCallbackUrl(serverId) {
635
+ this._callbackUrls = this._callbackUrls.filter((url) => !url.endsWith(`/${serverId}`));
636
+ }
637
+ /**
638
+ * Configure OAuth callback handling
639
+ * @param config OAuth callback configuration
640
+ */
641
+ configureOAuthCallback(config) {
642
+ this._oauthCallbackConfig = config;
643
+ }
644
+ /**
645
+ * Get the current OAuth callback configuration
646
+ * @returns The current OAuth callback configuration
647
+ */
648
+ getOAuthCallbackConfig() {
649
+ return this._oauthCallbackConfig;
650
+ }
651
+ /**
652
+ * @returns namespaced list of tools
653
+ */
654
+ listTools() {
655
+ return getNamespacedData(this.mcpConnections, "tools");
656
+ }
657
+ /**
658
+ * @returns a set of tools that you can use with the AI SDK
659
+ */
660
+ getAITools() {
661
+ return Object.fromEntries(getNamespacedData(this.mcpConnections, "tools").map((tool) => {
662
+ return [`tool_${tool.serverId.replace(/-/g, "")}_${tool.name}`, {
663
+ description: tool.description,
664
+ execute: async (args) => {
665
+ const result = await this.callTool({
666
+ arguments: args,
667
+ name: tool.name,
668
+ serverId: tool.serverId
669
+ });
670
+ if (result.isError) throw new Error(result.content[0].text);
671
+ return result;
672
+ },
673
+ inputSchema: this.jsonSchema(tool.inputSchema),
674
+ outputSchema: tool.outputSchema ? this.jsonSchema(tool.outputSchema) : void 0
675
+ }];
676
+ }));
677
+ }
678
+ /**
679
+ * @deprecated this has been renamed to getAITools(), and unstable_getAITools will be removed in the next major version
680
+ * @returns a set of tools that you can use with the AI SDK
681
+ */
682
+ unstable_getAITools() {
683
+ if (!this._didWarnAboutUnstableGetAITools) {
684
+ this._didWarnAboutUnstableGetAITools = true;
685
+ console.warn("unstable_getAITools is deprecated, use getAITools instead. unstable_getAITools will be removed in the next major version.");
686
+ }
687
+ return this.getAITools();
688
+ }
689
+ /**
690
+ * Closes all connections to MCP servers
691
+ */
692
+ async closeAllConnections() {
693
+ const ids = Object.keys(this.mcpConnections);
694
+ await Promise.all(ids.map(async (id) => {
695
+ await this.mcpConnections[id].client.close();
696
+ }));
697
+ for (const id of ids) {
698
+ const store = this._connectionDisposables.get(id);
699
+ if (store) store.dispose();
700
+ this._connectionDisposables.delete(id);
701
+ delete this.mcpConnections[id];
702
+ }
703
+ }
704
+ /**
705
+ * Closes a connection to an MCP server
706
+ * @param id The id of the connection to close
707
+ */
708
+ async closeConnection(id) {
709
+ if (!this.mcpConnections[id]) throw new Error(`Connection with id "${id}" does not exist.`);
710
+ await this.mcpConnections[id].client.close();
711
+ delete this.mcpConnections[id];
712
+ const store = this._connectionDisposables.get(id);
713
+ if (store) store.dispose();
714
+ this._connectionDisposables.delete(id);
715
+ }
716
+ /**
717
+ * Dispose the manager and all resources.
718
+ */
719
+ async dispose() {
720
+ try {
721
+ await this.closeAllConnections();
722
+ } finally {
723
+ this._onConnected.dispose();
724
+ this._onObservabilityEvent.dispose();
725
+ }
726
+ }
727
+ /**
728
+ * @returns namespaced list of prompts
729
+ */
730
+ listPrompts() {
731
+ return getNamespacedData(this.mcpConnections, "prompts");
732
+ }
733
+ /**
734
+ * @returns namespaced list of tools
735
+ */
736
+ listResources() {
737
+ return getNamespacedData(this.mcpConnections, "resources");
738
+ }
739
+ /**
740
+ * @returns namespaced list of resource templates
741
+ */
742
+ listResourceTemplates() {
743
+ return getNamespacedData(this.mcpConnections, "resourceTemplates");
744
+ }
745
+ /**
746
+ * Namespaced version of callTool
747
+ */
748
+ async callTool(params, resultSchema, options) {
749
+ const unqualifiedName = params.name.replace(`${params.serverId}.`, "");
750
+ return this.mcpConnections[params.serverId].client.callTool({
751
+ ...params,
752
+ name: unqualifiedName
753
+ }, resultSchema, options);
754
+ }
755
+ /**
756
+ * Namespaced version of readResource
757
+ */
758
+ readResource(params, options) {
759
+ return this.mcpConnections[params.serverId].client.readResource(params, options);
760
+ }
761
+ /**
762
+ * Namespaced version of getPrompt
763
+ */
764
+ getPrompt(params, options) {
765
+ return this.mcpConnections[params.serverId].client.getPrompt(params, options);
766
+ }
767
+ };
768
+ function getNamespacedData(mcpClients, type) {
769
+ return Object.entries(mcpClients).map(([name, conn]) => {
770
+ return {
771
+ data: conn[type],
772
+ name
773
+ };
774
+ }).flatMap(({ name: serverId, data }) => {
775
+ return data.map((item) => {
776
+ return {
777
+ ...item,
778
+ serverId
779
+ };
780
+ });
781
+ });
782
+ }
783
+
784
+ //#endregion
785
+ export { DisposableStore, MCPClientManager, SSEEdgeClientTransport, StreamableHTTPEdgeClientTransport, getNamespacedData };
786
+ //# sourceMappingURL=client-CZBVDDoO.js.map