agents 0.0.0-671bdf7 → 0.0.0-696d33e

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 +166 -53
  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-LL2AFX7V.js +109 -0
  15. package/dist/chunk-LL2AFX7V.js.map +1 -0
  16. package/dist/chunk-PNF6ZMUA.js +1296 -0
  17. package/dist/chunk-PNF6ZMUA.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 +4 -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 +61 -11
  37. package/dist/mcp/index.js +362 -184
  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 -67
  52. package/src/index.ts +1178 -152
  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-PNF6ZMUA.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-LL2AFX7V.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);
163
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);
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,32 +206,50 @@ 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
- ));
213
+ );
187
214
  await this._init(this.props);
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(
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 ?? {});
241
+ await this.updateProps(props);
201
242
  if (!this.ctx.storage.get("transportType")) {
202
243
  await this.ctx.storage.put("transportType", "unset");
203
244
  }
204
- this.props = props;
205
245
  if (!this.initRun) {
206
246
  this.initRun = true;
207
- 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
+ }
208
253
  }
209
254
  }
210
255
  async setInitialized() {
@@ -213,10 +258,21 @@ var _McpAgent = class _McpAgent extends DurableObject {
213
258
  async isInitialized() {
214
259
  return await this.ctx.storage.get("initialized") === true;
215
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
+ });
271
+ }
216
272
  // Allow the worker to fetch a websocket connection to the agent
217
273
  async fetch(request) {
218
- if (__privateGet(this, _status) !== "started") {
219
- await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
274
+ if (this._status !== "started") {
275
+ await this._initialize();
220
276
  }
221
277
  if (request.headers.get("Upgrade") !== "websocket") {
222
278
  return new Response("Expected WebSocket Upgrade request", {
@@ -225,6 +281,7 @@ var _McpAgent = class _McpAgent extends DurableObject {
225
281
  }
226
282
  const url = new URL(request.url);
227
283
  const path = url.pathname;
284
+ const server = await this.server;
228
285
  switch (path) {
229
286
  case "/sse": {
230
287
  const websockets = this.ctx.getWebSockets();
@@ -232,24 +289,24 @@ var _McpAgent = class _McpAgent extends DurableObject {
232
289
  return new Response("Websocket already connected", { status: 400 });
233
290
  }
234
291
  await this.ctx.storage.put("transportType", "sse");
235
- __privateSet(this, _transportType, "sse");
236
- if (!__privateGet(this, _transport)) {
237
- __privateSet(this, _transport, new McpSSETransport(() => this.getWebSocket()));
238
- 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);
239
296
  }
240
- return __privateGet(this, _agent).fetch(request);
297
+ return this._agent.fetch(request);
241
298
  }
242
299
  case "/streamable-http": {
243
- if (!__privateGet(this, _transport)) {
244
- __privateSet(this, _transport, new McpStreamableHttpTransport(
300
+ if (!this._transport) {
301
+ this._transport = new McpStreamableHttpTransport(
245
302
  (id) => this.getWebSocketForResponseID(id),
246
- (id) => __privateGet(this, _requestIdToConnectionId).delete(id)
247
- ));
248
- await this.server.connect(__privateGet(this, _transport));
303
+ (id) => this._requestIdToConnectionId.delete(id)
304
+ );
305
+ await server.connect(this._transport);
249
306
  }
250
307
  await this.ctx.storage.put("transportType", "streamable-http");
251
- __privateSet(this, _transportType, "streamable-http");
252
- return __privateGet(this, _agent).fetch(request);
308
+ this._transportType = "streamable-http";
309
+ return this._agent.fetch(request);
253
310
  }
254
311
  default:
255
312
  return new Response(
@@ -268,19 +325,19 @@ var _McpAgent = class _McpAgent extends DurableObject {
268
325
  return websockets[0];
269
326
  }
270
327
  getWebSocketForResponseID(id) {
271
- const connectionId = __privateGet(this, _requestIdToConnectionId).get(id);
328
+ const connectionId = this._requestIdToConnectionId.get(id);
272
329
  if (connectionId === void 0) {
273
330
  return null;
274
331
  }
275
- return __privateGet(this, _agent).getConnection(connectionId) ?? null;
332
+ return this._agent.getConnection(connectionId) ?? null;
276
333
  }
277
334
  // All messages received here. This is currently never called
278
335
  async onMessage(connection, event) {
279
- if (__privateGet(this, _transportType) !== "streamable-http") {
336
+ if (this._transportType !== "streamable-http") {
280
337
  const err = new Error(
281
338
  "Internal Server Error: Expected streamable-http protocol"
282
339
  );
283
- __privateGet(this, _transport)?.onerror?.(err);
340
+ this._transport?.onerror?.(err);
284
341
  return;
285
342
  }
286
343
  let message;
@@ -288,58 +345,125 @@ var _McpAgent = class _McpAgent extends DurableObject {
288
345
  const data = typeof event === "string" ? event : new TextDecoder().decode(event);
289
346
  message = JSONRPCMessageSchema.parse(JSON.parse(data));
290
347
  } catch (error) {
291
- __privateGet(this, _transport)?.onerror?.(error);
348
+ this._transport?.onerror?.(error);
349
+ return;
350
+ }
351
+ if (await this._handleElicitationResponse(message)) {
292
352
  return;
293
353
  }
294
354
  if (isJSONRPCRequest(message)) {
295
- __privateGet(this, _requestIdToConnectionId).set(message.id.toString(), connection.id);
355
+ this._requestIdToConnectionId.set(message.id.toString(), connection.id);
356
+ }
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}`);
296
381
  }
297
- __privateGet(this, _transport)?.onmessage?.(message);
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;
298
419
  }
299
420
  // All messages received over SSE after the initial connection has been established
300
421
  // will be passed here
301
- async onSSEMcpMessage(sessionId, request) {
302
- if (__privateGet(this, _status) !== "started") {
303
- await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
422
+ async onSSEMcpMessage(_sessionId, messageBody) {
423
+ if (this._status !== "started") {
424
+ await this._initialize();
304
425
  }
305
- if (__privateGet(this, _transportType) !== "sse") {
426
+ if (this._transportType !== "sse") {
306
427
  return new Error("Internal Server Error: Expected SSE protocol");
307
428
  }
308
429
  try {
309
- const message = await request.json();
310
430
  let parsedMessage;
311
431
  try {
312
- parsedMessage = JSONRPCMessageSchema.parse(message);
432
+ parsedMessage = JSONRPCMessageSchema.parse(messageBody);
313
433
  } catch (error) {
314
- __privateGet(this, _transport)?.onerror?.(error);
434
+ this._transport?.onerror?.(error);
315
435
  throw error;
316
436
  }
317
- __privateGet(this, _transport)?.onmessage?.(parsedMessage);
437
+ if (await this._handleElicitationResponse(parsedMessage)) {
438
+ return null;
439
+ }
440
+ this._transport?.onmessage?.(parsedMessage);
318
441
  return null;
319
442
  } catch (error) {
320
- __privateGet(this, _transport)?.onerror?.(error);
443
+ console.error("Error forwarding message to SSE:", error);
444
+ this._transport?.onerror?.(error);
321
445
  return error;
322
446
  }
323
447
  }
324
448
  // Delegate all websocket events to the underlying agent
325
449
  async webSocketMessage(ws, event) {
326
- if (__privateGet(this, _status) !== "started") {
327
- await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
450
+ if (this._status !== "started") {
451
+ await this._initialize();
328
452
  }
329
- return await __privateGet(this, _agent).webSocketMessage(ws, event);
453
+ return await this._agent.webSocketMessage(ws, event);
330
454
  }
331
455
  // WebSocket event handlers for hibernation support
332
456
  async webSocketError(ws, error) {
333
- if (__privateGet(this, _status) !== "started") {
334
- await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
457
+ if (this._status !== "started") {
458
+ await this._initialize();
335
459
  }
336
- return await __privateGet(this, _agent).webSocketError(ws, error);
460
+ return await this._agent.webSocketError(ws, error);
337
461
  }
338
462
  async webSocketClose(ws, code, reason, wasClean) {
339
- if (__privateGet(this, _status) !== "started") {
340
- await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
463
+ if (this._status !== "started") {
464
+ await this._initialize();
341
465
  }
342
- return await __privateGet(this, _agent).webSocketClose(ws, code, reason, wasClean);
466
+ return await this._agent.webSocketClose(ws, code, reason, wasClean);
343
467
  }
344
468
  static mount(path, {
345
469
  binding = "MCP_OBJECT",
@@ -358,29 +482,57 @@ var _McpAgent = class _McpAgent extends DurableObject {
358
482
  const basePattern = new URLPattern({ pathname });
359
483
  const messagePattern = new URLPattern({ pathname: `${pathname}/message` });
360
484
  return {
361
- fetch: async (request, env, ctx) => {
485
+ async fetch(request, env, ctx) {
362
486
  const corsResponse = handleCORS(request, corsOptions);
363
487
  if (corsResponse) return corsResponse;
364
488
  const url = new URL(request.url);
365
- 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;
366
500
  if (request.method === "GET" && basePattern.test(url)) {
367
501
  const sessionId = url.searchParams.get("sessionId") || namespace.newUniqueId().toString();
368
502
  const { readable, writable } = new TransformStream();
369
503
  const writer = writable.getWriter();
370
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;
371
509
  const endpointMessage = `event: endpoint
372
- data: ${encodeURI(`${pathname}/message`)}?sessionId=${sessionId}
510
+ data: ${relativeUrlWithSession}
373
511
 
374
512
  `;
375
513
  writer.write(encoder.encode(endpointMessage));
376
514
  const id = namespace.idFromName(`sse:${sessionId}`);
377
515
  const doStub = namespace.get(id);
378
- 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
+ }
379
526
  const upgradeUrl = new URL(request.url);
380
527
  upgradeUrl.pathname = "/sse";
528
+ const existingHeaders = {};
529
+ request.headers.forEach((value, key) => {
530
+ existingHeaders[key] = value;
531
+ });
381
532
  const response = await doStub.fetch(
382
533
  new Request(upgradeUrl, {
383
534
  headers: {
535
+ ...existingHeaders,
384
536
  Upgrade: "websocket",
385
537
  // Required by PartyServer
386
538
  "x-partykit-room": sessionId
@@ -416,10 +568,10 @@ data: ${JSON.stringify(result.data)}
416
568
  onMessage(event).catch(console.error);
417
569
  });
418
570
  ws.addEventListener("error", (error) => {
419
- async function onError(error2) {
571
+ async function onError(_error) {
420
572
  try {
421
573
  await writer.close();
422
- } catch (e) {
574
+ } catch (_e) {
423
575
  }
424
576
  }
425
577
  onError(error).catch(console.error);
@@ -436,10 +588,10 @@ data: ${JSON.stringify(result.data)}
436
588
  });
437
589
  return new Response(readable, {
438
590
  headers: {
439
- "Content-Type": "text/event-stream",
440
591
  "Cache-Control": "no-cache",
441
592
  Connection: "keep-alive",
442
- "Access-Control-Allow-Origin": corsOptions?.origin || "*"
593
+ "Content-Type": "text/event-stream",
594
+ ...corsHeaders(request, corsOptions)
443
595
  }
444
596
  });
445
597
  }
@@ -471,26 +623,28 @@ data: ${JSON.stringify(result.data)}
471
623
  }
472
624
  const id = namespace.idFromName(`sse:${sessionId}`);
473
625
  const doStub = namespace.get(id);
474
- 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);
475
629
  if (error) {
476
630
  return new Response(error.message, {
477
- status: 400,
478
631
  headers: {
479
- "Content-Type": "text/event-stream",
480
632
  "Cache-Control": "no-cache",
481
633
  Connection: "keep-alive",
482
- "Access-Control-Allow-Origin": corsOptions?.origin || "*"
483
- }
634
+ "Content-Type": "text/event-stream",
635
+ ...corsHeaders(request, corsOptions)
636
+ },
637
+ status: 400
484
638
  });
485
639
  }
486
640
  return new Response("Accepted", {
487
- status: 202,
488
641
  headers: {
489
- "Content-Type": "text/event-stream",
490
642
  "Cache-Control": "no-cache",
491
643
  Connection: "keep-alive",
492
- "Access-Control-Allow-Origin": corsOptions?.origin || "*"
493
- }
644
+ "Content-Type": "text/event-stream",
645
+ ...corsHeaders(request, corsOptions)
646
+ },
647
+ status: 202
494
648
  });
495
649
  }
496
650
  return new Response("Not Found", { status: 404 });
@@ -507,35 +661,45 @@ data: ${JSON.stringify(result.data)}
507
661
  }
508
662
  const basePattern = new URLPattern({ pathname });
509
663
  return {
510
- fetch: async (request, env, ctx) => {
664
+ async fetch(request, env, ctx) {
511
665
  const corsResponse = handleCORS(request, corsOptions);
512
666
  if (corsResponse) {
513
667
  return corsResponse;
514
668
  }
515
669
  const url = new URL(request.url);
516
- 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;
517
681
  if (request.method === "POST" && basePattern.test(url)) {
518
682
  const acceptHeader = request.headers.get("accept");
519
683
  if (!acceptHeader?.includes("application/json") || !acceptHeader.includes("text/event-stream")) {
520
684
  const body2 = JSON.stringify({
521
- jsonrpc: "2.0",
522
685
  error: {
523
686
  code: -32e3,
524
687
  message: "Not Acceptable: Client must accept both application/json and text/event-stream"
525
688
  },
526
- id: null
689
+ id: null,
690
+ jsonrpc: "2.0"
527
691
  });
528
692
  return new Response(body2, { status: 406 });
529
693
  }
530
694
  const ct = request.headers.get("content-type");
531
695
  if (!ct || !ct.includes("application/json")) {
532
696
  const body2 = JSON.stringify({
533
- jsonrpc: "2.0",
534
697
  error: {
535
698
  code: -32e3,
536
699
  message: "Unsupported Media Type: Content-Type must be application/json"
537
700
  },
538
- id: null
701
+ id: null,
702
+ jsonrpc: "2.0"
539
703
  });
540
704
  return new Response(body2, { status: 415 });
541
705
  }
@@ -545,12 +709,12 @@ data: ${JSON.stringify(result.data)}
545
709
  );
546
710
  if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {
547
711
  const body2 = JSON.stringify({
548
- jsonrpc: "2.0",
549
712
  error: {
550
713
  code: -32e3,
551
714
  message: `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE_BYTES} bytes`
552
715
  },
553
- id: null
716
+ id: null,
717
+ jsonrpc: "2.0"
554
718
  });
555
719
  return new Response(body2, { status: 413 });
556
720
  }
@@ -558,14 +722,14 @@ data: ${JSON.stringify(result.data)}
558
722
  let rawMessage;
559
723
  try {
560
724
  rawMessage = await request.json();
561
- } catch (error) {
725
+ } catch (_error) {
562
726
  const body2 = JSON.stringify({
563
- jsonrpc: "2.0",
564
727
  error: {
565
728
  code: -32700,
566
729
  message: "Parse error: Invalid JSON"
567
730
  },
568
- id: null
731
+ id: null,
732
+ jsonrpc: "2.0"
569
733
  });
570
734
  return new Response(body2, { status: 400 });
571
735
  }
@@ -579,12 +743,12 @@ data: ${JSON.stringify(result.data)}
579
743
  for (const msg of arrayMessage) {
580
744
  if (!JSONRPCMessageSchema.safeParse(msg).success) {
581
745
  const body2 = JSON.stringify({
582
- jsonrpc: "2.0",
583
746
  error: {
584
747
  code: -32700,
585
748
  message: "Parse error: Invalid JSON-RPC message"
586
749
  },
587
- id: null
750
+ id: null,
751
+ jsonrpc: "2.0"
588
752
  });
589
753
  return new Response(body2, { status: 400 });
590
754
  }
@@ -595,34 +759,34 @@ data: ${JSON.stringify(result.data)}
595
759
  );
596
760
  if (isInitializationRequest && sessionId) {
597
761
  const body2 = JSON.stringify({
598
- jsonrpc: "2.0",
599
762
  error: {
600
763
  code: -32600,
601
764
  message: "Invalid Request: Initialization requests must not include a sessionId"
602
765
  },
603
- id: null
766
+ id: null,
767
+ jsonrpc: "2.0"
604
768
  });
605
769
  return new Response(body2, { status: 400 });
606
770
  }
607
771
  if (isInitializationRequest && messages.length > 1) {
608
772
  const body2 = JSON.stringify({
609
- jsonrpc: "2.0",
610
773
  error: {
611
774
  code: -32600,
612
775
  message: "Invalid Request: Only one initialization request is allowed"
613
776
  },
614
- id: null
777
+ id: null,
778
+ jsonrpc: "2.0"
615
779
  });
616
780
  return new Response(body2, { status: 400 });
617
781
  }
618
782
  if (!isInitializationRequest && !sessionId) {
619
783
  const body2 = JSON.stringify({
620
- jsonrpc: "2.0",
621
784
  error: {
622
785
  code: -32e3,
623
786
  message: "Bad Request: Mcp-Session-Id header is required"
624
787
  },
625
- id: null
788
+ id: null,
789
+ jsonrpc: "2.0"
626
790
  });
627
791
  return new Response(body2, { status: 400 });
628
792
  }
@@ -631,26 +795,48 @@ data: ${JSON.stringify(result.data)}
631
795
  const doStub = namespace.get(id);
632
796
  const isInitialized = await doStub.isInitialized();
633
797
  if (isInitializationRequest) {
634
- await doStub.setInitialized();
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
+ }
635
814
  } else if (!isInitialized) {
636
815
  const body2 = JSON.stringify({
637
- jsonrpc: "2.0",
638
816
  error: {
639
817
  code: -32001,
640
818
  message: "Session not found"
641
819
  },
642
- id: null
820
+ id: null,
821
+ jsonrpc: "2.0"
643
822
  });
644
823
  return new Response(body2, { status: 404 });
824
+ } else {
825
+ await doStub.updateProps(ctx.props);
645
826
  }
646
827
  const { readable, writable } = new TransformStream();
647
828
  const writer = writable.getWriter();
648
829
  const encoder = new TextEncoder();
649
830
  const upgradeUrl = new URL(request.url);
650
831
  upgradeUrl.pathname = "/streamable-http";
832
+ const existingHeaders = {};
833
+ request.headers.forEach((value, key) => {
834
+ existingHeaders[key] = value;
835
+ });
651
836
  const response = await doStub.fetch(
652
837
  new Request(upgradeUrl, {
653
838
  headers: {
839
+ ...existingHeaders,
654
840
  Upgrade: "websocket",
655
841
  // Required by PartyServer
656
842
  "x-partykit-room": sessionId
@@ -662,12 +848,12 @@ data: ${JSON.stringify(result.data)}
662
848
  console.error("Failed to establish WebSocket connection");
663
849
  await writer.close();
664
850
  const body2 = JSON.stringify({
665
- jsonrpc: "2.0",
666
851
  error: {
667
852
  code: -32001,
668
853
  message: "Failed to establish WebSocket connection"
669
854
  },
670
- id: null
855
+ id: null,
856
+ jsonrpc: "2.0"
671
857
  });
672
858
  return new Response(body2, { status: 500 });
673
859
  }
@@ -700,10 +886,10 @@ data: ${JSON.stringify(result.data)}
700
886
  onMessage(event).catch(console.error);
701
887
  });
702
888
  ws.addEventListener("error", (error) => {
703
- async function onError(error2) {
889
+ async function onError(_error) {
704
890
  try {
705
891
  await writer.close();
706
- } catch (e) {
892
+ } catch (_e) {
707
893
  }
708
894
  }
709
895
  onError(error).catch(console.error);
@@ -726,7 +912,10 @@ data: ${JSON.stringify(result.data)}
726
912
  ws.send(JSON.stringify(message));
727
913
  }
728
914
  ws.close();
729
- return new Response(null, { status: 202 });
915
+ return new Response(null, {
916
+ headers: corsHeaders(request, corsOptions),
917
+ status: 202
918
+ });
730
919
  }
731
920
  for (const message of messages) {
732
921
  if (isJSONRPCRequest(message)) {
@@ -736,43 +925,32 @@ data: ${JSON.stringify(result.data)}
736
925
  }
737
926
  return new Response(readable, {
738
927
  headers: {
739
- "Content-Type": "text/event-stream",
740
928
  "Cache-Control": "no-cache",
741
929
  Connection: "keep-alive",
930
+ "Content-Type": "text/event-stream",
742
931
  "mcp-session-id": sessionId,
743
- "Access-Control-Allow-Origin": corsOptions?.origin || "*"
932
+ ...corsHeaders(request, corsOptions)
744
933
  },
745
934
  status: 200
746
935
  });
747
936
  }
748
937
  const body = JSON.stringify({
749
- jsonrpc: "2.0",
750
938
  error: {
751
939
  code: -32e3,
752
940
  message: "Method not allowed"
753
941
  },
754
- id: null
942
+ id: null,
943
+ jsonrpc: "2.0"
755
944
  });
756
945
  return new Response(body, { status: 405 });
757
946
  }
758
947
  };
759
948
  }
760
949
  };
761
- _status = new WeakMap();
762
- _transport = new WeakMap();
763
- _transportType = new WeakMap();
764
- _requestIdToConnectionId = new WeakMap();
765
- _agent = new WeakMap();
766
- _McpAgent_instances = new WeakSet();
767
- initialize_fn = async function() {
768
- await this.ctx.blockConcurrencyWhile(async () => {
769
- __privateSet(this, _status, "starting");
770
- await this.onStart();
771
- __privateSet(this, _status, "started");
772
- });
773
- };
774
- var McpAgent = _McpAgent;
775
950
  export {
776
- McpAgent
951
+ ElicitRequestSchema,
952
+ McpAgent,
953
+ SSEEdgeClientTransport,
954
+ StreamableHTTPEdgeClientTransport
777
955
  };
778
956
  //# sourceMappingURL=index.js.map