agents 0.0.0-2cc0f02 → 0.0.0-2e73791

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 (68) hide show
  1. package/README.md +126 -3
  2. package/dist/ai-chat-agent.d.ts +231 -22
  3. package/dist/ai-chat-agent.js +691 -121
  4. package/dist/ai-chat-agent.js.map +1 -1
  5. package/dist/{ai-chat-v5-migration-gdyLiTd8.js → ai-chat-v5-migration-DguhuLKF.js} +2 -2
  6. package/dist/{ai-chat-v5-migration-gdyLiTd8.js.map → ai-chat-v5-migration-DguhuLKF.js.map} +1 -1
  7. package/dist/ai-chat-v5-migration.js +1 -1
  8. package/dist/ai-react.d.ts +145 -16
  9. package/dist/ai-react.js +389 -75
  10. package/dist/ai-react.js.map +1 -1
  11. package/dist/{ai-types-B0GBFDwi.js → ai-types-DEtF_8Km.js} +10 -2
  12. package/dist/ai-types-DEtF_8Km.js.map +1 -0
  13. package/dist/{ai-types-BWW4umHY.d.ts → ai-types-U8lYA0o8.d.ts} +41 -9
  14. package/dist/ai-types.d.ts +4 -4
  15. package/dist/ai-types.js +1 -1
  16. package/dist/cli/index.d.ts +1 -0
  17. package/dist/cli/index.js +28 -0
  18. package/dist/cli/index.js.map +1 -0
  19. package/dist/client-Cfw92Wb_.d.ts +834 -0
  20. package/dist/{client-CmMi85Sj.d.ts → client-ClORm6f0.d.ts} +10 -10
  21. package/dist/{client-zS-OCVJA.js → client-DjTPRM8-.js} +3 -3
  22. package/dist/{client-zS-OCVJA.js.map → client-DjTPRM8-.js.map} +1 -1
  23. package/dist/client-QZa2Rq0l.js +1105 -0
  24. package/dist/client-QZa2Rq0l.js.map +1 -0
  25. package/dist/client.d.ts +8 -8
  26. package/dist/client.js +2 -2
  27. package/dist/codemode/ai.js +7 -6
  28. package/dist/codemode/ai.js.map +1 -1
  29. package/dist/context-BkKbAa1R.js +8 -0
  30. package/dist/context-BkKbAa1R.js.map +1 -0
  31. package/dist/context-_sPQqJWv.d.ts +24 -0
  32. package/dist/context.d.ts +6 -0
  33. package/dist/context.js +3 -0
  34. package/dist/{do-oauth-client-provider-CCwGwnrA.d.ts → do-oauth-client-provider-B-ryFIPr.d.ts} +21 -6
  35. package/dist/{do-oauth-client-provider-B2jr6UNq.js → do-oauth-client-provider-B1fVIshX.js} +71 -9
  36. package/dist/do-oauth-client-provider-B1fVIshX.js.map +1 -0
  37. package/dist/{index-W4JUkafc.d.ts → index-CyDpAVHZ.d.ts} +7 -3
  38. package/dist/{index-DWcUTPtX.d.ts → index-xIS9I1YX.d.ts} +83 -65
  39. package/dist/index.d.ts +36 -36
  40. package/dist/index.js +6 -5
  41. package/dist/mcp/client.d.ts +4 -4
  42. package/dist/mcp/client.js +2 -1
  43. package/dist/mcp/do-oauth-client-provider.d.ts +1 -1
  44. package/dist/mcp/do-oauth-client-provider.js +1 -1
  45. package/dist/mcp/index.d.ts +140 -12
  46. package/dist/mcp/index.js +636 -41
  47. package/dist/mcp/index.js.map +1 -1
  48. package/dist/mcp/x402.js +10 -6
  49. package/dist/mcp/x402.js.map +1 -1
  50. package/dist/{mcp-BEwaCsxO.d.ts → mcp-CzbSsLfc.d.ts} +2 -2
  51. package/dist/observability/index.d.ts +2 -2
  52. package/dist/observability/index.js +6 -5
  53. package/dist/{react-B8BT6PYZ.d.ts → react-ElpIreHg.d.ts} +35 -17
  54. package/dist/react.d.ts +15 -10
  55. package/dist/react.js +57 -57
  56. package/dist/react.js.map +1 -1
  57. package/dist/{serializable-gtr9YMhp.d.ts → serializable-C4GLimgv.d.ts} +8 -3
  58. package/dist/serializable.d.ts +5 -5
  59. package/dist/{src-C9xZ0CrH.js → src-BZDh910Z.js} +130 -128
  60. package/dist/src-BZDh910Z.js.map +1 -0
  61. package/package.json +61 -44
  62. package/dist/ai-types-B0GBFDwi.js.map +0 -1
  63. package/dist/client-C-u-lCFT.d.ts +0 -5311
  64. package/dist/client-WbaRgKYN.js +0 -788
  65. package/dist/client-WbaRgKYN.js.map +0 -1
  66. package/dist/do-oauth-client-provider-B2jr6UNq.js.map +0 -1
  67. package/dist/src-C9xZ0CrH.js.map +0 -1
  68. package/src/index.ts +0 -2031
package/dist/mcp/index.js CHANGED
@@ -1,9 +1,13 @@
1
- import { SSEEdgeClientTransport, StreamableHTTPEdgeClientTransport } from "../client-WbaRgKYN.js";
2
- import { MessageType } from "../ai-types-B0GBFDwi.js";
3
- import "../client-zS-OCVJA.js";
4
- import "../do-oauth-client-provider-B2jr6UNq.js";
5
- import { Agent, getAgentByName, getCurrentAgent } from "../src-C9xZ0CrH.js";
6
- import { ElicitRequestSchema, InitializeRequestSchema, JSONRPCMessageSchema, isJSONRPCError, isJSONRPCNotification, isJSONRPCRequest, isJSONRPCResponse } from "@modelcontextprotocol/sdk/types.js";
1
+ import "../context-BkKbAa1R.js";
2
+ import { t as MessageType } from "../ai-types-DEtF_8Km.js";
3
+ import "../client-DjTPRM8-.js";
4
+ import "../client-QZa2Rq0l.js";
5
+ import "../do-oauth-client-provider-B1fVIshX.js";
6
+ import { c as getCurrentAgent, s as getAgentByName, t as Agent } from "../src-BZDh910Z.js";
7
+ import { AsyncLocalStorage } from "node:async_hooks";
8
+ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
9
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
10
+ import { ElicitRequestSchema, InitializeRequestSchema, JSONRPCMessageSchema, SUPPORTED_PROTOCOL_VERSIONS, isInitializeRequest, isJSONRPCError, isJSONRPCNotification, isJSONRPCRequest, isJSONRPCResponse } from "@modelcontextprotocol/sdk/types.js";
7
11
 
8
12
  //#region src/mcp/utils.ts
9
13
  /**
@@ -20,7 +24,7 @@ const MCP_HTTP_METHOD_HEADER = "cf-mcp-method";
20
24
  */
21
25
  const MCP_MESSAGE_HEADER = "cf-mcp-message";
22
26
  const MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
23
- const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
27
+ const createStreamingHttpHandler = (basePath, namespace, options = {}) => {
24
28
  let pathname = basePath;
25
29
  if (basePath === "/") pathname = "/*";
26
30
  const basePattern = new URLPattern({ pathname });
@@ -129,7 +133,10 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
129
133
  return new Response(body$1, { status: 400 });
130
134
  }
131
135
  sessionId = sessionId ?? namespace.newUniqueId().toString();
132
- const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, { props: ctx.props });
136
+ const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, {
137
+ props: ctx.props,
138
+ jurisdiction: options.jurisdiction
139
+ });
133
140
  const isInitialized = await agent.getInitializeRequest();
134
141
  if (maybeInitializeRequest) await agent.setInitializeRequest(maybeInitializeRequest);
135
142
  else if (!isInitialized) {
@@ -204,7 +211,7 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
204
211
  if (messages.every((msg) => isJSONRPCNotification(msg) || isJSONRPCResponse(msg))) {
205
212
  ws.close();
206
213
  return new Response(null, {
207
- headers: corsHeaders(request, corsOptions),
214
+ headers: corsHeaders(request, options.corsOptions),
208
215
  status: 202
209
216
  });
210
217
  }
@@ -214,7 +221,7 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
214
221
  Connection: "keep-alive",
215
222
  "Content-Type": "text/event-stream",
216
223
  "mcp-session-id": sessionId,
217
- ...corsHeaders(request, corsOptions)
224
+ ...corsHeaders(request, options.corsOptions)
218
225
  },
219
226
  status: 200
220
227
  });
@@ -242,7 +249,10 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
242
249
  const { readable, writable } = new TransformStream();
243
250
  const writer = writable.getWriter();
244
251
  const encoder = new TextEncoder();
245
- const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, { props: ctx.props });
252
+ const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, {
253
+ props: ctx.props,
254
+ jurisdiction: options.jurisdiction
255
+ });
246
256
  if (!await agent.getInitializeRequest()) return new Response(JSON.stringify({
247
257
  jsonrpc: "2.0",
248
258
  error: {
@@ -291,7 +301,7 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
291
301
  Connection: "keep-alive",
292
302
  "Content-Type": "text/event-stream",
293
303
  "mcp-session-id": sessionId,
294
- ...corsHeaders(request, corsOptions)
304
+ ...corsHeaders(request, options.corsOptions)
295
305
  },
296
306
  status: 200
297
307
  });
@@ -306,9 +316,9 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
306
316
  id: null
307
317
  }), {
308
318
  status: 400,
309
- headers: corsHeaders(request, corsOptions)
319
+ headers: corsHeaders(request, options.corsOptions)
310
320
  });
311
- const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`);
321
+ const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, { jurisdiction: options.jurisdiction });
312
322
  if (!await agent.getInitializeRequest()) return new Response(JSON.stringify({
313
323
  jsonrpc: "2.0",
314
324
  error: {
@@ -318,12 +328,12 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
318
328
  id: null
319
329
  }), {
320
330
  status: 404,
321
- headers: corsHeaders(request, corsOptions)
331
+ headers: corsHeaders(request, options.corsOptions)
322
332
  });
323
333
  ctx.waitUntil(agent.destroy().catch(() => {}));
324
334
  return new Response(null, {
325
335
  status: 204,
326
- headers: corsHeaders(request, corsOptions)
336
+ headers: corsHeaders(request, options.corsOptions)
327
337
  });
328
338
  }
329
339
  }
@@ -338,7 +348,7 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
338
348
  return new Response(body, { status: 404 });
339
349
  };
340
350
  };
341
- const createLegacySseHandler = (basePath, namespace, corsOptions) => {
351
+ const createLegacySseHandler = (basePath, namespace, options = {}) => {
342
352
  let pathname = basePath;
343
353
  if (basePath === "/") pathname = "/*";
344
354
  const basePattern = new URLPattern({ pathname });
@@ -355,7 +365,10 @@ const createLegacySseHandler = (basePath, namespace, corsOptions) => {
355
365
  endpointUrl.searchParams.set("sessionId", sessionId);
356
366
  const endpointMessage = `event: endpoint\ndata: ${endpointUrl.pathname + endpointUrl.search + endpointUrl.hash}\n\n`;
357
367
  writer.write(encoder.encode(endpointMessage));
358
- const agent = await getAgentByName(namespace, `sse:${sessionId}`, { props: ctx.props });
368
+ const agent = await getAgentByName(namespace, `sse:${sessionId}`, {
369
+ props: ctx.props,
370
+ jurisdiction: options.jurisdiction
371
+ });
359
372
  const existingHeaders = {};
360
373
  request.headers.forEach((value, key) => {
361
374
  existingHeaders[key] = value;
@@ -407,7 +420,7 @@ const createLegacySseHandler = (basePath, namespace, corsOptions) => {
407
420
  "Cache-Control": "no-cache",
408
421
  Connection: "keep-alive",
409
422
  "Content-Type": "text/event-stream",
410
- ...corsHeaders(request, corsOptions)
423
+ ...corsHeaders(request, options.corsOptions)
411
424
  } });
412
425
  }
413
426
  if (request.method === "POST" && messagePattern.test(url)) {
@@ -417,15 +430,19 @@ const createLegacySseHandler = (basePath, namespace, corsOptions) => {
417
430
  if (!contentType.includes("application/json")) return new Response(`Unsupported content-type: ${contentType}`, { status: 400 });
418
431
  const contentLength = Number.parseInt(request.headers.get("content-length") || "0", 10);
419
432
  if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) return new Response(`Request body too large: ${contentLength} bytes`, { status: 400 });
420
- const agent = await getAgentByName(namespace, `sse:${sessionId}`, { props: ctx.props });
433
+ const agent = await getAgentByName(namespace, `sse:${sessionId}`, {
434
+ props: ctx.props,
435
+ jurisdiction: options.jurisdiction
436
+ });
421
437
  const messageBody = await request.json();
422
- const error = await agent.onSSEMcpMessage(sessionId, messageBody);
438
+ const extraInfo = { requestInfo: { headers: Object.fromEntries(request.headers.entries()) } };
439
+ const error = await agent.onSSEMcpMessage(sessionId, messageBody, extraInfo);
423
440
  if (error) return new Response(error.message, {
424
441
  headers: {
425
442
  "Cache-Control": "no-cache",
426
443
  Connection: "keep-alive",
427
444
  "Content-Type": "text/event-stream",
428
- ...corsHeaders(request, corsOptions)
445
+ ...corsHeaders(request, options.corsOptions)
429
446
  },
430
447
  status: 400
431
448
  });
@@ -434,7 +451,7 @@ const createLegacySseHandler = (basePath, namespace, corsOptions) => {
434
451
  "Cache-Control": "no-cache",
435
452
  Connection: "keep-alive",
436
453
  "Content-Type": "text/event-stream",
437
- ...corsHeaders(request, corsOptions)
454
+ ...corsHeaders(request, options.corsOptions)
438
455
  },
439
456
  status: 202
440
457
  });
@@ -463,9 +480,12 @@ function isDurableObjectNamespace(namespace) {
463
480
  //#endregion
464
481
  //#region src/mcp/transport.ts
465
482
  var McpSSETransport = class {
466
- constructor(getWebSocket) {
483
+ constructor() {
467
484
  this._started = false;
468
- this._getWebSocket = getWebSocket;
485
+ const { agent } = getCurrentAgent();
486
+ if (!agent) throw new Error("McpAgent was not found in Transport constructor");
487
+ this.sessionId = agent.getSessionId();
488
+ this._getWebSocket = () => agent.getWebSocket();
469
489
  }
470
490
  async start() {
471
491
  if (this._started) throw new Error("Transport already started");
@@ -573,19 +593,35 @@ var StreamableHTTPServerTransport = class {
573
593
  if (Array.isArray(rawMessage)) messages = rawMessage.map((msg) => JSONRPCMessageSchema.parse(msg));
574
594
  else messages = [JSONRPCMessageSchema.parse(rawMessage)];
575
595
  const hasRequests = messages.some(isJSONRPCRequest);
576
- if (!hasRequests) for (const message of messages) this.onmessage?.(message, {
577
- authInfo,
578
- requestInfo
579
- });
596
+ if (!hasRequests) for (const message of messages) {
597
+ if (this.messageInterceptor) {
598
+ if (await this.messageInterceptor(message, {
599
+ authInfo,
600
+ requestInfo
601
+ })) continue;
602
+ }
603
+ this.onmessage?.(message, {
604
+ authInfo,
605
+ requestInfo
606
+ });
607
+ }
580
608
  else if (hasRequests) {
581
609
  const { connection } = getCurrentAgent();
582
610
  if (!connection) throw new Error("Connection was not found in handlePostRequest");
583
611
  const requestIds = messages.filter(isJSONRPCRequest).map((message) => message.id);
584
612
  connection.setState({ requestIds });
585
- for (const message of messages) this.onmessage?.(message, {
586
- authInfo,
587
- requestInfo
588
- });
613
+ for (const message of messages) {
614
+ if (this.messageInterceptor) {
615
+ if (await this.messageInterceptor(message, {
616
+ authInfo,
617
+ requestInfo
618
+ })) continue;
619
+ }
620
+ this.onmessage?.(message, {
621
+ authInfo,
622
+ requestInfo
623
+ });
624
+ }
589
625
  }
590
626
  }
591
627
  async close() {
@@ -624,6 +660,553 @@ var StreamableHTTPServerTransport = class {
624
660
  }
625
661
  };
626
662
 
663
+ //#endregion
664
+ //#region src/mcp/client-transports.ts
665
+ /**
666
+ * Deprecated transport wrappers
667
+ */
668
+ let didWarnAboutSSEEdgeClientTransport = false;
669
+ /**
670
+ * @deprecated Use SSEClientTransport from @modelcontextprotocol/sdk/client/sse.js instead. This alias will be removed in the next major version.
671
+ */
672
+ var SSEEdgeClientTransport = class extends SSEClientTransport {
673
+ constructor(url, options) {
674
+ super(url, options);
675
+ if (!didWarnAboutSSEEdgeClientTransport) {
676
+ didWarnAboutSSEEdgeClientTransport = true;
677
+ console.warn("SSEEdgeClientTransport is deprecated. Use SSEClientTransport from @modelcontextprotocol/sdk/client/sse.js instead. SSEEdgeClientTransport will be removed in the next major version.");
678
+ }
679
+ }
680
+ };
681
+ let didWarnAboutStreamableHTTPEdgeClientTransport = false;
682
+ /**
683
+ * @deprecated Use StreamableHTTPClientTransport from @modelcontextprotocol/sdk/client/streamableHttp.js instead. This alias will be removed in the next major version.
684
+ */
685
+ var StreamableHTTPEdgeClientTransport = class extends StreamableHTTPClientTransport {
686
+ constructor(url, options) {
687
+ super(url, options);
688
+ if (!didWarnAboutStreamableHTTPEdgeClientTransport) {
689
+ didWarnAboutStreamableHTTPEdgeClientTransport = true;
690
+ console.warn("StreamableHTTPEdgeClientTransport is deprecated. Use StreamableHTTPClientTransport from @modelcontextprotocol/sdk/client/streamableHttp.js instead. StreamableHTTPEdgeClientTransport will be removed in the next major version.");
691
+ }
692
+ }
693
+ };
694
+
695
+ //#endregion
696
+ //#region src/mcp/worker-transport.ts
697
+ const MCP_PROTOCOL_VERSION_HEADER = "MCP-Protocol-Version";
698
+ var WorkerTransport = class {
699
+ constructor(options) {
700
+ this.started = false;
701
+ this.initialized = false;
702
+ this.enableJsonResponse = false;
703
+ this.standaloneSseStreamId = "_GET_stream";
704
+ this.streamMapping = /* @__PURE__ */ new Map();
705
+ this.requestToStreamMapping = /* @__PURE__ */ new Map();
706
+ this.requestResponseMap = /* @__PURE__ */ new Map();
707
+ this.stateRestored = false;
708
+ this.sessionIdGenerator = options?.sessionIdGenerator;
709
+ this.enableJsonResponse = options?.enableJsonResponse ?? false;
710
+ this.onsessioninitialized = options?.onsessioninitialized;
711
+ this.corsOptions = options?.corsOptions;
712
+ this.storage = options?.storage;
713
+ }
714
+ /**
715
+ * Restore transport state from persistent storage.
716
+ * This is automatically called on start.
717
+ */
718
+ async restoreState() {
719
+ if (!this.storage || this.stateRestored) return;
720
+ const state = await Promise.resolve(this.storage.get());
721
+ if (state) {
722
+ this.sessionId = state.sessionId;
723
+ this.initialized = state.initialized;
724
+ }
725
+ this.stateRestored = true;
726
+ }
727
+ /**
728
+ * Persist current transport state to storage.
729
+ */
730
+ async saveState() {
731
+ if (!this.storage) return;
732
+ const state = {
733
+ sessionId: this.sessionId,
734
+ initialized: this.initialized
735
+ };
736
+ await Promise.resolve(this.storage.set(state));
737
+ }
738
+ async start() {
739
+ if (this.started) throw new Error("Transport already started");
740
+ this.started = true;
741
+ }
742
+ /**
743
+ * Validates the MCP-Protocol-Version header on incoming requests.
744
+ *
745
+ * This performs a simple check: if a version header is present, it must be
746
+ * in the SUPPORTED_PROTOCOL_VERSIONS list. We do not track the negotiated
747
+ * version or enforce version consistency across requests - the SDK handles
748
+ * version negotiation during initialization, and we simply reject any
749
+ * explicitly unsupported versions.
750
+ *
751
+ * - Header present and supported: Accept
752
+ * - Header present and unsupported: 400 Bad Request
753
+ * - Header missing: Accept (version validation is optional)
754
+ */
755
+ validateProtocolVersion(request) {
756
+ const protocolVersion = request.headers.get(MCP_PROTOCOL_VERSION_HEADER);
757
+ if (protocolVersion !== null && !SUPPORTED_PROTOCOL_VERSIONS.includes(protocolVersion)) return new Response(JSON.stringify({
758
+ jsonrpc: "2.0",
759
+ error: {
760
+ code: -32e3,
761
+ message: `Bad Request: Unsupported protocol version: ${protocolVersion} (supported versions: ${SUPPORTED_PROTOCOL_VERSIONS.join(", ")})`
762
+ },
763
+ id: null
764
+ }), {
765
+ status: 400,
766
+ headers: {
767
+ "Content-Type": "application/json",
768
+ ...this.getHeaders()
769
+ }
770
+ });
771
+ }
772
+ getHeaders({ forPreflight } = {}) {
773
+ const options = {
774
+ origin: "*",
775
+ headers: "Content-Type, Accept, Authorization, mcp-session-id, MCP-Protocol-Version",
776
+ methods: "GET, POST, DELETE, OPTIONS",
777
+ exposeHeaders: "mcp-session-id",
778
+ maxAge: 86400,
779
+ ...this.corsOptions
780
+ };
781
+ if (forPreflight) return {
782
+ "Access-Control-Allow-Origin": options.origin,
783
+ "Access-Control-Allow-Headers": options.headers,
784
+ "Access-Control-Allow-Methods": options.methods,
785
+ "Access-Control-Max-Age": options.maxAge.toString()
786
+ };
787
+ return {
788
+ "Access-Control-Allow-Origin": options.origin,
789
+ "Access-Control-Expose-Headers": options.exposeHeaders
790
+ };
791
+ }
792
+ async handleRequest(request, parsedBody) {
793
+ await this.restoreState();
794
+ switch (request.method) {
795
+ case "OPTIONS": return this.handleOptionsRequest(request);
796
+ case "GET": return this.handleGetRequest(request);
797
+ case "POST": return this.handlePostRequest(request, parsedBody);
798
+ case "DELETE": return this.handleDeleteRequest(request);
799
+ default: return this.handleUnsupportedRequest();
800
+ }
801
+ }
802
+ async handleGetRequest(request) {
803
+ if (!request.headers.get("Accept")?.includes("text/event-stream")) return new Response(JSON.stringify({
804
+ jsonrpc: "2.0",
805
+ error: {
806
+ code: -32e3,
807
+ message: "Not Acceptable: Client must accept text/event-stream"
808
+ },
809
+ id: null
810
+ }), {
811
+ status: 406,
812
+ headers: {
813
+ "Content-Type": "application/json",
814
+ ...this.getHeaders()
815
+ }
816
+ });
817
+ const sessionError = this.validateSession(request);
818
+ if (sessionError) return sessionError;
819
+ const versionError = this.validateProtocolVersion(request);
820
+ if (versionError) return versionError;
821
+ const streamId = this.standaloneSseStreamId;
822
+ if (this.streamMapping.get(streamId) !== void 0) return new Response(JSON.stringify({
823
+ jsonrpc: "2.0",
824
+ error: {
825
+ code: -32e3,
826
+ message: "Conflict: Only one SSE stream is allowed per session"
827
+ },
828
+ id: null
829
+ }), {
830
+ status: 409,
831
+ headers: {
832
+ "Content-Type": "application/json",
833
+ ...this.getHeaders()
834
+ }
835
+ });
836
+ const { readable, writable } = new TransformStream();
837
+ const writer = writable.getWriter();
838
+ const encoder = new TextEncoder();
839
+ const headers = new Headers({
840
+ "Content-Type": "text/event-stream",
841
+ "Cache-Control": "no-cache",
842
+ Connection: "keep-alive",
843
+ ...this.getHeaders()
844
+ });
845
+ if (this.sessionId !== void 0) headers.set("mcp-session-id", this.sessionId);
846
+ const keepAlive = setInterval(() => {
847
+ try {
848
+ writer.write(encoder.encode("event: ping\ndata: \n\n"));
849
+ } catch {
850
+ clearInterval(keepAlive);
851
+ }
852
+ }, 3e4);
853
+ this.streamMapping.set(streamId, {
854
+ writer,
855
+ encoder,
856
+ cleanup: () => {
857
+ clearInterval(keepAlive);
858
+ this.streamMapping.delete(streamId);
859
+ writer.close().catch(() => {});
860
+ }
861
+ });
862
+ return new Response(readable, { headers });
863
+ }
864
+ async handlePostRequest(request, parsedBody) {
865
+ const acceptHeader = request.headers.get("Accept");
866
+ if (!acceptHeader?.includes("application/json") || !acceptHeader?.includes("text/event-stream")) return new Response(JSON.stringify({
867
+ jsonrpc: "2.0",
868
+ error: {
869
+ code: -32e3,
870
+ message: "Not Acceptable: Client must accept both application/json and text/event-stream"
871
+ },
872
+ id: null
873
+ }), {
874
+ status: 406,
875
+ headers: {
876
+ "Content-Type": "application/json",
877
+ ...this.getHeaders()
878
+ }
879
+ });
880
+ if (!request.headers.get("Content-Type")?.includes("application/json")) return new Response(JSON.stringify({
881
+ jsonrpc: "2.0",
882
+ error: {
883
+ code: -32e3,
884
+ message: "Unsupported Media Type: Content-Type must be application/json"
885
+ },
886
+ id: null
887
+ }), {
888
+ status: 415,
889
+ headers: {
890
+ "Content-Type": "application/json",
891
+ ...this.getHeaders()
892
+ }
893
+ });
894
+ let rawMessage = parsedBody;
895
+ if (rawMessage === void 0) try {
896
+ rawMessage = await request.json();
897
+ } catch {
898
+ return new Response(JSON.stringify({
899
+ jsonrpc: "2.0",
900
+ error: {
901
+ code: -32700,
902
+ message: "Parse error: Invalid JSON"
903
+ },
904
+ id: null
905
+ }), {
906
+ status: 400,
907
+ headers: {
908
+ "Content-Type": "application/json",
909
+ ...this.getHeaders()
910
+ }
911
+ });
912
+ }
913
+ let messages;
914
+ try {
915
+ if (Array.isArray(rawMessage)) messages = rawMessage.map((msg) => JSONRPCMessageSchema.parse(msg));
916
+ else messages = [JSONRPCMessageSchema.parse(rawMessage)];
917
+ } catch {
918
+ return new Response(JSON.stringify({
919
+ jsonrpc: "2.0",
920
+ error: {
921
+ code: -32700,
922
+ message: "Parse error: Invalid JSON-RPC message"
923
+ },
924
+ id: null
925
+ }), {
926
+ status: 400,
927
+ headers: {
928
+ "Content-Type": "application/json",
929
+ ...this.getHeaders()
930
+ }
931
+ });
932
+ }
933
+ const requestInfo = { headers: Object.fromEntries(request.headers.entries()) };
934
+ const isInitializationRequest = messages.some(isInitializeRequest);
935
+ if (isInitializationRequest) {
936
+ if (this.initialized && this.sessionId !== void 0) return new Response(JSON.stringify({
937
+ jsonrpc: "2.0",
938
+ error: {
939
+ code: -32600,
940
+ message: "Invalid Request: Server already initialized"
941
+ },
942
+ id: null
943
+ }), {
944
+ status: 400,
945
+ headers: {
946
+ "Content-Type": "application/json",
947
+ ...this.getHeaders()
948
+ }
949
+ });
950
+ if (messages.length > 1) return new Response(JSON.stringify({
951
+ jsonrpc: "2.0",
952
+ error: {
953
+ code: -32600,
954
+ message: "Invalid Request: Only one initialization request is allowed"
955
+ },
956
+ id: null
957
+ }), {
958
+ status: 400,
959
+ headers: {
960
+ "Content-Type": "application/json",
961
+ ...this.getHeaders()
962
+ }
963
+ });
964
+ this.sessionId = this.sessionIdGenerator?.();
965
+ this.initialized = true;
966
+ await this.saveState();
967
+ if (this.sessionId && this.onsessioninitialized) this.onsessioninitialized(this.sessionId);
968
+ }
969
+ if (!isInitializationRequest) {
970
+ const sessionError = this.validateSession(request);
971
+ if (sessionError) return sessionError;
972
+ const versionError = this.validateProtocolVersion(request);
973
+ if (versionError) return versionError;
974
+ }
975
+ if (!messages.some(isJSONRPCRequest)) {
976
+ for (const message of messages) this.onmessage?.(message, { requestInfo });
977
+ return new Response(null, {
978
+ status: 202,
979
+ headers: { ...this.getHeaders() }
980
+ });
981
+ }
982
+ const streamId = crypto.randomUUID();
983
+ if (this.enableJsonResponse) return new Promise((resolve) => {
984
+ this.streamMapping.set(streamId, {
985
+ resolveJson: resolve,
986
+ cleanup: () => {
987
+ this.streamMapping.delete(streamId);
988
+ }
989
+ });
990
+ for (const message of messages) if (isJSONRPCRequest(message)) this.requestToStreamMapping.set(message.id, streamId);
991
+ for (const message of messages) this.onmessage?.(message, { requestInfo });
992
+ });
993
+ const { readable, writable } = new TransformStream();
994
+ const writer = writable.getWriter();
995
+ const encoder = new TextEncoder();
996
+ const headers = new Headers({
997
+ "Content-Type": "text/event-stream",
998
+ "Cache-Control": "no-cache",
999
+ Connection: "keep-alive",
1000
+ ...this.getHeaders()
1001
+ });
1002
+ if (this.sessionId !== void 0) headers.set("mcp-session-id", this.sessionId);
1003
+ this.streamMapping.set(streamId, {
1004
+ writer,
1005
+ encoder,
1006
+ cleanup: () => {
1007
+ this.streamMapping.delete(streamId);
1008
+ writer.close().catch(() => {});
1009
+ }
1010
+ });
1011
+ for (const message of messages) if (isJSONRPCRequest(message)) this.requestToStreamMapping.set(message.id, streamId);
1012
+ for (const message of messages) this.onmessage?.(message, { requestInfo });
1013
+ return new Response(readable, { headers });
1014
+ }
1015
+ async handleDeleteRequest(request) {
1016
+ const sessionError = this.validateSession(request);
1017
+ if (sessionError) return sessionError;
1018
+ const versionError = this.validateProtocolVersion(request);
1019
+ if (versionError) return versionError;
1020
+ await this.close();
1021
+ return new Response(null, {
1022
+ status: 200,
1023
+ headers: { ...this.getHeaders() }
1024
+ });
1025
+ }
1026
+ handleOptionsRequest(_request) {
1027
+ return new Response(null, {
1028
+ status: 200,
1029
+ headers: { ...this.getHeaders({ forPreflight: true }) }
1030
+ });
1031
+ }
1032
+ handleUnsupportedRequest() {
1033
+ return new Response(JSON.stringify({
1034
+ jsonrpc: "2.0",
1035
+ error: {
1036
+ code: -32e3,
1037
+ message: "Method not allowed."
1038
+ },
1039
+ id: null
1040
+ }), {
1041
+ status: 405,
1042
+ headers: {
1043
+ Allow: "GET, POST, DELETE, OPTIONS",
1044
+ "Content-Type": "application/json"
1045
+ }
1046
+ });
1047
+ }
1048
+ validateSession(request) {
1049
+ if (this.sessionIdGenerator === void 0) return;
1050
+ if (!this.initialized) return new Response(JSON.stringify({
1051
+ jsonrpc: "2.0",
1052
+ error: {
1053
+ code: -32e3,
1054
+ message: "Bad Request: Server not initialized"
1055
+ },
1056
+ id: null
1057
+ }), {
1058
+ status: 400,
1059
+ headers: {
1060
+ "Content-Type": "application/json",
1061
+ ...this.getHeaders()
1062
+ }
1063
+ });
1064
+ const sessionId = request.headers.get("mcp-session-id");
1065
+ if (!sessionId) return new Response(JSON.stringify({
1066
+ jsonrpc: "2.0",
1067
+ error: {
1068
+ code: -32e3,
1069
+ message: "Bad Request: Mcp-Session-Id header is required"
1070
+ },
1071
+ id: null
1072
+ }), {
1073
+ status: 400,
1074
+ headers: {
1075
+ "Content-Type": "application/json",
1076
+ ...this.getHeaders()
1077
+ }
1078
+ });
1079
+ if (sessionId !== this.sessionId) return new Response(JSON.stringify({
1080
+ jsonrpc: "2.0",
1081
+ error: {
1082
+ code: -32001,
1083
+ message: "Session not found"
1084
+ },
1085
+ id: null
1086
+ }), {
1087
+ status: 404,
1088
+ headers: {
1089
+ "Content-Type": "application/json",
1090
+ ...this.getHeaders()
1091
+ }
1092
+ });
1093
+ }
1094
+ async close() {
1095
+ for (const { cleanup } of this.streamMapping.values()) cleanup();
1096
+ this.streamMapping.clear();
1097
+ this.requestResponseMap.clear();
1098
+ this.onclose?.();
1099
+ }
1100
+ async send(message, options) {
1101
+ let requestId = options?.relatedRequestId;
1102
+ if (isJSONRPCResponse(message) || isJSONRPCError(message)) requestId = message.id;
1103
+ if (requestId === void 0) {
1104
+ if (isJSONRPCResponse(message) || isJSONRPCError(message)) throw new Error("Cannot send a response on a standalone SSE stream unless resuming a previous client request");
1105
+ const standaloneSse = this.streamMapping.get(this.standaloneSseStreamId);
1106
+ if (standaloneSse === void 0) return;
1107
+ if (standaloneSse.writer && standaloneSse.encoder) {
1108
+ const data = `event: message\ndata: ${JSON.stringify(message)}\n\n`;
1109
+ await standaloneSse.writer.write(standaloneSse.encoder.encode(data));
1110
+ }
1111
+ return;
1112
+ }
1113
+ const streamId = this.requestToStreamMapping.get(requestId);
1114
+ if (!streamId) throw new Error(`No connection established for request ID: ${String(requestId)}`);
1115
+ const response = this.streamMapping.get(streamId);
1116
+ if (!response) throw new Error(`No connection established for request ID: ${String(requestId)}`);
1117
+ if (!this.enableJsonResponse) {
1118
+ if (response.writer && response.encoder) {
1119
+ const data = `event: message\ndata: ${JSON.stringify(message)}\n\n`;
1120
+ await response.writer.write(response.encoder.encode(data));
1121
+ }
1122
+ }
1123
+ if (isJSONRPCResponse(message) || isJSONRPCError(message)) {
1124
+ this.requestResponseMap.set(requestId, message);
1125
+ const relatedIds = Array.from(this.requestToStreamMapping.entries()).filter(([, sid]) => sid === streamId).map(([id]) => id);
1126
+ if (relatedIds.every((id) => this.requestResponseMap.has(id))) {
1127
+ if (this.enableJsonResponse && response.resolveJson) {
1128
+ const responses = relatedIds.map((id) => this.requestResponseMap.get(id));
1129
+ const headers = new Headers({
1130
+ "Content-Type": "application/json",
1131
+ ...this.getHeaders()
1132
+ });
1133
+ if (this.sessionId !== void 0) headers.set("mcp-session-id", this.sessionId);
1134
+ const body = responses.length === 1 ? responses[0] : responses;
1135
+ response.resolveJson(new Response(JSON.stringify(body), { headers }));
1136
+ } else response.cleanup();
1137
+ for (const id of relatedIds) {
1138
+ this.requestResponseMap.delete(id);
1139
+ this.requestToStreamMapping.delete(id);
1140
+ }
1141
+ }
1142
+ }
1143
+ }
1144
+ };
1145
+
1146
+ //#endregion
1147
+ //#region src/mcp/auth-context.ts
1148
+ const authContextStorage = new AsyncLocalStorage();
1149
+ function getMcpAuthContext() {
1150
+ return authContextStorage.getStore();
1151
+ }
1152
+ function runWithAuthContext(context, fn) {
1153
+ return authContextStorage.run(context, fn);
1154
+ }
1155
+
1156
+ //#endregion
1157
+ //#region src/mcp/handler.ts
1158
+ function createMcpHandler(server, options = {}) {
1159
+ const route = options.route ?? "/mcp";
1160
+ return async (request, _env, ctx) => {
1161
+ const url = new URL(request.url);
1162
+ if (route && url.pathname !== route) return new Response("Not Found", { status: 404 });
1163
+ const transport = options.transport ?? new WorkerTransport({
1164
+ sessionIdGenerator: options.sessionIdGenerator,
1165
+ enableJsonResponse: options.enableJsonResponse,
1166
+ onsessioninitialized: options.onsessioninitialized,
1167
+ corsOptions: options.corsOptions,
1168
+ storage: options.storage
1169
+ });
1170
+ const buildAuthContext = () => {
1171
+ if (options.authContext) return options.authContext;
1172
+ if (ctx.props && Object.keys(ctx.props).length > 0) return { props: ctx.props };
1173
+ };
1174
+ const handleRequest = async () => {
1175
+ return await transport.handleRequest(request);
1176
+ };
1177
+ const authContext = buildAuthContext();
1178
+ if (!transport.started) await server.connect(transport);
1179
+ try {
1180
+ if (authContext) return await runWithAuthContext(authContext, handleRequest);
1181
+ else return await handleRequest();
1182
+ } catch (error) {
1183
+ console.error("MCP handler error:", error);
1184
+ return new Response(JSON.stringify({
1185
+ jsonrpc: "2.0",
1186
+ error: {
1187
+ code: -32603,
1188
+ message: error instanceof Error ? error.message : "Internal server error"
1189
+ },
1190
+ id: null
1191
+ }), {
1192
+ status: 500,
1193
+ headers: { "Content-Type": "application/json" }
1194
+ });
1195
+ }
1196
+ };
1197
+ }
1198
+ let didWarnAboutExperimentalCreateMcpHandler = false;
1199
+ /**
1200
+ * @deprecated This has been renamed to createMcpHandler, and experimental_createMcpHandler will be removed in the next major version
1201
+ */
1202
+ function experimental_createMcpHandler(server, options = {}) {
1203
+ if (!didWarnAboutExperimentalCreateMcpHandler) {
1204
+ didWarnAboutExperimentalCreateMcpHandler = true;
1205
+ console.warn("experimental_createMcpHandler is deprecated, use createMcpHandler instead. experimental_createMcpHandler will be removed in the next major version.");
1206
+ }
1207
+ return createMcpHandler(server, options);
1208
+ }
1209
+
627
1210
  //#endregion
628
1211
  //#region src/mcp/index.ts
629
1212
  var McpAgent = class McpAgent extends Agent {
@@ -663,8 +1246,14 @@ var McpAgent = class McpAgent extends Agent {
663
1246
  /** Returns a new transport matching the type of the Agent. */
664
1247
  initTransport() {
665
1248
  switch (this.getTransportType()) {
666
- case "sse": return new McpSSETransport(() => this.getWebSocket());
667
- case "streamable-http": return new StreamableHTTPServerTransport({});
1249
+ case "sse": return new McpSSETransport();
1250
+ case "streamable-http": {
1251
+ const transport = new StreamableHTTPServerTransport({});
1252
+ transport.messageInterceptor = async (message) => {
1253
+ return this._handleElicitationResponse(message);
1254
+ };
1255
+ return transport;
1256
+ }
668
1257
  }
669
1258
  }
670
1259
  /** Update and store the props */
@@ -716,7 +1305,7 @@ var McpAgent = class McpAgent extends Agent {
716
1305
  }
717
1306
  }
718
1307
  /** Handles MCP Messages for the legacy SSE transport. */
719
- async onSSEMcpMessage(_sessionId, messageBody) {
1308
+ async onSSEMcpMessage(_sessionId, messageBody, extraInfo) {
720
1309
  if (this.getTransportType() !== "sse") return /* @__PURE__ */ new Error("Internal Server Error: Expected SSE transport");
721
1310
  try {
722
1311
  let parsedMessage;
@@ -727,7 +1316,7 @@ var McpAgent = class McpAgent extends Agent {
727
1316
  throw error;
728
1317
  }
729
1318
  if (await this._handleElicitationResponse(parsedMessage)) return null;
730
- this._transport?.onmessage?.(parsedMessage);
1319
+ this._transport?.onmessage?.(parsedMessage, extraInfo);
731
1320
  return null;
732
1321
  } catch (error) {
733
1322
  console.error("Error forwarding message to SSE:", error);
@@ -813,7 +1402,7 @@ var McpAgent = class McpAgent extends Agent {
813
1402
  /** Return a handler for the given path for this MCP.
814
1403
  * Defaults to Streamable HTTP transport.
815
1404
  */
816
- static serve(path, { binding = "MCP_OBJECT", corsOptions, transport = "streamable-http" } = {}) {
1405
+ static serve(path, { binding = "MCP_OBJECT", corsOptions, transport = "streamable-http", jurisdiction } = {}) {
817
1406
  return { async fetch(request, env, ctx) {
818
1407
  const corsResponse = handleCORS(request, corsOptions);
819
1408
  if (corsResponse) return corsResponse;
@@ -822,8 +1411,14 @@ var McpAgent = class McpAgent extends Agent {
822
1411
  if (!isDurableObjectNamespace(bindingValue)) throw new Error(`Invalid McpAgent binding for ${binding}. Make sure it's a Durable Object binding.`);
823
1412
  const namespace = bindingValue;
824
1413
  switch (transport) {
825
- case "streamable-http": return createStreamingHttpHandler(path, namespace, corsOptions)(request, ctx);
826
- case "sse": return createLegacySseHandler(path, namespace, corsOptions)(request, ctx);
1414
+ case "streamable-http": return createStreamingHttpHandler(path, namespace, {
1415
+ corsOptions,
1416
+ jurisdiction
1417
+ })(request, ctx);
1418
+ case "sse": return createLegacySseHandler(path, namespace, {
1419
+ corsOptions,
1420
+ jurisdiction
1421
+ })(request, ctx);
827
1422
  default: return new Response("Invalid MCP transport mode. Only `streamable-http` or `sse` are allowed.", { status: 500 });
828
1423
  }
829
1424
  } };
@@ -843,5 +1438,5 @@ var McpAgent = class McpAgent extends Agent {
843
1438
  };
844
1439
 
845
1440
  //#endregion
846
- export { ElicitRequestSchema, McpAgent, SSEEdgeClientTransport, StreamableHTTPEdgeClientTransport };
1441
+ export { ElicitRequestSchema, McpAgent, SSEEdgeClientTransport, StreamableHTTPEdgeClientTransport, WorkerTransport, createMcpHandler, experimental_createMcpHandler, getMcpAuthContext };
847
1442
  //# sourceMappingURL=index.js.map