agents 0.3.9 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +2 -2
  2. package/dist/{index-N6791tVt.d.ts → agent-DY6QmSI_.d.ts} +3 -25
  3. package/dist/ai-types.js +1 -1
  4. package/dist/client-connection-CGMuV62J.js +472 -0
  5. package/dist/client-connection-CGMuV62J.js.map +1 -0
  6. package/dist/client-storage-Cvy5r9FG.d.ts +355 -0
  7. package/dist/client.d.ts +11 -7
  8. package/dist/client.js +6 -2
  9. package/dist/client.js.map +1 -1
  10. package/dist/email.d.ts +146 -16
  11. package/dist/email.js +222 -2
  12. package/dist/email.js.map +1 -0
  13. package/dist/index.d.ts +139 -41
  14. package/dist/index.js +2317 -6
  15. package/dist/index.js.map +1 -0
  16. package/dist/internal_context.d.ts +28 -5
  17. package/dist/internal_context.js +7 -2
  18. package/dist/internal_context.js.map +1 -0
  19. package/dist/mcp/client.d.ts +516 -2
  20. package/dist/mcp/client.js +662 -3
  21. package/dist/mcp/client.js.map +1 -0
  22. package/dist/mcp/do-oauth-client-provider.d.ts +61 -2
  23. package/dist/mcp/do-oauth-client-provider.js +154 -2
  24. package/dist/mcp/do-oauth-client-provider.js.map +1 -0
  25. package/dist/mcp/index.d.ts +3 -5
  26. package/dist/mcp/index.js +8 -7
  27. package/dist/mcp/index.js.map +1 -1
  28. package/dist/mcp/x402.d.ts +34 -14
  29. package/dist/mcp/x402.js +128 -66
  30. package/dist/mcp/x402.js.map +1 -1
  31. package/dist/{mcp-BwPscEiF.d.ts → mcp-Dw5vDrY8.d.ts} +1 -1
  32. package/dist/observability/index.d.ts +23 -2
  33. package/dist/observability/index.js +25 -6
  34. package/dist/observability/index.js.map +1 -0
  35. package/dist/react.d.ts +16 -10
  36. package/dist/react.js +34 -16
  37. package/dist/react.js.map +1 -1
  38. package/dist/types.d.ts +14 -1
  39. package/dist/types.js +16 -2
  40. package/dist/types.js.map +1 -0
  41. package/dist/utils.js +15 -2
  42. package/dist/utils.js.map +1 -0
  43. package/dist/workflow-types.d.ts +235 -23
  44. package/dist/workflows.d.ts +22 -24
  45. package/dist/workflows.js +2 -5
  46. package/dist/workflows.js.map +1 -1
  47. package/package.json +26 -23
  48. package/dist/client-BA8NJB6l.js +0 -1124
  49. package/dist/client-BA8NJB6l.js.map +0 -1
  50. package/dist/client-Ba-xntmv.d.ts +0 -963
  51. package/dist/do-oauth-client-provider-BqnOQzjy.d.ts +0 -70
  52. package/dist/do-oauth-client-provider-DDg8QrEA.js +0 -155
  53. package/dist/do-oauth-client-provider-DDg8QrEA.js.map +0 -1
  54. package/dist/email-8ljcpvwV.d.ts +0 -157
  55. package/dist/email-XHsSYsTO.js +0 -223
  56. package/dist/email-XHsSYsTO.js.map +0 -1
  57. package/dist/internal_context-CEu5ji80.d.ts +0 -29
  58. package/dist/internal_context-D9eKFth1.js +0 -8
  59. package/dist/internal_context-D9eKFth1.js.map +0 -1
  60. package/dist/src-CqnVUbg1.js +0 -2146
  61. package/dist/src-CqnVUbg1.js.map +0 -1
  62. package/dist/types-BITaDFf-.js +0 -16
  63. package/dist/types-BITaDFf-.js.map +0 -1
  64. package/dist/types-DSSHBW6w.d.ts +0 -14
  65. package/dist/utils-B49TmLCI.js +0 -16
  66. package/dist/utils-B49TmLCI.js.map +0 -1
  67. package/dist/workflow-types-Z_Oem1FJ.d.ts +0 -260
package/README.md CHANGED
@@ -128,8 +128,8 @@ export class MyAgent extends Agent<Env, { items: string[] }> {
128
128
  this.setState({ items: [...this.state.items, item] });
129
129
  }
130
130
 
131
- onStateUpdate(state: State, source: Connection | "server") {
132
- // Called when state changes from any source
131
+ onStateChanged(state: State, source: Connection | "server") {
132
+ // Called after state is persisted and broadcast
133
133
  }
134
134
  }
135
135
  ```
@@ -1,4 +1,4 @@
1
- import { n as BaseEvent, t as MCPObservabilityEvent } from "./mcp-BwPscEiF.js";
1
+ import { n as BaseEvent } from "./mcp-Dw5vDrY8.js";
2
2
 
3
3
  //#region src/observability/agent.d.ts
4
4
  /**
@@ -47,27 +47,5 @@ type AgentObservabilityEvent =
47
47
  }
48
48
  >;
49
49
  //#endregion
50
- //#region src/observability/index.d.ts
51
- /**
52
- * Union of all observability event types from different domains
53
- */
54
- type ObservabilityEvent = AgentObservabilityEvent | MCPObservabilityEvent;
55
- interface Observability {
56
- /**
57
- * Emit an event for the Agent's observability implementation to handle.
58
- * @param event - The event to emit
59
- * @param ctx - The execution context of the invocation (optional)
60
- */
61
- emit(event: ObservabilityEvent, ctx?: DurableObjectState): void;
62
- }
63
- /**
64
- * A generic observability implementation that logs events to the console.
65
- */
66
- declare const genericObservability: Observability;
67
- //#endregion
68
- export {
69
- ObservabilityEvent as n,
70
- genericObservability as r,
71
- Observability as t
72
- };
73
- //# sourceMappingURL=index-N6791tVt.d.ts.map
50
+ export { AgentObservabilityEvent as t };
51
+ //# sourceMappingURL=agent-DY6QmSI_.d.ts.map
package/dist/ai-types.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as MessageType$2 } from "./types-BITaDFf-.js";
1
+ import { MessageType as MessageType$2 } from "./types.js";
2
2
  import { MessageType as MessageType$1 } from "@cloudflare/ai-chat/types";
3
3
 
4
4
  //#region src/ai-types.ts
@@ -0,0 +1,472 @@
1
+ import { nanoid } from "nanoid";
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
4
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5
+ import { ElicitRequestSchema, PromptListChangedNotificationSchema, ResourceListChangedNotificationSchema, ToolListChangedNotificationSchema } from "@modelcontextprotocol/sdk/types.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 getErrorCode(error) {
51
+ if (error && typeof error === "object" && "code" in error && typeof error.code === "number") return error.code;
52
+ }
53
+ function isUnauthorized(error) {
54
+ if (getErrorCode(error) === 401) return true;
55
+ const msg = toErrorMessage(error);
56
+ return msg.includes("Unauthorized") || msg.includes("401");
57
+ }
58
+ function isTransportNotImplemented(error) {
59
+ const code = getErrorCode(error);
60
+ if (code === 404 || code === 405) return true;
61
+ const msg = toErrorMessage(error);
62
+ return msg.includes("404") || msg.includes("405") || msg.includes("Not Implemented") || msg.includes("not implemented");
63
+ }
64
+
65
+ //#endregion
66
+ //#region src/mcp/client-connection.ts
67
+ /**
68
+ * Connection state machine for MCP client connections.
69
+ *
70
+ * State transitions:
71
+ * - Non-OAuth: init() → CONNECTING → DISCOVERING → READY
72
+ * - OAuth: init() → AUTHENTICATING → (callback) → CONNECTING → DISCOVERING → READY
73
+ * - Any state can transition to FAILED on error
74
+ */
75
+ const MCPConnectionState = {
76
+ AUTHENTICATING: "authenticating",
77
+ CONNECTING: "connecting",
78
+ CONNECTED: "connected",
79
+ DISCOVERING: "discovering",
80
+ READY: "ready",
81
+ FAILED: "failed"
82
+ };
83
+ var MCPClientConnection = class {
84
+ constructor(url, info, options = {
85
+ client: {},
86
+ transport: {}
87
+ }) {
88
+ this.url = url;
89
+ this.options = options;
90
+ this.connectionState = MCPConnectionState.CONNECTING;
91
+ this.connectionError = null;
92
+ this.tools = [];
93
+ this.prompts = [];
94
+ this.resources = [];
95
+ this.resourceTemplates = [];
96
+ this._onObservabilityEvent = new Emitter();
97
+ this.onObservabilityEvent = this._onObservabilityEvent.event;
98
+ this.client = new Client(info, {
99
+ ...options.client,
100
+ capabilities: {
101
+ ...options.client?.capabilities,
102
+ elicitation: {}
103
+ }
104
+ });
105
+ }
106
+ /**
107
+ * Initialize a client connection, if authentication is required, the connection will be in the AUTHENTICATING state
108
+ * Sets connection state based on the result and emits observability events
109
+ *
110
+ * @returns Error message if connection failed, undefined otherwise
111
+ */
112
+ async init() {
113
+ const transportType = this.options.transport.type;
114
+ if (!transportType) throw new Error("Transport type must be specified");
115
+ const res = await this.tryConnect(transportType);
116
+ this.connectionState = res.state;
117
+ if (res.state === MCPConnectionState.CONNECTED && res.transport) {
118
+ this.client.setRequestHandler(ElicitRequestSchema, async (request) => {
119
+ return await this.handleElicitationRequest(request);
120
+ });
121
+ this.lastConnectedTransport = res.transport;
122
+ this._onObservabilityEvent.fire({
123
+ type: "mcp:client:connect",
124
+ displayMessage: `Connected successfully using ${res.transport} transport for ${this.url.toString()}`,
125
+ payload: {
126
+ url: this.url.toString(),
127
+ transport: res.transport,
128
+ state: this.connectionState
129
+ },
130
+ timestamp: Date.now(),
131
+ id: nanoid()
132
+ });
133
+ return;
134
+ } else if (res.state === MCPConnectionState.FAILED && res.error) {
135
+ const errorMessage = toErrorMessage(res.error);
136
+ this._onObservabilityEvent.fire({
137
+ type: "mcp:client:connect",
138
+ displayMessage: `Failed to connect to ${this.url.toString()}: ${errorMessage}`,
139
+ payload: {
140
+ url: this.url.toString(),
141
+ transport: transportType,
142
+ state: this.connectionState,
143
+ error: errorMessage
144
+ },
145
+ timestamp: Date.now(),
146
+ id: nanoid()
147
+ });
148
+ return errorMessage;
149
+ }
150
+ }
151
+ /**
152
+ * Finish OAuth by probing transports based on configured type.
153
+ * - Explicit: finish on that transport
154
+ * - Auto: try streamable-http, then sse on 404/405/Not Implemented
155
+ */
156
+ async finishAuthProbe(code) {
157
+ if (!this.options.transport.authProvider) throw new Error("No auth provider configured");
158
+ const configuredType = this.options.transport.type;
159
+ if (!configuredType) throw new Error("Transport type must be specified");
160
+ const finishAuth = async (base) => {
161
+ await this.getTransport(base).finishAuth(code);
162
+ };
163
+ if (configuredType === "sse" || configuredType === "streamable-http") {
164
+ await finishAuth(configuredType);
165
+ return;
166
+ }
167
+ try {
168
+ await finishAuth("streamable-http");
169
+ } catch (e) {
170
+ if (isTransportNotImplemented(e)) {
171
+ await finishAuth("sse");
172
+ return;
173
+ }
174
+ throw e;
175
+ }
176
+ }
177
+ /**
178
+ * Complete OAuth authorization
179
+ */
180
+ async completeAuthorization(code) {
181
+ if (this.connectionState !== MCPConnectionState.AUTHENTICATING) throw new Error("Connection must be in authenticating state to complete authorization");
182
+ try {
183
+ await this.finishAuthProbe(code);
184
+ this.connectionState = MCPConnectionState.CONNECTING;
185
+ } catch (error) {
186
+ this.connectionState = MCPConnectionState.FAILED;
187
+ throw error;
188
+ }
189
+ }
190
+ /**
191
+ * Discover server capabilities and register tools, resources, prompts, and templates.
192
+ * This method does the work but does not manage connection state - that's handled by discover().
193
+ */
194
+ async discoverAndRegister() {
195
+ this.serverCapabilities = this.client.getServerCapabilities();
196
+ if (!this.serverCapabilities) throw new Error("The MCP Server failed to return server capabilities");
197
+ const operations = [];
198
+ const operationNames = [];
199
+ operations.push(Promise.resolve(this.client.getInstructions()));
200
+ operationNames.push("instructions");
201
+ if (this.serverCapabilities.tools) {
202
+ operations.push(this.registerTools());
203
+ operationNames.push("tools");
204
+ }
205
+ if (this.serverCapabilities.resources) {
206
+ operations.push(this.registerResources());
207
+ operationNames.push("resources");
208
+ }
209
+ if (this.serverCapabilities.prompts) {
210
+ operations.push(this.registerPrompts());
211
+ operationNames.push("prompts");
212
+ }
213
+ if (this.serverCapabilities.resources) {
214
+ operations.push(this.registerResourceTemplates());
215
+ operationNames.push("resource templates");
216
+ }
217
+ try {
218
+ const results = await Promise.all(operations);
219
+ for (let i = 0; i < results.length; i++) {
220
+ const result = results[i];
221
+ switch (operationNames[i]) {
222
+ case "instructions":
223
+ this.instructions = result;
224
+ break;
225
+ case "tools":
226
+ this.tools = result;
227
+ break;
228
+ case "resources":
229
+ this.resources = result;
230
+ break;
231
+ case "prompts":
232
+ this.prompts = result;
233
+ break;
234
+ case "resource templates":
235
+ this.resourceTemplates = result;
236
+ break;
237
+ }
238
+ }
239
+ } catch (error) {
240
+ this._onObservabilityEvent.fire({
241
+ type: "mcp:client:discover",
242
+ displayMessage: `Failed to discover capabilities for ${this.url.toString()}: ${toErrorMessage(error)}`,
243
+ payload: {
244
+ url: this.url.toString(),
245
+ error: toErrorMessage(error)
246
+ },
247
+ timestamp: Date.now(),
248
+ id: nanoid()
249
+ });
250
+ throw error;
251
+ }
252
+ }
253
+ /**
254
+ * Discover server capabilities with timeout and cancellation support.
255
+ * If called while a previous discovery is in-flight, the previous discovery will be aborted.
256
+ *
257
+ * @param options Optional configuration
258
+ * @param options.timeoutMs Timeout in milliseconds (default: 15000)
259
+ * @returns Result indicating success/failure with optional error message
260
+ */
261
+ async discover(options = {}) {
262
+ const { timeoutMs = 15e3 } = options;
263
+ if (this.connectionState !== MCPConnectionState.CONNECTED && this.connectionState !== MCPConnectionState.READY) {
264
+ this._onObservabilityEvent.fire({
265
+ type: "mcp:client:discover",
266
+ displayMessage: `Discovery skipped for ${this.url.toString()}, state is ${this.connectionState}`,
267
+ payload: {
268
+ url: this.url.toString(),
269
+ state: this.connectionState
270
+ },
271
+ timestamp: Date.now(),
272
+ id: nanoid()
273
+ });
274
+ return {
275
+ success: false,
276
+ error: `Discovery skipped - connection in ${this.connectionState} state`
277
+ };
278
+ }
279
+ if (this._discoveryAbortController) {
280
+ this._discoveryAbortController.abort();
281
+ this._discoveryAbortController = void 0;
282
+ }
283
+ const abortController = new AbortController();
284
+ this._discoveryAbortController = abortController;
285
+ this.connectionState = MCPConnectionState.DISCOVERING;
286
+ let timeoutId;
287
+ try {
288
+ const timeoutPromise = new Promise((_, reject) => {
289
+ timeoutId = setTimeout(() => reject(/* @__PURE__ */ new Error(`Discovery timed out after ${timeoutMs}ms`)), timeoutMs);
290
+ });
291
+ if (abortController.signal.aborted) throw new Error("Discovery was cancelled");
292
+ const abortPromise = new Promise((_, reject) => {
293
+ abortController.signal.addEventListener("abort", () => {
294
+ reject(/* @__PURE__ */ new Error("Discovery was cancelled"));
295
+ });
296
+ });
297
+ await Promise.race([
298
+ this.discoverAndRegister(),
299
+ timeoutPromise,
300
+ abortPromise
301
+ ]);
302
+ if (timeoutId !== void 0) clearTimeout(timeoutId);
303
+ this.connectionState = MCPConnectionState.READY;
304
+ this._onObservabilityEvent.fire({
305
+ type: "mcp:client:discover",
306
+ displayMessage: `Discovery completed for ${this.url.toString()}`,
307
+ payload: { url: this.url.toString() },
308
+ timestamp: Date.now(),
309
+ id: nanoid()
310
+ });
311
+ return { success: true };
312
+ } catch (e) {
313
+ if (timeoutId !== void 0) clearTimeout(timeoutId);
314
+ this.connectionState = MCPConnectionState.CONNECTED;
315
+ return {
316
+ success: false,
317
+ error: e instanceof Error ? e.message : String(e)
318
+ };
319
+ } finally {
320
+ this._discoveryAbortController = void 0;
321
+ }
322
+ }
323
+ /**
324
+ * Cancel any in-flight discovery operation.
325
+ * Called when closing the connection.
326
+ */
327
+ cancelDiscovery() {
328
+ if (this._discoveryAbortController) {
329
+ this._discoveryAbortController.abort();
330
+ this._discoveryAbortController = void 0;
331
+ }
332
+ }
333
+ /**
334
+ * Notification handler registration for tools
335
+ * Should only be called if serverCapabilities.tools exists
336
+ */
337
+ async registerTools() {
338
+ if (this.serverCapabilities?.tools?.listChanged) this.client.setNotificationHandler(ToolListChangedNotificationSchema, async (_notification) => {
339
+ this.tools = await this.fetchTools();
340
+ });
341
+ return this.fetchTools();
342
+ }
343
+ /**
344
+ * Notification handler registration for resources
345
+ * Should only be called if serverCapabilities.resources exists
346
+ */
347
+ async registerResources() {
348
+ if (this.serverCapabilities?.resources?.listChanged) this.client.setNotificationHandler(ResourceListChangedNotificationSchema, async (_notification) => {
349
+ this.resources = await this.fetchResources();
350
+ });
351
+ return this.fetchResources();
352
+ }
353
+ /**
354
+ * Notification handler registration for prompts
355
+ * Should only be called if serverCapabilities.prompts exists
356
+ */
357
+ async registerPrompts() {
358
+ if (this.serverCapabilities?.prompts?.listChanged) this.client.setNotificationHandler(PromptListChangedNotificationSchema, async (_notification) => {
359
+ this.prompts = await this.fetchPrompts();
360
+ });
361
+ return this.fetchPrompts();
362
+ }
363
+ async registerResourceTemplates() {
364
+ return this.fetchResourceTemplates();
365
+ }
366
+ async fetchTools() {
367
+ let toolsAgg = [];
368
+ let toolsResult = { tools: [] };
369
+ do {
370
+ toolsResult = await this.client.listTools({ cursor: toolsResult.nextCursor }).catch(this._capabilityErrorHandler({ tools: [] }, "tools/list"));
371
+ toolsAgg = toolsAgg.concat(toolsResult.tools);
372
+ } while (toolsResult.nextCursor);
373
+ return toolsAgg;
374
+ }
375
+ async fetchResources() {
376
+ let resourcesAgg = [];
377
+ let resourcesResult = { resources: [] };
378
+ do {
379
+ resourcesResult = await this.client.listResources({ cursor: resourcesResult.nextCursor }).catch(this._capabilityErrorHandler({ resources: [] }, "resources/list"));
380
+ resourcesAgg = resourcesAgg.concat(resourcesResult.resources);
381
+ } while (resourcesResult.nextCursor);
382
+ return resourcesAgg;
383
+ }
384
+ async fetchPrompts() {
385
+ let promptsAgg = [];
386
+ let promptsResult = { prompts: [] };
387
+ do {
388
+ promptsResult = await this.client.listPrompts({ cursor: promptsResult.nextCursor }).catch(this._capabilityErrorHandler({ prompts: [] }, "prompts/list"));
389
+ promptsAgg = promptsAgg.concat(promptsResult.prompts);
390
+ } while (promptsResult.nextCursor);
391
+ return promptsAgg;
392
+ }
393
+ async fetchResourceTemplates() {
394
+ let templatesAgg = [];
395
+ let templatesResult = { resourceTemplates: [] };
396
+ do {
397
+ templatesResult = await this.client.listResourceTemplates({ cursor: templatesResult.nextCursor }).catch(this._capabilityErrorHandler({ resourceTemplates: [] }, "resources/templates/list"));
398
+ templatesAgg = templatesAgg.concat(templatesResult.resourceTemplates);
399
+ } while (templatesResult.nextCursor);
400
+ return templatesAgg;
401
+ }
402
+ /**
403
+ * Handle elicitation request from server
404
+ * Automatically uses the Agent's built-in elicitation handling if available
405
+ */
406
+ async handleElicitationRequest(_request) {
407
+ throw new Error("Elicitation handler must be implemented for your platform. Override handleElicitationRequest method.");
408
+ }
409
+ /**
410
+ * Get the transport for the client
411
+ * @param transportType - The transport type to get
412
+ * @returns The transport for the client
413
+ */
414
+ getTransport(transportType) {
415
+ switch (transportType) {
416
+ case "streamable-http": return new StreamableHTTPClientTransport(this.url, this.options.transport);
417
+ case "sse": return new SSEClientTransport(this.url, this.options.transport);
418
+ default: throw new Error(`Unsupported transport type: ${transportType}`);
419
+ }
420
+ }
421
+ async tryConnect(transportType) {
422
+ const transports = transportType === "auto" ? ["streamable-http", "sse"] : [transportType];
423
+ for (const currentTransportType of transports) {
424
+ const isLastTransport = currentTransportType === transports[transports.length - 1];
425
+ const hasFallback = transportType === "auto" && currentTransportType === "streamable-http" && !isLastTransport;
426
+ const transport = this.getTransport(currentTransportType);
427
+ try {
428
+ await this.client.connect(transport);
429
+ return {
430
+ state: MCPConnectionState.CONNECTED,
431
+ transport: currentTransportType
432
+ };
433
+ } catch (e) {
434
+ const error = e instanceof Error ? e : new Error(String(e));
435
+ if (isUnauthorized(error)) return { state: MCPConnectionState.AUTHENTICATING };
436
+ if (isTransportNotImplemented(error) && hasFallback) continue;
437
+ return {
438
+ state: MCPConnectionState.FAILED,
439
+ error
440
+ };
441
+ }
442
+ }
443
+ return {
444
+ state: MCPConnectionState.FAILED,
445
+ error: /* @__PURE__ */ new Error("No transports available")
446
+ };
447
+ }
448
+ _capabilityErrorHandler(empty, method) {
449
+ return (e) => {
450
+ if (e.code === -32601) {
451
+ const url = this.url.toString();
452
+ this._onObservabilityEvent.fire({
453
+ type: "mcp:client:discover",
454
+ displayMessage: `The server advertised support for the capability ${method.split("/")[0]}, but returned "Method not found" for '${method}' for ${url}`,
455
+ payload: {
456
+ url,
457
+ capability: method.split("/")[0],
458
+ error: toErrorMessage(e)
459
+ },
460
+ timestamp: Date.now(),
461
+ id: nanoid()
462
+ });
463
+ return empty;
464
+ }
465
+ throw e;
466
+ };
467
+ }
468
+ };
469
+
470
+ //#endregion
471
+ export { Emitter as a, DisposableStore as i, MCPConnectionState as n, toErrorMessage as r, MCPClientConnection as t };
472
+ //# sourceMappingURL=client-connection-CGMuV62J.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-connection-CGMuV62J.js","names":[],"sources":["../src/core/events.ts","../src/mcp/errors.ts","../src/mcp/client-connection.ts"],"sourcesContent":["export interface Disposable {\n dispose(): void;\n}\n\nexport function toDisposable(fn: () => void): Disposable {\n return { dispose: fn };\n}\n\nexport class DisposableStore implements Disposable {\n private readonly _items: Disposable[] = [];\n\n add<T extends Disposable>(d: T): T {\n this._items.push(d);\n return d;\n }\n\n dispose(): void {\n while (this._items.length) {\n try {\n this._items.pop()!.dispose();\n } catch {\n // best-effort cleanup\n }\n }\n }\n}\n\nexport type Event<T> = (listener: (e: T) => void) => Disposable;\n\nexport class Emitter<T> implements Disposable {\n private _listeners: Set<(e: T) => void> = new Set();\n\n readonly event: Event<T> = (listener) => {\n this._listeners.add(listener);\n return toDisposable(() => this._listeners.delete(listener));\n };\n\n fire(data: T): void {\n for (const listener of [...this._listeners]) {\n try {\n listener(data);\n } catch (err) {\n // do not let one bad listener break others\n console.error(\"Emitter listener error:\", err);\n }\n }\n }\n\n dispose(): void {\n this._listeners.clear();\n }\n}\n","export function toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction getErrorCode(error: unknown): number | undefined {\n if (\n error &&\n typeof error === \"object\" &&\n \"code\" in error &&\n typeof (error as { code: unknown }).code === \"number\"\n ) {\n return (error as { code: number }).code;\n }\n return undefined;\n}\n\nexport function isUnauthorized(error: unknown): boolean {\n const code = getErrorCode(error);\n if (code === 401) return true;\n\n const msg = toErrorMessage(error);\n return msg.includes(\"Unauthorized\") || msg.includes(\"401\");\n}\n\n// MCP SDK change (v1.24.0, commit 6b90e1a):\n// - Old: Error POSTing to endpoint (HTTP 404): Not Found\n// - New: StreamableHTTPError with code: 404 and message Error POSTing to endpoint: Not Found\nexport function isTransportNotImplemented(error: unknown): boolean {\n const code = getErrorCode(error);\n if (code === 404 || code === 405) return true;\n\n const msg = toErrorMessage(error);\n return (\n msg.includes(\"404\") ||\n msg.includes(\"405\") ||\n msg.includes(\"Not Implemented\") ||\n msg.includes(\"not implemented\")\n );\n}\n","import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport {\n SSEClientTransport,\n type SSEClientTransportOptions\n} from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport {\n StreamableHTTPClientTransport,\n type StreamableHTTPClientTransportOptions\n} from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\n// Import types directly from MCP SDK\nimport type {\n Prompt,\n Resource,\n Tool\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n type ClientCapabilities,\n type ElicitRequest,\n ElicitRequestSchema,\n type ElicitResult,\n type ListPromptsResult,\n type ListResourceTemplatesResult,\n type ListResourcesResult,\n type ListToolsResult,\n PromptListChangedNotificationSchema,\n ResourceListChangedNotificationSchema,\n type ResourceTemplate,\n type ServerCapabilities,\n ToolListChangedNotificationSchema\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { nanoid } from \"nanoid\";\nimport { Emitter, type Event } from \"../core/events\";\nimport type { MCPObservabilityEvent } from \"../observability/mcp\";\nimport type { AgentMcpOAuthProvider } from \"./do-oauth-client-provider\";\nimport {\n isTransportNotImplemented,\n isUnauthorized,\n toErrorMessage\n} from \"./errors\";\nimport type { BaseTransportType, TransportType } from \"./types\";\n\n/**\n * Connection state machine for MCP client connections.\n *\n * State transitions:\n * - Non-OAuth: init() → CONNECTING → DISCOVERING → READY\n * - OAuth: init() → AUTHENTICATING → (callback) → CONNECTING → DISCOVERING → READY\n * - Any state can transition to FAILED on error\n */\nexport const MCPConnectionState = {\n /** Waiting for OAuth authorization to complete */\n AUTHENTICATING: \"authenticating\",\n /** Establishing transport connection to MCP server */\n CONNECTING: \"connecting\",\n /** Transport connection established */\n CONNECTED: \"connected\",\n /** Discovering server capabilities (tools, resources, prompts) */\n DISCOVERING: \"discovering\",\n /** Fully connected and ready to use */\n READY: \"ready\",\n /** Connection failed at some point */\n FAILED: \"failed\"\n} as const;\n\n/**\n * Connection state type for MCP client connections.\n */\nexport type MCPConnectionState =\n (typeof MCPConnectionState)[keyof typeof MCPConnectionState];\n\nexport type MCPTransportOptions = (\n | SSEClientTransportOptions\n | StreamableHTTPClientTransportOptions\n) & {\n authProvider?: AgentMcpOAuthProvider;\n type?: TransportType;\n};\n\nexport type MCPClientConnectionResult = {\n state: MCPConnectionState;\n error?: Error;\n transport?: BaseTransportType;\n};\n\n/**\n * Result of a discovery operation.\n * success indicates whether discovery completed successfully.\n * error is present when success is false.\n */\nexport type MCPDiscoveryResult = {\n success: boolean;\n error?: string;\n};\n\nexport class MCPClientConnection {\n client: Client;\n connectionState: MCPConnectionState = MCPConnectionState.CONNECTING;\n connectionError: string | null = null;\n lastConnectedTransport: BaseTransportType | undefined;\n instructions?: string;\n tools: Tool[] = [];\n prompts: Prompt[] = [];\n resources: Resource[] = [];\n resourceTemplates: ResourceTemplate[] = [];\n serverCapabilities: ServerCapabilities | undefined;\n\n /** Tracks in-flight discovery to allow cancellation */\n private _discoveryAbortController: AbortController | undefined;\n\n private readonly _onObservabilityEvent = new Emitter<MCPObservabilityEvent>();\n public readonly onObservabilityEvent: Event<MCPObservabilityEvent> =\n this._onObservabilityEvent.event;\n\n constructor(\n public url: URL,\n info: ConstructorParameters<typeof Client>[0],\n public options: {\n transport: MCPTransportOptions;\n client: ConstructorParameters<typeof Client>[1];\n } = { client: {}, transport: {} }\n ) {\n const clientOptions = {\n ...options.client,\n capabilities: {\n ...options.client?.capabilities,\n elicitation: {}\n } as ClientCapabilities\n };\n\n this.client = new Client(info, clientOptions);\n }\n\n /**\n * Initialize a client connection, if authentication is required, the connection will be in the AUTHENTICATING state\n * Sets connection state based on the result and emits observability events\n *\n * @returns Error message if connection failed, undefined otherwise\n */\n async init(): Promise<string | undefined> {\n const transportType = this.options.transport.type;\n if (!transportType) {\n throw new Error(\"Transport type must be specified\");\n }\n\n const res = await this.tryConnect(transportType);\n\n // Set the connection state\n this.connectionState = res.state;\n\n // Handle the result and emit appropriate events\n if (res.state === MCPConnectionState.CONNECTED && res.transport) {\n // Set up elicitation request handler after successful connection\n this.client.setRequestHandler(\n ElicitRequestSchema,\n async (request: ElicitRequest) => {\n return await this.handleElicitationRequest(request);\n }\n );\n\n this.lastConnectedTransport = res.transport;\n\n this._onObservabilityEvent.fire({\n type: \"mcp:client:connect\",\n displayMessage: `Connected successfully using ${res.transport} transport for ${this.url.toString()}`,\n payload: {\n url: this.url.toString(),\n transport: res.transport,\n state: this.connectionState\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n return undefined;\n } else if (res.state === MCPConnectionState.FAILED && res.error) {\n const errorMessage = toErrorMessage(res.error);\n this._onObservabilityEvent.fire({\n type: \"mcp:client:connect\",\n displayMessage: `Failed to connect to ${this.url.toString()}: ${errorMessage}`,\n payload: {\n url: this.url.toString(),\n transport: transportType,\n state: this.connectionState,\n error: errorMessage\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n return errorMessage;\n }\n return undefined;\n }\n\n /**\n * Finish OAuth by probing transports based on configured type.\n * - Explicit: finish on that transport\n * - Auto: try streamable-http, then sse on 404/405/Not Implemented\n */\n private async finishAuthProbe(code: string): Promise<void> {\n if (!this.options.transport.authProvider) {\n throw new Error(\"No auth provider configured\");\n }\n\n const configuredType = this.options.transport.type;\n if (!configuredType) {\n throw new Error(\"Transport type must be specified\");\n }\n\n const finishAuth = async (base: BaseTransportType) => {\n const transport = this.getTransport(base);\n await transport.finishAuth(code);\n };\n\n if (configuredType === \"sse\" || configuredType === \"streamable-http\") {\n await finishAuth(configuredType);\n return;\n }\n\n // For \"auto\" mode, try streamable-http first, then fall back to SSE\n try {\n await finishAuth(\"streamable-http\");\n } catch (e) {\n if (isTransportNotImplemented(e)) {\n await finishAuth(\"sse\");\n return;\n }\n throw e;\n }\n }\n\n /**\n * Complete OAuth authorization\n */\n async completeAuthorization(code: string): Promise<void> {\n if (this.connectionState !== MCPConnectionState.AUTHENTICATING) {\n throw new Error(\n \"Connection must be in authenticating state to complete authorization\"\n );\n }\n\n try {\n // Finish OAuth by probing transports per configuration\n await this.finishAuthProbe(code);\n\n // Mark as connecting\n this.connectionState = MCPConnectionState.CONNECTING;\n } catch (error) {\n this.connectionState = MCPConnectionState.FAILED;\n throw error;\n }\n }\n\n /**\n * Discover server capabilities and register tools, resources, prompts, and templates.\n * This method does the work but does not manage connection state - that's handled by discover().\n */\n async discoverAndRegister(): Promise<void> {\n this.serverCapabilities = this.client.getServerCapabilities();\n if (!this.serverCapabilities) {\n throw new Error(\"The MCP Server failed to return server capabilities\");\n }\n\n // Build list of operations to perform based on server capabilities\n type DiscoveryResult =\n | string\n | undefined\n | Tool[]\n | Resource[]\n | Prompt[]\n | ResourceTemplate[];\n const operations: Promise<DiscoveryResult>[] = [];\n const operationNames: string[] = [];\n\n // Instructions (always try to fetch if available)\n operations.push(Promise.resolve(this.client.getInstructions()));\n operationNames.push(\"instructions\");\n\n // Only register capabilities that the server advertises\n if (this.serverCapabilities.tools) {\n operations.push(this.registerTools());\n operationNames.push(\"tools\");\n }\n\n if (this.serverCapabilities.resources) {\n operations.push(this.registerResources());\n operationNames.push(\"resources\");\n }\n\n if (this.serverCapabilities.prompts) {\n operations.push(this.registerPrompts());\n operationNames.push(\"prompts\");\n }\n\n if (this.serverCapabilities.resources) {\n operations.push(this.registerResourceTemplates());\n operationNames.push(\"resource templates\");\n }\n\n try {\n const results = await Promise.all(operations);\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n const name = operationNames[i];\n\n switch (name) {\n case \"instructions\":\n this.instructions = result as string | undefined;\n break;\n case \"tools\":\n this.tools = result as Tool[];\n break;\n case \"resources\":\n this.resources = result as Resource[];\n break;\n case \"prompts\":\n this.prompts = result as Prompt[];\n break;\n case \"resource templates\":\n this.resourceTemplates = result as ResourceTemplate[];\n break;\n }\n }\n } catch (error) {\n this._onObservabilityEvent.fire({\n type: \"mcp:client:discover\",\n displayMessage: `Failed to discover capabilities for ${this.url.toString()}: ${toErrorMessage(error)}`,\n payload: {\n url: this.url.toString(),\n error: toErrorMessage(error)\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n\n throw error;\n }\n }\n\n /**\n * Discover server capabilities with timeout and cancellation support.\n * If called while a previous discovery is in-flight, the previous discovery will be aborted.\n *\n * @param options Optional configuration\n * @param options.timeoutMs Timeout in milliseconds (default: 15000)\n * @returns Result indicating success/failure with optional error message\n */\n async discover(\n options: { timeoutMs?: number } = {}\n ): Promise<MCPDiscoveryResult> {\n const { timeoutMs = 15000 } = options;\n\n // Check if state allows discovery\n if (\n this.connectionState !== MCPConnectionState.CONNECTED &&\n this.connectionState !== MCPConnectionState.READY\n ) {\n this._onObservabilityEvent.fire({\n type: \"mcp:client:discover\",\n displayMessage: `Discovery skipped for ${this.url.toString()}, state is ${this.connectionState}`,\n payload: {\n url: this.url.toString(),\n state: this.connectionState\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n return {\n success: false,\n error: `Discovery skipped - connection in ${this.connectionState} state`\n };\n }\n\n // Cancel any previous in-flight discovery\n if (this._discoveryAbortController) {\n this._discoveryAbortController.abort();\n this._discoveryAbortController = undefined;\n }\n\n // Create a new AbortController for this discovery\n const abortController = new AbortController();\n this._discoveryAbortController = abortController;\n\n this.connectionState = MCPConnectionState.DISCOVERING;\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n try {\n // Create timeout promise\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(\n () => reject(new Error(`Discovery timed out after ${timeoutMs}ms`)),\n timeoutMs\n );\n });\n\n // Check if aborted before starting\n if (abortController.signal.aborted) {\n throw new Error(\"Discovery was cancelled\");\n }\n\n // Create an abort promise that rejects when signal fires\n const abortPromise = new Promise<never>((_, reject) => {\n abortController.signal.addEventListener(\"abort\", () => {\n reject(new Error(\"Discovery was cancelled\"));\n });\n });\n\n await Promise.race([\n this.discoverAndRegister(),\n timeoutPromise,\n abortPromise\n ]);\n\n // Clear timeout on success\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n\n // Discovery succeeded - transition to ready\n this.connectionState = MCPConnectionState.READY;\n\n this._onObservabilityEvent.fire({\n type: \"mcp:client:discover\",\n displayMessage: `Discovery completed for ${this.url.toString()}`,\n payload: {\n url: this.url.toString()\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n\n return { success: true };\n } catch (e) {\n // Always clear the timeout\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId);\n }\n\n // Return to CONNECTED state so user can retry discovery\n this.connectionState = MCPConnectionState.CONNECTED;\n\n const error = e instanceof Error ? e.message : String(e);\n return { success: false, error };\n } finally {\n // Clean up the abort controller\n this._discoveryAbortController = undefined;\n }\n }\n\n /**\n * Cancel any in-flight discovery operation.\n * Called when closing the connection.\n */\n cancelDiscovery(): void {\n if (this._discoveryAbortController) {\n this._discoveryAbortController.abort();\n this._discoveryAbortController = undefined;\n }\n }\n\n /**\n * Notification handler registration for tools\n * Should only be called if serverCapabilities.tools exists\n */\n async registerTools(): Promise<Tool[]> {\n if (this.serverCapabilities?.tools?.listChanged) {\n this.client.setNotificationHandler(\n ToolListChangedNotificationSchema,\n async (_notification) => {\n this.tools = await this.fetchTools();\n }\n );\n }\n\n return this.fetchTools();\n }\n\n /**\n * Notification handler registration for resources\n * Should only be called if serverCapabilities.resources exists\n */\n async registerResources(): Promise<Resource[]> {\n if (this.serverCapabilities?.resources?.listChanged) {\n this.client.setNotificationHandler(\n ResourceListChangedNotificationSchema,\n async (_notification) => {\n this.resources = await this.fetchResources();\n }\n );\n }\n\n return this.fetchResources();\n }\n\n /**\n * Notification handler registration for prompts\n * Should only be called if serverCapabilities.prompts exists\n */\n async registerPrompts(): Promise<Prompt[]> {\n if (this.serverCapabilities?.prompts?.listChanged) {\n this.client.setNotificationHandler(\n PromptListChangedNotificationSchema,\n async (_notification) => {\n this.prompts = await this.fetchPrompts();\n }\n );\n }\n\n return this.fetchPrompts();\n }\n\n async registerResourceTemplates(): Promise<ResourceTemplate[]> {\n return this.fetchResourceTemplates();\n }\n\n async fetchTools() {\n let toolsAgg: Tool[] = [];\n let toolsResult: ListToolsResult = { tools: [] };\n do {\n toolsResult = await this.client\n .listTools({\n cursor: toolsResult.nextCursor\n })\n .catch(this._capabilityErrorHandler({ tools: [] }, \"tools/list\"));\n toolsAgg = toolsAgg.concat(toolsResult.tools);\n } while (toolsResult.nextCursor);\n return toolsAgg;\n }\n\n async fetchResources() {\n let resourcesAgg: Resource[] = [];\n let resourcesResult: ListResourcesResult = { resources: [] };\n do {\n resourcesResult = await this.client\n .listResources({\n cursor: resourcesResult.nextCursor\n })\n .catch(\n this._capabilityErrorHandler({ resources: [] }, \"resources/list\")\n );\n resourcesAgg = resourcesAgg.concat(resourcesResult.resources);\n } while (resourcesResult.nextCursor);\n return resourcesAgg;\n }\n\n async fetchPrompts() {\n let promptsAgg: Prompt[] = [];\n let promptsResult: ListPromptsResult = { prompts: [] };\n do {\n promptsResult = await this.client\n .listPrompts({\n cursor: promptsResult.nextCursor\n })\n .catch(this._capabilityErrorHandler({ prompts: [] }, \"prompts/list\"));\n promptsAgg = promptsAgg.concat(promptsResult.prompts);\n } while (promptsResult.nextCursor);\n return promptsAgg;\n }\n\n async fetchResourceTemplates() {\n let templatesAgg: ResourceTemplate[] = [];\n let templatesResult: ListResourceTemplatesResult = {\n resourceTemplates: []\n };\n do {\n templatesResult = await this.client\n .listResourceTemplates({\n cursor: templatesResult.nextCursor\n })\n .catch(\n this._capabilityErrorHandler(\n { resourceTemplates: [] },\n \"resources/templates/list\"\n )\n );\n templatesAgg = templatesAgg.concat(templatesResult.resourceTemplates);\n } while (templatesResult.nextCursor);\n return templatesAgg;\n }\n\n /**\n * Handle elicitation request from server\n * Automatically uses the Agent's built-in elicitation handling if available\n */\n async handleElicitationRequest(\n _request: ElicitRequest\n ): Promise<ElicitResult> {\n // Elicitation handling must be implemented by the platform\n // For MCP servers, this should be handled by McpAgent.elicitInput()\n throw new Error(\n \"Elicitation handler must be implemented for your platform. Override handleElicitationRequest method.\"\n );\n }\n /**\n * Get the transport for the client\n * @param transportType - The transport type to get\n * @returns The transport for the client\n */\n getTransport(transportType: BaseTransportType) {\n switch (transportType) {\n case \"streamable-http\":\n return new StreamableHTTPClientTransport(\n this.url,\n this.options.transport as StreamableHTTPClientTransportOptions\n );\n case \"sse\":\n return new SSEClientTransport(\n this.url,\n this.options.transport as SSEClientTransportOptions\n );\n default:\n throw new Error(`Unsupported transport type: ${transportType}`);\n }\n }\n\n private async tryConnect(\n transportType: TransportType\n ): Promise<MCPClientConnectionResult> {\n const transports: BaseTransportType[] =\n transportType === \"auto\" ? [\"streamable-http\", \"sse\"] : [transportType];\n\n for (const currentTransportType of transports) {\n const isLastTransport =\n currentTransportType === transports[transports.length - 1];\n const hasFallback =\n transportType === \"auto\" &&\n currentTransportType === \"streamable-http\" &&\n !isLastTransport;\n\n const transport = this.getTransport(currentTransportType);\n\n try {\n await this.client.connect(transport);\n\n return {\n state: MCPConnectionState.CONNECTED,\n transport: currentTransportType\n };\n } catch (e) {\n const error = e instanceof Error ? e : new Error(String(e));\n\n if (isUnauthorized(error)) {\n return {\n state: MCPConnectionState.AUTHENTICATING\n };\n }\n\n if (isTransportNotImplemented(error) && hasFallback) {\n // Try the next transport\n continue;\n }\n\n return {\n state: MCPConnectionState.FAILED,\n error\n };\n }\n }\n\n // Should never reach here\n return {\n state: MCPConnectionState.FAILED,\n error: new Error(\"No transports available\")\n };\n }\n\n private _capabilityErrorHandler<T>(empty: T, method: string) {\n return (e: { code: number }) => {\n // server is badly behaved and returning invalid capabilities. This commonly occurs for resource templates\n if (e.code === -32601) {\n const url = this.url.toString();\n this._onObservabilityEvent.fire({\n type: \"mcp:client:discover\",\n displayMessage: `The server advertised support for the capability ${method.split(\"/\")[0]}, but returned \"Method not found\" for '${method}' for ${url}`,\n payload: {\n url,\n capability: method.split(\"/\")[0],\n error: toErrorMessage(e)\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n return empty;\n }\n throw e;\n };\n }\n}\n"],"mappings":"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"}