agents 0.0.0-1e060d3 → 0.0.0-1e4188c

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 (56) hide show
  1. package/README.md +131 -25
  2. package/dist/ai-chat-agent.d.ts +54 -8
  3. package/dist/ai-chat-agent.js +259 -90
  4. package/dist/ai-chat-agent.js.map +1 -1
  5. package/dist/ai-chat-v5-migration.d.ts +152 -0
  6. package/dist/ai-chat-v5-migration.js +19 -0
  7. package/dist/ai-react.d.ts +71 -67
  8. package/dist/ai-react.js +179 -61
  9. package/dist/ai-react.js.map +1 -1
  10. package/dist/ai-types.d.ts +40 -18
  11. package/dist/ai-types.js +6 -0
  12. package/dist/chunk-AVYJQSLW.js +17 -0
  13. package/dist/chunk-AVYJQSLW.js.map +1 -0
  14. package/dist/chunk-HKY5L652.js +1301 -0
  15. package/dist/chunk-HKY5L652.js.map +1 -0
  16. package/dist/chunk-PVQZBKN7.js +106 -0
  17. package/dist/chunk-PVQZBKN7.js.map +1 -0
  18. package/dist/chunk-QEVM4BVL.js +116 -0
  19. package/dist/chunk-QEVM4BVL.js.map +1 -0
  20. package/dist/chunk-UJVEAURM.js +150 -0
  21. package/dist/chunk-UJVEAURM.js.map +1 -0
  22. package/dist/chunk-VYENMKFS.js +612 -0
  23. package/dist/chunk-VYENMKFS.js.map +1 -0
  24. package/dist/client-B9tFv5gX.d.ts +4607 -0
  25. package/dist/client.d.ts +16 -2
  26. package/dist/client.js +7 -126
  27. package/dist/client.js.map +1 -1
  28. package/dist/index.d.ts +274 -21
  29. package/dist/index.js +17 -6
  30. package/dist/mcp/client.d.ts +9 -761
  31. package/dist/mcp/client.js +3 -402
  32. package/dist/mcp/client.js.map +1 -1
  33. package/dist/mcp/do-oauth-client-provider.d.ts +3 -3
  34. package/dist/mcp/do-oauth-client-provider.js +3 -103
  35. package/dist/mcp/do-oauth-client-provider.js.map +1 -1
  36. package/dist/mcp/index.d.ts +63 -11
  37. package/dist/mcp/index.js +371 -188
  38. package/dist/mcp/index.js.map +1 -1
  39. package/dist/observability/index.d.ts +46 -0
  40. package/dist/observability/index.js +11 -0
  41. package/dist/observability/index.js.map +1 -0
  42. package/dist/react.d.ts +89 -5
  43. package/dist/react.js +23 -9
  44. package/dist/react.js.map +1 -1
  45. package/dist/schedule.d.ts +81 -7
  46. package/dist/schedule.js +19 -8
  47. package/dist/schedule.js.map +1 -1
  48. package/dist/serializable.d.ts +32 -0
  49. package/dist/serializable.js +1 -0
  50. package/dist/serializable.js.map +1 -0
  51. package/package.json +83 -56
  52. package/src/index.ts +1170 -144
  53. package/dist/chunk-HMLY7DHA.js +0 -16
  54. package/dist/chunk-XG52S6YY.js +0 -591
  55. package/dist/chunk-XG52S6YY.js.map +0 -1
  56. /package/dist/{chunk-HMLY7DHA.js.map → ai-chat-v5-migration.js.map} +0 -0
package/dist/mcp/index.js CHANGED
@@ -1,55 +1,63 @@
1
1
  import {
2
2
  Agent
3
- } from "../chunk-XG52S6YY.js";
3
+ } from "../chunk-HKY5L652.js";
4
4
  import {
5
- __privateAdd,
6
- __privateGet,
7
- __privateMethod,
8
- __privateSet
9
- } from "../chunk-HMLY7DHA.js";
5
+ SSEEdgeClientTransport,
6
+ StreamableHTTPEdgeClientTransport
7
+ } from "../chunk-VYENMKFS.js";
8
+ import "../chunk-PVQZBKN7.js";
9
+ import "../chunk-QEVM4BVL.js";
10
+ import "../chunk-AVYJQSLW.js";
10
11
 
11
12
  // src/mcp/index.ts
12
13
  import { DurableObject } from "cloudflare:workers";
13
14
  import {
14
15
  InitializeRequestSchema,
16
+ JSONRPCMessageSchema,
15
17
  isJSONRPCError,
16
18
  isJSONRPCNotification,
17
19
  isJSONRPCRequest,
18
- isJSONRPCResponse,
19
- JSONRPCMessageSchema
20
+ isJSONRPCResponse
21
+ } from "@modelcontextprotocol/sdk/types.js";
22
+ import {
23
+ ElicitRequestSchema
20
24
  } from "@modelcontextprotocol/sdk/types.js";
21
25
  var MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
22
- function handleCORS(request, corsOptions) {
23
- const origin = request.headers.get("Origin") || "*";
24
- const corsHeaders = {
25
- "Access-Control-Allow-Origin": corsOptions?.origin || origin,
26
- "Access-Control-Allow-Methods": corsOptions?.methods || "GET, POST, OPTIONS",
27
- "Access-Control-Allow-Headers": corsOptions?.headers || "Content-Type",
28
- "Access-Control-Max-Age": (corsOptions?.maxAge || 86400).toString()
26
+ function corsHeaders(_request, corsOptions = {}) {
27
+ const origin = "*";
28
+ return {
29
+ "Access-Control-Allow-Headers": corsOptions.headers || "Content-Type, mcp-session-id, mcp-protocol-version",
30
+ "Access-Control-Allow-Methods": corsOptions.methods || "GET, POST, OPTIONS",
31
+ "Access-Control-Allow-Origin": corsOptions.origin || origin,
32
+ "Access-Control-Expose-Headers": corsOptions.exposeHeaders || "mcp-session-id",
33
+ "Access-Control-Max-Age": (corsOptions.maxAge || 86400).toString()
29
34
  };
35
+ }
36
+ function isDurableObjectNamespace(namespace) {
37
+ return typeof namespace === "object" && namespace !== null && "newUniqueId" in namespace && typeof namespace.newUniqueId === "function" && "idFromName" in namespace && typeof namespace.idFromName === "function";
38
+ }
39
+ function handleCORS(request, corsOptions) {
30
40
  if (request.method === "OPTIONS") {
31
- return new Response(null, { headers: corsHeaders });
41
+ return new Response(null, { headers: corsHeaders(request, corsOptions) });
32
42
  }
33
43
  return null;
34
44
  }
35
- var _getWebSocket, _started;
36
45
  var McpSSETransport = class {
37
46
  constructor(getWebSocket) {
38
- __privateAdd(this, _getWebSocket);
39
- __privateAdd(this, _started, false);
40
- __privateSet(this, _getWebSocket, getWebSocket);
47
+ this._started = false;
48
+ this._getWebSocket = getWebSocket;
41
49
  }
42
50
  async start() {
43
- if (__privateGet(this, _started)) {
51
+ if (this._started) {
44
52
  throw new Error("Transport already started");
45
53
  }
46
- __privateSet(this, _started, true);
54
+ this._started = true;
47
55
  }
48
56
  async send(message) {
49
- if (!__privateGet(this, _started)) {
57
+ if (!this._started) {
50
58
  throw new Error("Transport not started");
51
59
  }
52
- const websocket = __privateGet(this, _getWebSocket).call(this);
60
+ const websocket = this._getWebSocket();
53
61
  if (!websocket) {
54
62
  throw new Error("WebSocket not connected");
55
63
  }
@@ -64,52 +72,40 @@ var McpSSETransport = class {
64
72
  this.onclose?.();
65
73
  }
66
74
  };
67
- _getWebSocket = new WeakMap();
68
- _started = new WeakMap();
69
- var _getWebSocketForGetRequest, _getWebSocketForMessageID, _notifyResponseIdSent, _started2;
70
75
  var McpStreamableHttpTransport = class {
71
76
  constructor(getWebSocketForMessageID, notifyResponseIdSent) {
72
- // TODO: If there is an open connection to send server-initiated messages
73
- // back, we should use that connection
74
- __privateAdd(this, _getWebSocketForGetRequest);
75
- // Get the appropriate websocket connection for a given message id
76
- __privateAdd(this, _getWebSocketForMessageID);
77
- // Notify the server that a response has been sent for a given message id
78
- // so that it may clean up it's mapping of message ids to connections
79
- // once they are no longer needed
80
- __privateAdd(this, _notifyResponseIdSent);
81
- __privateAdd(this, _started2, false);
82
- __privateSet(this, _getWebSocketForMessageID, getWebSocketForMessageID);
83
- __privateSet(this, _notifyResponseIdSent, notifyResponseIdSent);
84
- __privateSet(this, _getWebSocketForGetRequest, () => null);
77
+ this._started = false;
78
+ this._getWebSocketForMessageID = getWebSocketForMessageID;
79
+ this._notifyResponseIdSent = notifyResponseIdSent;
80
+ this._getWebSocketForGetRequest = () => null;
85
81
  }
86
82
  async start() {
87
- if (__privateGet(this, _started2)) {
83
+ if (this._started) {
88
84
  throw new Error("Transport already started");
89
85
  }
90
- __privateSet(this, _started2, true);
86
+ this._started = true;
91
87
  }
92
88
  async send(message) {
93
- if (!__privateGet(this, _started2)) {
89
+ if (!this._started) {
94
90
  throw new Error("Transport not started");
95
91
  }
96
92
  let websocket = null;
97
93
  if (isJSONRPCResponse(message) || isJSONRPCError(message)) {
98
- websocket = __privateGet(this, _getWebSocketForMessageID).call(this, message.id.toString());
94
+ websocket = this._getWebSocketForMessageID(message.id.toString());
99
95
  if (!websocket) {
100
96
  throw new Error(
101
97
  `Could not find WebSocket for message id: ${message.id}`
102
98
  );
103
99
  }
104
100
  } else if (isJSONRPCRequest(message)) {
105
- websocket = __privateGet(this, _getWebSocketForGetRequest).call(this);
101
+ websocket = this._getWebSocketForGetRequest();
106
102
  } else if (isJSONRPCNotification(message)) {
107
103
  websocket = null;
108
104
  }
109
105
  try {
110
106
  websocket?.send(JSON.stringify(message));
111
107
  if (isJSONRPCResponse(message)) {
112
- __privateGet(this, _notifyResponseIdSent).call(this, message.id.toString());
108
+ this._notifyResponseIdSent(message.id.toString());
113
109
  }
114
110
  } catch (error) {
115
111
  this.onerror?.(error);
@@ -120,28 +116,16 @@ var McpStreamableHttpTransport = class {
120
116
  this.onclose?.();
121
117
  }
122
118
  };
123
- _getWebSocketForGetRequest = new WeakMap();
124
- _getWebSocketForMessageID = new WeakMap();
125
- _notifyResponseIdSent = new WeakMap();
126
- _started2 = new WeakMap();
127
- var _status, _transport, _transportType, _requestIdToConnectionId, _agent, _McpAgent_instances, initialize_fn;
128
- var _McpAgent = class _McpAgent extends DurableObject {
119
+ var McpAgent = class _McpAgent extends DurableObject {
129
120
  constructor(ctx, env) {
130
121
  var _a;
131
122
  super(ctx, env);
132
- __privateAdd(this, _McpAgent_instances);
133
- __privateAdd(this, _status, "zero");
134
- __privateAdd(this, _transport);
135
- __privateAdd(this, _transportType, "unset");
136
- __privateAdd(this, _requestIdToConnectionId, /* @__PURE__ */ new Map());
137
- /**
138
- * Since McpAgent's _aren't_ yet real "Agents", let's only expose a couple of the methods
139
- * to the outer class: initialState/state/setState/onStateUpdate/sql
140
- */
141
- __privateAdd(this, _agent);
123
+ this._status = "zero";
124
+ this._transportType = "unset";
125
+ this._requestIdToConnectionId = /* @__PURE__ */ new Map();
142
126
  this.initRun = false;
143
127
  const self = this;
144
- __privateSet(this, _agent, new (_a = class extends Agent {
128
+ this._agent = new (_a = class extends Agent {
145
129
  onStateUpdate(state, source) {
146
130
  return self.onStateUpdate(state, source);
147
131
  }
@@ -150,23 +134,66 @@ var _McpAgent = class _McpAgent extends DurableObject {
150
134
  }
151
135
  }, _a.options = {
152
136
  hibernate: true
153
- }, _a)(ctx, env));
137
+ }, _a)(ctx, env);
138
+ }
139
+ get mcp() {
140
+ return this._agent.mcp;
154
141
  }
155
142
  get state() {
156
- return __privateGet(this, _agent).state;
143
+ return this._agent.state;
157
144
  }
158
145
  sql(strings, ...values) {
159
- return __privateGet(this, _agent).sql(strings, ...values);
146
+ return this._agent.sql(strings, ...values);
160
147
  }
161
148
  setState(state) {
162
- return __privateGet(this, _agent).setState(state);
149
+ return this._agent.setState(state);
150
+ }
151
+ /**
152
+ * Elicit user input with a message and schema
153
+ */
154
+ async elicitInput(params) {
155
+ const requestId = `elicit_${Math.random().toString(36).substring(2, 11)}`;
156
+ await this.ctx.storage.put(`elicitation:${requestId}`, {
157
+ message: params.message,
158
+ requestedSchema: params.requestedSchema,
159
+ timestamp: Date.now()
160
+ });
161
+ const elicitRequest = {
162
+ jsonrpc: "2.0",
163
+ id: requestId,
164
+ method: "elicitation/create",
165
+ params: {
166
+ message: params.message,
167
+ requestedSchema: params.requestedSchema
168
+ }
169
+ };
170
+ if (this._transport) {
171
+ await this._transport.send(elicitRequest);
172
+ } else {
173
+ const connections = this._agent?.getConnections();
174
+ if (!connections || Array.from(connections).length === 0) {
175
+ await this.ctx.storage.delete(`elicitation:${requestId}`);
176
+ throw new Error("No active connections available for elicitation");
177
+ }
178
+ const connectionList = Array.from(connections);
179
+ for (const connection of connectionList) {
180
+ try {
181
+ connection.send(JSON.stringify(elicitRequest));
182
+ } catch (error) {
183
+ console.error("Failed to send elicitation request:", error);
184
+ }
185
+ }
186
+ }
187
+ return this._waitForElicitationResponse(requestId);
163
188
  }
189
+ // we leave the variables as unused for autocomplete purposes
190
+ // biome-ignore lint/correctness/noUnusedFunctionParameters: overriden later
164
191
  onStateUpdate(state, source) {
165
192
  }
166
193
  async onStart() {
167
194
  var _a;
168
195
  const self = this;
169
- __privateSet(this, _agent, new (_a = class extends Agent {
196
+ this._agent = new (_a = class extends Agent {
170
197
  constructor() {
171
198
  super(...arguments);
172
199
  this.initialState = self.initialState;
@@ -179,39 +206,73 @@ var _McpAgent = class _McpAgent extends DurableObject {
179
206
  }
180
207
  }, _a.options = {
181
208
  hibernate: true
182
- }, _a)(this.ctx, this.env));
209
+ }, _a)(this.ctx, this.env);
183
210
  this.props = await this.ctx.storage.get("props");
184
- __privateSet(this, _transportType, await this.ctx.storage.get(
211
+ this._transportType = await this.ctx.storage.get(
185
212
  "transportType"
186
- ));
187
- this.init?.();
188
- if (__privateGet(this, _transportType) === "sse") {
189
- __privateSet(this, _transport, new McpSSETransport(() => this.getWebSocket()));
190
- await this.server.connect(__privateGet(this, _transport));
191
- } else if (__privateGet(this, _transportType) === "streamable-http") {
192
- __privateSet(this, _transport, new McpStreamableHttpTransport(
213
+ );
214
+ await this._init(this.props);
215
+ const server = await this.server;
216
+ if (this._transportType === "sse") {
217
+ this._transport = new McpSSETransport(() => this.getWebSocket());
218
+ await server.connect(this._transport);
219
+ } else if (this._transportType === "streamable-http") {
220
+ this._transport = new McpStreamableHttpTransport(
193
221
  (id) => this.getWebSocketForResponseID(id),
194
- (id) => __privateGet(this, _requestIdToConnectionId).delete(id)
195
- ));
196
- await this.server.connect(__privateGet(this, _transport));
222
+ (id) => this._requestIdToConnectionId.delete(id)
223
+ );
224
+ await server.connect(this._transport);
197
225
  }
198
226
  }
227
+ /**
228
+ * Handle errors that occur during initialization or operation.
229
+ * Override this method to provide custom error handling.
230
+ * @param error - The error that occurred
231
+ * @returns An error response object with status code and message
232
+ */
233
+ onError(error) {
234
+ console.error("McpAgent error:", error);
235
+ return {
236
+ status: 500,
237
+ message: error.message || "An unexpected error occurred during initialization"
238
+ };
239
+ }
199
240
  async _init(props) {
200
- await this.ctx.storage.put("props", props ?? {});
201
- await this.ctx.storage.put("transportType", "unset");
202
- this.props = props;
241
+ await this.updateProps(props);
242
+ if (!this.ctx.storage.get("transportType")) {
243
+ await this.ctx.storage.put("transportType", "unset");
244
+ }
203
245
  if (!this.initRun) {
204
246
  this.initRun = true;
205
- await this.init();
247
+ try {
248
+ await this.init();
249
+ } catch (error) {
250
+ const errorResponse = this.onError(error);
251
+ throw new Error(`Initialization failed: ${errorResponse.message}`);
252
+ }
206
253
  }
207
254
  }
208
- isInitialized() {
209
- return this.initRun;
255
+ async setInitialized() {
256
+ await this.ctx.storage.put("initialized", true);
257
+ }
258
+ async isInitialized() {
259
+ return await this.ctx.storage.get("initialized") === true;
260
+ }
261
+ async updateProps(props) {
262
+ await this.ctx.storage.put("props", props ?? {});
263
+ this.props = props;
264
+ }
265
+ async _initialize() {
266
+ await this.ctx.blockConcurrencyWhile(async () => {
267
+ this._status = "starting";
268
+ await this.onStart();
269
+ this._status = "started";
270
+ });
210
271
  }
211
272
  // Allow the worker to fetch a websocket connection to the agent
212
273
  async fetch(request) {
213
- if (__privateGet(this, _status) !== "started") {
214
- await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
274
+ if (this._status !== "started") {
275
+ await this._initialize();
215
276
  }
216
277
  if (request.headers.get("Upgrade") !== "websocket") {
217
278
  return new Response("Expected WebSocket Upgrade request", {
@@ -220,6 +281,7 @@ var _McpAgent = class _McpAgent extends DurableObject {
220
281
  }
221
282
  const url = new URL(request.url);
222
283
  const path = url.pathname;
284
+ const server = await this.server;
223
285
  switch (path) {
224
286
  case "/sse": {
225
287
  const websockets = this.ctx.getWebSockets();
@@ -227,24 +289,24 @@ var _McpAgent = class _McpAgent extends DurableObject {
227
289
  return new Response("Websocket already connected", { status: 400 });
228
290
  }
229
291
  await this.ctx.storage.put("transportType", "sse");
230
- __privateSet(this, _transportType, "sse");
231
- if (!__privateGet(this, _transport)) {
232
- __privateSet(this, _transport, new McpSSETransport(() => this.getWebSocket()));
233
- await this.server.connect(__privateGet(this, _transport));
292
+ this._transportType = "sse";
293
+ if (!this._transport) {
294
+ this._transport = new McpSSETransport(() => this.getWebSocket());
295
+ await server.connect(this._transport);
234
296
  }
235
- return __privateGet(this, _agent).fetch(request);
297
+ return this._agent.fetch(request);
236
298
  }
237
299
  case "/streamable-http": {
238
- if (!__privateGet(this, _transport)) {
239
- __privateSet(this, _transport, new McpStreamableHttpTransport(
300
+ if (!this._transport) {
301
+ this._transport = new McpStreamableHttpTransport(
240
302
  (id) => this.getWebSocketForResponseID(id),
241
- (id) => __privateGet(this, _requestIdToConnectionId).delete(id)
242
- ));
243
- await this.server.connect(__privateGet(this, _transport));
303
+ (id) => this._requestIdToConnectionId.delete(id)
304
+ );
305
+ await server.connect(this._transport);
244
306
  }
245
307
  await this.ctx.storage.put("transportType", "streamable-http");
246
- __privateSet(this, _transportType, "streamable-http");
247
- return __privateGet(this, _agent).fetch(request);
308
+ this._transportType = "streamable-http";
309
+ return this._agent.fetch(request);
248
310
  }
249
311
  default:
250
312
  return new Response(
@@ -263,19 +325,19 @@ var _McpAgent = class _McpAgent extends DurableObject {
263
325
  return websockets[0];
264
326
  }
265
327
  getWebSocketForResponseID(id) {
266
- const connectionId = __privateGet(this, _requestIdToConnectionId).get(id);
328
+ const connectionId = this._requestIdToConnectionId.get(id);
267
329
  if (connectionId === void 0) {
268
330
  return null;
269
331
  }
270
- return __privateGet(this, _agent).getConnection(connectionId) ?? null;
332
+ return this._agent.getConnection(connectionId) ?? null;
271
333
  }
272
334
  // All messages received here. This is currently never called
273
335
  async onMessage(connection, event) {
274
- if (__privateGet(this, _transportType) !== "streamable-http") {
336
+ if (this._transportType !== "streamable-http") {
275
337
  const err = new Error(
276
338
  "Internal Server Error: Expected streamable-http protocol"
277
339
  );
278
- __privateGet(this, _transport)?.onerror?.(err);
340
+ this._transport?.onerror?.(err);
279
341
  return;
280
342
  }
281
343
  let message;
@@ -283,58 +345,125 @@ var _McpAgent = class _McpAgent extends DurableObject {
283
345
  const data = typeof event === "string" ? event : new TextDecoder().decode(event);
284
346
  message = JSONRPCMessageSchema.parse(JSON.parse(data));
285
347
  } catch (error) {
286
- __privateGet(this, _transport)?.onerror?.(error);
348
+ this._transport?.onerror?.(error);
349
+ return;
350
+ }
351
+ if (await this._handleElicitationResponse(message)) {
287
352
  return;
288
353
  }
289
354
  if (isJSONRPCRequest(message)) {
290
- __privateGet(this, _requestIdToConnectionId).set(message.id.toString(), connection.id);
355
+ this._requestIdToConnectionId.set(message.id.toString(), connection.id);
291
356
  }
292
- __privateGet(this, _transport)?.onmessage?.(message);
357
+ this._transport?.onmessage?.(message);
358
+ }
359
+ /**
360
+ * Wait for elicitation response through storage polling
361
+ */
362
+ async _waitForElicitationResponse(requestId) {
363
+ const startTime = Date.now();
364
+ const timeout = 6e4;
365
+ try {
366
+ while (Date.now() - startTime < timeout) {
367
+ const response = await this.ctx.storage.get(
368
+ `elicitation:response:${requestId}`
369
+ );
370
+ if (response) {
371
+ await this.ctx.storage.delete(`elicitation:${requestId}`);
372
+ await this.ctx.storage.delete(`elicitation:response:${requestId}`);
373
+ return response;
374
+ }
375
+ await new Promise((resolve) => setTimeout(resolve, 100));
376
+ }
377
+ throw new Error("Elicitation request timed out");
378
+ } finally {
379
+ await this.ctx.storage.delete(`elicitation:${requestId}`);
380
+ await this.ctx.storage.delete(`elicitation:response:${requestId}`);
381
+ }
382
+ }
383
+ /**
384
+ * Handle elicitation responses */
385
+ async _handleElicitationResponse(message) {
386
+ if (isJSONRPCResponse(message) && message.result) {
387
+ const requestId = message.id?.toString();
388
+ if (!requestId || !requestId.startsWith("elicit_")) return false;
389
+ const pendingRequest = await this.ctx.storage.get(
390
+ `elicitation:${requestId}`
391
+ );
392
+ if (!pendingRequest) return false;
393
+ await this.ctx.storage.put(
394
+ `elicitation:response:${requestId}`,
395
+ message.result
396
+ );
397
+ return true;
398
+ }
399
+ if (isJSONRPCError(message)) {
400
+ const requestId = message.id?.toString();
401
+ if (!requestId || !requestId.startsWith("elicit_")) return false;
402
+ const pendingRequest = await this.ctx.storage.get(
403
+ `elicitation:${requestId}`
404
+ );
405
+ if (!pendingRequest) return false;
406
+ const errorResult = {
407
+ action: "cancel",
408
+ content: {
409
+ error: message.error.message || "Elicitation request failed"
410
+ }
411
+ };
412
+ await this.ctx.storage.put(
413
+ `elicitation:response:${requestId}`,
414
+ errorResult
415
+ );
416
+ return true;
417
+ }
418
+ return false;
293
419
  }
294
420
  // All messages received over SSE after the initial connection has been established
295
421
  // will be passed here
296
- async onSSEMcpMessage(sessionId, request) {
297
- if (__privateGet(this, _status) !== "started") {
298
- await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
422
+ async onSSEMcpMessage(_sessionId, messageBody) {
423
+ if (this._status !== "started") {
424
+ await this._initialize();
299
425
  }
300
- if (__privateGet(this, _transportType) !== "sse") {
426
+ if (this._transportType !== "sse") {
301
427
  return new Error("Internal Server Error: Expected SSE protocol");
302
428
  }
303
429
  try {
304
- const message = await request.json();
305
430
  let parsedMessage;
306
431
  try {
307
- parsedMessage = JSONRPCMessageSchema.parse(message);
432
+ parsedMessage = JSONRPCMessageSchema.parse(messageBody);
308
433
  } catch (error) {
309
- __privateGet(this, _transport)?.onerror?.(error);
434
+ this._transport?.onerror?.(error);
310
435
  throw error;
311
436
  }
312
- __privateGet(this, _transport)?.onmessage?.(parsedMessage);
437
+ if (await this._handleElicitationResponse(parsedMessage)) {
438
+ return null;
439
+ }
440
+ this._transport?.onmessage?.(parsedMessage);
313
441
  return null;
314
442
  } catch (error) {
315
- __privateGet(this, _transport)?.onerror?.(error);
443
+ console.error("Error forwarding message to SSE:", error);
444
+ this._transport?.onerror?.(error);
316
445
  return error;
317
446
  }
318
447
  }
319
448
  // Delegate all websocket events to the underlying agent
320
449
  async webSocketMessage(ws, event) {
321
- if (__privateGet(this, _status) !== "started") {
322
- await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
450
+ if (this._status !== "started") {
451
+ await this._initialize();
323
452
  }
324
- return await __privateGet(this, _agent).webSocketMessage(ws, event);
453
+ return await this._agent.webSocketMessage(ws, event);
325
454
  }
326
455
  // WebSocket event handlers for hibernation support
327
456
  async webSocketError(ws, error) {
328
- if (__privateGet(this, _status) !== "started") {
329
- await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
457
+ if (this._status !== "started") {
458
+ await this._initialize();
330
459
  }
331
- return await __privateGet(this, _agent).webSocketError(ws, error);
460
+ return await this._agent.webSocketError(ws, error);
332
461
  }
333
462
  async webSocketClose(ws, code, reason, wasClean) {
334
- if (__privateGet(this, _status) !== "started") {
335
- await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
463
+ if (this._status !== "started") {
464
+ await this._initialize();
336
465
  }
337
- return await __privateGet(this, _agent).webSocketClose(ws, code, reason, wasClean);
466
+ return await this._agent.webSocketClose(ws, code, reason, wasClean);
338
467
  }
339
468
  static mount(path, {
340
469
  binding = "MCP_OBJECT",
@@ -353,29 +482,57 @@ var _McpAgent = class _McpAgent extends DurableObject {
353
482
  const basePattern = new URLPattern({ pathname });
354
483
  const messagePattern = new URLPattern({ pathname: `${pathname}/message` });
355
484
  return {
356
- fetch: async (request, env, ctx) => {
485
+ async fetch(request, env, ctx) {
357
486
  const corsResponse = handleCORS(request, corsOptions);
358
487
  if (corsResponse) return corsResponse;
359
488
  const url = new URL(request.url);
360
- const namespace = env[binding];
489
+ const bindingValue = env[binding];
490
+ if (bindingValue == null || typeof bindingValue !== "object") {
491
+ console.error(
492
+ `Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`
493
+ );
494
+ return new Response("Invalid binding", { status: 500 });
495
+ }
496
+ if (!isDurableObjectNamespace(bindingValue)) {
497
+ return new Response("Invalid binding", { status: 500 });
498
+ }
499
+ const namespace = bindingValue;
361
500
  if (request.method === "GET" && basePattern.test(url)) {
362
501
  const sessionId = url.searchParams.get("sessionId") || namespace.newUniqueId().toString();
363
502
  const { readable, writable } = new TransformStream();
364
503
  const writer = writable.getWriter();
365
504
  const encoder = new TextEncoder();
505
+ const endpointUrl = new URL(request.url);
506
+ endpointUrl.pathname = encodeURI(`${pathname}/message`);
507
+ endpointUrl.searchParams.set("sessionId", sessionId);
508
+ const relativeUrlWithSession = endpointUrl.pathname + endpointUrl.search + endpointUrl.hash;
366
509
  const endpointMessage = `event: endpoint
367
- data: ${encodeURI(`${pathname}/message`)}?sessionId=${sessionId}
510
+ data: ${relativeUrlWithSession}
368
511
 
369
512
  `;
370
513
  writer.write(encoder.encode(endpointMessage));
371
514
  const id = namespace.idFromName(`sse:${sessionId}`);
372
515
  const doStub = namespace.get(id);
373
- await doStub._init(ctx.props);
516
+ try {
517
+ await doStub._init(ctx.props);
518
+ } catch (error) {
519
+ console.error("Failed to initialize McpAgent:", error);
520
+ await writer.close();
521
+ const errorMessage = error instanceof Error ? error.message : String(error);
522
+ return new Response(`Initialization failed: ${errorMessage}`, {
523
+ status: 500
524
+ });
525
+ }
374
526
  const upgradeUrl = new URL(request.url);
375
527
  upgradeUrl.pathname = "/sse";
528
+ const existingHeaders = {};
529
+ request.headers.forEach((value, key) => {
530
+ existingHeaders[key] = value;
531
+ });
376
532
  const response = await doStub.fetch(
377
533
  new Request(upgradeUrl, {
378
534
  headers: {
535
+ ...existingHeaders,
379
536
  Upgrade: "websocket",
380
537
  // Required by PartyServer
381
538
  "x-partykit-room": sessionId
@@ -411,10 +568,10 @@ data: ${JSON.stringify(result.data)}
411
568
  onMessage(event).catch(console.error);
412
569
  });
413
570
  ws.addEventListener("error", (error) => {
414
- async function onError(error2) {
571
+ async function onError(_error) {
415
572
  try {
416
573
  await writer.close();
417
- } catch (e) {
574
+ } catch (_e) {
418
575
  }
419
576
  }
420
577
  onError(error).catch(console.error);
@@ -431,10 +588,10 @@ data: ${JSON.stringify(result.data)}
431
588
  });
432
589
  return new Response(readable, {
433
590
  headers: {
434
- "Content-Type": "text/event-stream",
435
591
  "Cache-Control": "no-cache",
436
592
  Connection: "keep-alive",
437
- "Access-Control-Allow-Origin": corsOptions?.origin || "*"
593
+ "Content-Type": "text/event-stream",
594
+ ...corsHeaders(request, corsOptions)
438
595
  }
439
596
  });
440
597
  }
@@ -466,26 +623,28 @@ data: ${JSON.stringify(result.data)}
466
623
  }
467
624
  const id = namespace.idFromName(`sse:${sessionId}`);
468
625
  const doStub = namespace.get(id);
469
- const error = await doStub.onSSEMcpMessage(sessionId, request);
626
+ const messageBody = await request.json();
627
+ await doStub.updateProps(ctx.props);
628
+ const error = await doStub.onSSEMcpMessage(sessionId, messageBody);
470
629
  if (error) {
471
630
  return new Response(error.message, {
472
- status: 400,
473
631
  headers: {
474
- "Content-Type": "text/event-stream",
475
632
  "Cache-Control": "no-cache",
476
633
  Connection: "keep-alive",
477
- "Access-Control-Allow-Origin": corsOptions?.origin || "*"
478
- }
634
+ "Content-Type": "text/event-stream",
635
+ ...corsHeaders(request, corsOptions)
636
+ },
637
+ status: 400
479
638
  });
480
639
  }
481
640
  return new Response("Accepted", {
482
- status: 202,
483
641
  headers: {
484
- "Content-Type": "text/event-stream",
485
642
  "Cache-Control": "no-cache",
486
643
  Connection: "keep-alive",
487
- "Access-Control-Allow-Origin": corsOptions?.origin || "*"
488
- }
644
+ "Content-Type": "text/event-stream",
645
+ ...corsHeaders(request, corsOptions)
646
+ },
647
+ status: 202
489
648
  });
490
649
  }
491
650
  return new Response("Not Found", { status: 404 });
@@ -502,35 +661,45 @@ data: ${JSON.stringify(result.data)}
502
661
  }
503
662
  const basePattern = new URLPattern({ pathname });
504
663
  return {
505
- fetch: async (request, env, ctx) => {
664
+ async fetch(request, env, ctx) {
506
665
  const corsResponse = handleCORS(request, corsOptions);
507
666
  if (corsResponse) {
508
667
  return corsResponse;
509
668
  }
510
669
  const url = new URL(request.url);
511
- const namespace = env[binding];
670
+ const bindingValue = env[binding];
671
+ if (bindingValue == null || typeof bindingValue !== "object") {
672
+ console.error(
673
+ `Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`
674
+ );
675
+ return new Response("Invalid binding", { status: 500 });
676
+ }
677
+ if (!isDurableObjectNamespace(bindingValue)) {
678
+ return new Response("Invalid binding", { status: 500 });
679
+ }
680
+ const namespace = bindingValue;
512
681
  if (request.method === "POST" && basePattern.test(url)) {
513
682
  const acceptHeader = request.headers.get("accept");
514
683
  if (!acceptHeader?.includes("application/json") || !acceptHeader.includes("text/event-stream")) {
515
684
  const body2 = JSON.stringify({
516
- jsonrpc: "2.0",
517
685
  error: {
518
686
  code: -32e3,
519
687
  message: "Not Acceptable: Client must accept both application/json and text/event-stream"
520
688
  },
521
- id: null
689
+ id: null,
690
+ jsonrpc: "2.0"
522
691
  });
523
692
  return new Response(body2, { status: 406 });
524
693
  }
525
694
  const ct = request.headers.get("content-type");
526
695
  if (!ct || !ct.includes("application/json")) {
527
696
  const body2 = JSON.stringify({
528
- jsonrpc: "2.0",
529
697
  error: {
530
698
  code: -32e3,
531
699
  message: "Unsupported Media Type: Content-Type must be application/json"
532
700
  },
533
- id: null
701
+ id: null,
702
+ jsonrpc: "2.0"
534
703
  });
535
704
  return new Response(body2, { status: 415 });
536
705
  }
@@ -540,12 +709,12 @@ data: ${JSON.stringify(result.data)}
540
709
  );
541
710
  if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {
542
711
  const body2 = JSON.stringify({
543
- jsonrpc: "2.0",
544
712
  error: {
545
713
  code: -32e3,
546
714
  message: `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE_BYTES} bytes`
547
715
  },
548
- id: null
716
+ id: null,
717
+ jsonrpc: "2.0"
549
718
  });
550
719
  return new Response(body2, { status: 413 });
551
720
  }
@@ -553,14 +722,14 @@ data: ${JSON.stringify(result.data)}
553
722
  let rawMessage;
554
723
  try {
555
724
  rawMessage = await request.json();
556
- } catch (error) {
725
+ } catch (_error) {
557
726
  const body2 = JSON.stringify({
558
- jsonrpc: "2.0",
559
727
  error: {
560
728
  code: -32700,
561
729
  message: "Parse error: Invalid JSON"
562
730
  },
563
- id: null
731
+ id: null,
732
+ jsonrpc: "2.0"
564
733
  });
565
734
  return new Response(body2, { status: 400 });
566
735
  }
@@ -574,12 +743,12 @@ data: ${JSON.stringify(result.data)}
574
743
  for (const msg of arrayMessage) {
575
744
  if (!JSONRPCMessageSchema.safeParse(msg).success) {
576
745
  const body2 = JSON.stringify({
577
- jsonrpc: "2.0",
578
746
  error: {
579
747
  code: -32700,
580
748
  message: "Parse error: Invalid JSON-RPC message"
581
749
  },
582
- id: null
750
+ id: null,
751
+ jsonrpc: "2.0"
583
752
  });
584
753
  return new Response(body2, { status: 400 });
585
754
  }
@@ -590,34 +759,34 @@ data: ${JSON.stringify(result.data)}
590
759
  );
591
760
  if (isInitializationRequest && sessionId) {
592
761
  const body2 = JSON.stringify({
593
- jsonrpc: "2.0",
594
762
  error: {
595
763
  code: -32600,
596
764
  message: "Invalid Request: Initialization requests must not include a sessionId"
597
765
  },
598
- id: null
766
+ id: null,
767
+ jsonrpc: "2.0"
599
768
  });
600
769
  return new Response(body2, { status: 400 });
601
770
  }
602
771
  if (isInitializationRequest && messages.length > 1) {
603
772
  const body2 = JSON.stringify({
604
- jsonrpc: "2.0",
605
773
  error: {
606
774
  code: -32600,
607
775
  message: "Invalid Request: Only one initialization request is allowed"
608
776
  },
609
- id: null
777
+ id: null,
778
+ jsonrpc: "2.0"
610
779
  });
611
780
  return new Response(body2, { status: 400 });
612
781
  }
613
782
  if (!isInitializationRequest && !sessionId) {
614
783
  const body2 = JSON.stringify({
615
- jsonrpc: "2.0",
616
784
  error: {
617
785
  code: -32e3,
618
786
  message: "Bad Request: Mcp-Session-Id header is required"
619
787
  },
620
- id: null
788
+ id: null,
789
+ jsonrpc: "2.0"
621
790
  });
622
791
  return new Response(body2, { status: 400 });
623
792
  }
@@ -626,26 +795,48 @@ data: ${JSON.stringify(result.data)}
626
795
  const doStub = namespace.get(id);
627
796
  const isInitialized = await doStub.isInitialized();
628
797
  if (isInitializationRequest) {
629
- await doStub._init(ctx.props);
798
+ try {
799
+ await doStub._init(ctx.props);
800
+ await doStub.setInitialized();
801
+ } catch (error) {
802
+ console.error("Failed to initialize McpAgent:", error);
803
+ const errorMessage = error instanceof Error ? error.message : String(error);
804
+ const body2 = JSON.stringify({
805
+ error: {
806
+ code: -32001,
807
+ message: `Initialization failed: ${errorMessage}`
808
+ },
809
+ id: null,
810
+ jsonrpc: "2.0"
811
+ });
812
+ return new Response(body2, { status: 500 });
813
+ }
630
814
  } else if (!isInitialized) {
631
815
  const body2 = JSON.stringify({
632
- jsonrpc: "2.0",
633
816
  error: {
634
817
  code: -32001,
635
818
  message: "Session not found"
636
819
  },
637
- id: null
820
+ id: null,
821
+ jsonrpc: "2.0"
638
822
  });
639
823
  return new Response(body2, { status: 404 });
824
+ } else {
825
+ await doStub.updateProps(ctx.props);
640
826
  }
641
827
  const { readable, writable } = new TransformStream();
642
828
  const writer = writable.getWriter();
643
829
  const encoder = new TextEncoder();
644
830
  const upgradeUrl = new URL(request.url);
645
831
  upgradeUrl.pathname = "/streamable-http";
832
+ const existingHeaders = {};
833
+ request.headers.forEach((value, key) => {
834
+ existingHeaders[key] = value;
835
+ });
646
836
  const response = await doStub.fetch(
647
837
  new Request(upgradeUrl, {
648
838
  headers: {
839
+ ...existingHeaders,
649
840
  Upgrade: "websocket",
650
841
  // Required by PartyServer
651
842
  "x-partykit-room": sessionId
@@ -657,12 +848,12 @@ data: ${JSON.stringify(result.data)}
657
848
  console.error("Failed to establish WebSocket connection");
658
849
  await writer.close();
659
850
  const body2 = JSON.stringify({
660
- jsonrpc: "2.0",
661
851
  error: {
662
852
  code: -32001,
663
853
  message: "Failed to establish WebSocket connection"
664
854
  },
665
- id: null
855
+ id: null,
856
+ jsonrpc: "2.0"
666
857
  });
667
858
  return new Response(body2, { status: 500 });
668
859
  }
@@ -695,10 +886,10 @@ data: ${JSON.stringify(result.data)}
695
886
  onMessage(event).catch(console.error);
696
887
  });
697
888
  ws.addEventListener("error", (error) => {
698
- async function onError(error2) {
889
+ async function onError(_error) {
699
890
  try {
700
891
  await writer.close();
701
- } catch (e) {
892
+ } catch (_e) {
702
893
  }
703
894
  }
704
895
  onError(error).catch(console.error);
@@ -721,7 +912,10 @@ data: ${JSON.stringify(result.data)}
721
912
  ws.send(JSON.stringify(message));
722
913
  }
723
914
  ws.close();
724
- return new Response(null, { status: 202 });
915
+ return new Response(null, {
916
+ headers: corsHeaders(request, corsOptions),
917
+ status: 202
918
+ });
725
919
  }
726
920
  for (const message of messages) {
727
921
  if (isJSONRPCRequest(message)) {
@@ -731,43 +925,32 @@ data: ${JSON.stringify(result.data)}
731
925
  }
732
926
  return new Response(readable, {
733
927
  headers: {
734
- "Content-Type": "text/event-stream",
735
928
  "Cache-Control": "no-cache",
736
929
  Connection: "keep-alive",
930
+ "Content-Type": "text/event-stream",
737
931
  "mcp-session-id": sessionId,
738
- "Access-Control-Allow-Origin": corsOptions?.origin || "*"
932
+ ...corsHeaders(request, corsOptions)
739
933
  },
740
934
  status: 200
741
935
  });
742
936
  }
743
937
  const body = JSON.stringify({
744
- jsonrpc: "2.0",
745
938
  error: {
746
939
  code: -32e3,
747
940
  message: "Method not allowed"
748
941
  },
749
- id: null
942
+ id: null,
943
+ jsonrpc: "2.0"
750
944
  });
751
945
  return new Response(body, { status: 405 });
752
946
  }
753
947
  };
754
948
  }
755
949
  };
756
- _status = new WeakMap();
757
- _transport = new WeakMap();
758
- _transportType = new WeakMap();
759
- _requestIdToConnectionId = new WeakMap();
760
- _agent = new WeakMap();
761
- _McpAgent_instances = new WeakSet();
762
- initialize_fn = async function() {
763
- await this.ctx.blockConcurrencyWhile(async () => {
764
- __privateSet(this, _status, "starting");
765
- await this.onStart();
766
- __privateSet(this, _status, "started");
767
- });
768
- };
769
- var McpAgent = _McpAgent;
770
950
  export {
771
- McpAgent
951
+ ElicitRequestSchema,
952
+ McpAgent,
953
+ SSEEdgeClientTransport,
954
+ StreamableHTTPEdgeClientTransport
772
955
  };
773
956
  //# sourceMappingURL=index.js.map