agents 0.0.0-90db5ba → 0.0.0-928211f

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