agents 0.0.0-8bc0470 → 0.0.0-8c2713f

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