agents 0.0.0-8d8216c → 0.0.0-8dab081

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