agents 0.2.10 → 0.2.11

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