agents 0.0.0-8a4558c → 0.0.0-8bf3250

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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MCPClientManager,
3
3
  getNamespacedData
4
- } from "../chunk-OYJXQRRH.js";
4
+ } from "../chunk-E3LCYPCB.js";
5
5
  export {
6
6
  MCPClientManager,
7
7
  getNamespacedData
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  DurableObjectOAuthClientProvider
3
- } from "../chunk-BZXOAZUX.js";
3
+ } from "../chunk-767EASBA.js";
4
4
  export {
5
5
  DurableObjectOAuthClientProvider
6
6
  };
@@ -1,17 +1,17 @@
1
1
  import { MCPClientManager } from './client.js';
2
2
  import { DurableObject } from 'cloudflare:workers';
3
- import { Connection, WSMessage } from 'partyserver';
4
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
3
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { Connection, WSMessage } from 'partyserver';
6
6
  import 'zod';
7
- import '@modelcontextprotocol/sdk/types.js';
8
7
  import '@modelcontextprotocol/sdk/client/index.js';
9
8
  import '@modelcontextprotocol/sdk/client/sse.js';
9
+ import '@modelcontextprotocol/sdk/shared/protocol.js';
10
+ import '@modelcontextprotocol/sdk/types.js';
11
+ import 'ai';
10
12
  import './do-oauth-client-provider.js';
11
13
  import '@modelcontextprotocol/sdk/client/auth.js';
12
14
  import '@modelcontextprotocol/sdk/shared/auth.js';
13
- import '@modelcontextprotocol/sdk/shared/protocol.js';
14
- import 'ai';
15
15
 
16
16
  interface CORSOptions {
17
17
  origin?: string;
@@ -57,7 +57,7 @@ declare abstract class McpAgent<Env = unknown, State = unknown, Props extends Re
57
57
  getWebSocket(): WebSocket | null;
58
58
  getWebSocketForResponseID(id: string): WebSocket | null;
59
59
  onMessage(connection: Connection, event: WSMessage): Promise<void>;
60
- onSSEMcpMessage(sessionId: string, request: Request): Promise<Error | null>;
60
+ onSSEMcpMessage(_sessionId: string, request: Request): Promise<Error | null>;
61
61
  webSocketMessage(ws: WebSocket, event: ArrayBuffer | string): Promise<void>;
62
62
  webSocketError(ws: WebSocket, error: unknown): Promise<void>;
63
63
  webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean): Promise<void>;
package/dist/mcp/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  Agent
3
- } from "../chunk-6RPGDIE2.js";
4
- import "../chunk-OYJXQRRH.js";
5
- import "../chunk-BZXOAZUX.js";
6
- import "../chunk-VCSB47AK.js";
3
+ } from "../chunk-4CIGD73X.js";
4
+ import "../chunk-E3LCYPCB.js";
5
+ import "../chunk-767EASBA.js";
6
+ import "../chunk-NKZZ66QY.js";
7
7
 
8
8
  // src/mcp/index.ts
9
9
  import { DurableObject } from "cloudflare:workers";
@@ -16,14 +16,14 @@ import {
16
16
  JSONRPCMessageSchema
17
17
  } from "@modelcontextprotocol/sdk/types.js";
18
18
  var MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
19
- function corsHeaders(request, corsOptions = {}) {
19
+ function corsHeaders(_request, corsOptions = {}) {
20
20
  const origin = "*";
21
21
  return {
22
- "Access-Control-Allow-Origin": corsOptions.origin || origin,
22
+ "Access-Control-Allow-Headers": corsOptions.headers || "Content-Type, mcp-session-id, mcp-protocol-version",
23
23
  "Access-Control-Allow-Methods": corsOptions.methods || "GET, POST, OPTIONS",
24
- "Access-Control-Allow-Headers": corsOptions.headers || "Content-Type, mcp-session-id",
25
- "Access-Control-Max-Age": (corsOptions.maxAge || 86400).toString(),
26
- "Access-Control-Expose-Headers": corsOptions.exposeHeaders || "mcp-session-id"
24
+ "Access-Control-Allow-Origin": corsOptions.origin || origin,
25
+ "Access-Control-Expose-Headers": corsOptions.exposeHeaders || "mcp-session-id",
26
+ "Access-Control-Max-Age": (corsOptions.maxAge || 86400).toString()
27
27
  };
28
28
  }
29
29
  function isDurableObjectNamespace(namespace) {
@@ -141,6 +141,7 @@ var McpAgent = class _McpAgent extends DurableObject {
141
141
  setState(state) {
142
142
  return this._agent.setState(state);
143
143
  }
144
+ // biome-ignore lint/correctness/noUnusedFunctionParameters: overriden later
144
145
  onStateUpdate(state, source) {
145
146
  }
146
147
  async onStart() {
@@ -287,7 +288,7 @@ var McpAgent = class _McpAgent extends DurableObject {
287
288
  }
288
289
  // All messages received over SSE after the initial connection has been established
289
290
  // will be passed here
290
- async onSSEMcpMessage(sessionId, request) {
291
+ async onSSEMcpMessage(_sessionId, request) {
291
292
  if (this._status !== "started") {
292
293
  await this._initialize();
293
294
  }
@@ -420,10 +421,10 @@ data: ${JSON.stringify(result.data)}
420
421
  onMessage(event).catch(console.error);
421
422
  });
422
423
  ws.addEventListener("error", (error) => {
423
- async function onError(error2) {
424
+ async function onError(_error) {
424
425
  try {
425
426
  await writer.close();
426
- } catch (e) {
427
+ } catch (_e) {
427
428
  }
428
429
  }
429
430
  onError(error).catch(console.error);
@@ -440,9 +441,9 @@ data: ${JSON.stringify(result.data)}
440
441
  });
441
442
  return new Response(readable, {
442
443
  headers: {
443
- "Content-Type": "text/event-stream",
444
444
  "Cache-Control": "no-cache",
445
445
  Connection: "keep-alive",
446
+ "Content-Type": "text/event-stream",
446
447
  ...corsHeaders(request, corsOptions)
447
448
  }
448
449
  });
@@ -478,23 +479,23 @@ data: ${JSON.stringify(result.data)}
478
479
  const error = await doStub.onSSEMcpMessage(sessionId, request);
479
480
  if (error) {
480
481
  return new Response(error.message, {
481
- status: 400,
482
482
  headers: {
483
- "Content-Type": "text/event-stream",
484
483
  "Cache-Control": "no-cache",
485
484
  Connection: "keep-alive",
485
+ "Content-Type": "text/event-stream",
486
486
  ...corsHeaders(request, corsOptions)
487
- }
487
+ },
488
+ status: 400
488
489
  });
489
490
  }
490
491
  return new Response("Accepted", {
491
- status: 202,
492
492
  headers: {
493
- "Content-Type": "text/event-stream",
494
493
  "Cache-Control": "no-cache",
495
494
  Connection: "keep-alive",
495
+ "Content-Type": "text/event-stream",
496
496
  ...corsHeaders(request, corsOptions)
497
- }
497
+ },
498
+ status: 202
498
499
  });
499
500
  }
500
501
  return new Response("Not Found", { status: 404 });
@@ -532,24 +533,24 @@ data: ${JSON.stringify(result.data)}
532
533
  const acceptHeader = request.headers.get("accept");
533
534
  if (!acceptHeader?.includes("application/json") || !acceptHeader.includes("text/event-stream")) {
534
535
  const body2 = JSON.stringify({
535
- jsonrpc: "2.0",
536
536
  error: {
537
537
  code: -32e3,
538
538
  message: "Not Acceptable: Client must accept both application/json and text/event-stream"
539
539
  },
540
- id: null
540
+ id: null,
541
+ jsonrpc: "2.0"
541
542
  });
542
543
  return new Response(body2, { status: 406 });
543
544
  }
544
545
  const ct = request.headers.get("content-type");
545
546
  if (!ct || !ct.includes("application/json")) {
546
547
  const body2 = JSON.stringify({
547
- jsonrpc: "2.0",
548
548
  error: {
549
549
  code: -32e3,
550
550
  message: "Unsupported Media Type: Content-Type must be application/json"
551
551
  },
552
- id: null
552
+ id: null,
553
+ jsonrpc: "2.0"
553
554
  });
554
555
  return new Response(body2, { status: 415 });
555
556
  }
@@ -559,12 +560,12 @@ data: ${JSON.stringify(result.data)}
559
560
  );
560
561
  if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {
561
562
  const body2 = JSON.stringify({
562
- jsonrpc: "2.0",
563
563
  error: {
564
564
  code: -32e3,
565
565
  message: `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE_BYTES} bytes`
566
566
  },
567
- id: null
567
+ id: null,
568
+ jsonrpc: "2.0"
568
569
  });
569
570
  return new Response(body2, { status: 413 });
570
571
  }
@@ -572,14 +573,14 @@ data: ${JSON.stringify(result.data)}
572
573
  let rawMessage;
573
574
  try {
574
575
  rawMessage = await request.json();
575
- } catch (error) {
576
+ } catch (_error) {
576
577
  const body2 = JSON.stringify({
577
- jsonrpc: "2.0",
578
578
  error: {
579
579
  code: -32700,
580
580
  message: "Parse error: Invalid JSON"
581
581
  },
582
- id: null
582
+ id: null,
583
+ jsonrpc: "2.0"
583
584
  });
584
585
  return new Response(body2, { status: 400 });
585
586
  }
@@ -593,12 +594,12 @@ data: ${JSON.stringify(result.data)}
593
594
  for (const msg of arrayMessage) {
594
595
  if (!JSONRPCMessageSchema.safeParse(msg).success) {
595
596
  const body2 = JSON.stringify({
596
- jsonrpc: "2.0",
597
597
  error: {
598
598
  code: -32700,
599
599
  message: "Parse error: Invalid JSON-RPC message"
600
600
  },
601
- id: null
601
+ id: null,
602
+ jsonrpc: "2.0"
602
603
  });
603
604
  return new Response(body2, { status: 400 });
604
605
  }
@@ -609,34 +610,34 @@ data: ${JSON.stringify(result.data)}
609
610
  );
610
611
  if (isInitializationRequest && sessionId) {
611
612
  const body2 = JSON.stringify({
612
- jsonrpc: "2.0",
613
613
  error: {
614
614
  code: -32600,
615
615
  message: "Invalid Request: Initialization requests must not include a sessionId"
616
616
  },
617
- id: null
617
+ id: null,
618
+ jsonrpc: "2.0"
618
619
  });
619
620
  return new Response(body2, { status: 400 });
620
621
  }
621
622
  if (isInitializationRequest && messages.length > 1) {
622
623
  const body2 = JSON.stringify({
623
- jsonrpc: "2.0",
624
624
  error: {
625
625
  code: -32600,
626
626
  message: "Invalid Request: Only one initialization request is allowed"
627
627
  },
628
- id: null
628
+ id: null,
629
+ jsonrpc: "2.0"
629
630
  });
630
631
  return new Response(body2, { status: 400 });
631
632
  }
632
633
  if (!isInitializationRequest && !sessionId) {
633
634
  const body2 = JSON.stringify({
634
- jsonrpc: "2.0",
635
635
  error: {
636
636
  code: -32e3,
637
637
  message: "Bad Request: Mcp-Session-Id header is required"
638
638
  },
639
- id: null
639
+ id: null,
640
+ jsonrpc: "2.0"
640
641
  });
641
642
  return new Response(body2, { status: 400 });
642
643
  }
@@ -649,12 +650,12 @@ data: ${JSON.stringify(result.data)}
649
650
  await doStub.setInitialized();
650
651
  } else if (!isInitialized) {
651
652
  const body2 = JSON.stringify({
652
- jsonrpc: "2.0",
653
653
  error: {
654
654
  code: -32001,
655
655
  message: "Session not found"
656
656
  },
657
- id: null
657
+ id: null,
658
+ jsonrpc: "2.0"
658
659
  });
659
660
  return new Response(body2, { status: 404 });
660
661
  }
@@ -677,12 +678,12 @@ data: ${JSON.stringify(result.data)}
677
678
  console.error("Failed to establish WebSocket connection");
678
679
  await writer.close();
679
680
  const body2 = JSON.stringify({
680
- jsonrpc: "2.0",
681
681
  error: {
682
682
  code: -32001,
683
683
  message: "Failed to establish WebSocket connection"
684
684
  },
685
- id: null
685
+ id: null,
686
+ jsonrpc: "2.0"
686
687
  });
687
688
  return new Response(body2, { status: 500 });
688
689
  }
@@ -715,10 +716,10 @@ data: ${JSON.stringify(result.data)}
715
716
  onMessage(event).catch(console.error);
716
717
  });
717
718
  ws.addEventListener("error", (error) => {
718
- async function onError(error2) {
719
+ async function onError(_error) {
719
720
  try {
720
721
  await writer.close();
721
- } catch (e) {
722
+ } catch (_e) {
722
723
  }
723
724
  }
724
725
  onError(error).catch(console.error);
@@ -742,8 +743,8 @@ data: ${JSON.stringify(result.data)}
742
743
  }
743
744
  ws.close();
744
745
  return new Response(null, {
745
- status: 202,
746
- headers: corsHeaders(request, corsOptions)
746
+ headers: corsHeaders(request, corsOptions),
747
+ status: 202
747
748
  });
748
749
  }
749
750
  for (const message of messages) {
@@ -754,9 +755,9 @@ data: ${JSON.stringify(result.data)}
754
755
  }
755
756
  return new Response(readable, {
756
757
  headers: {
757
- "Content-Type": "text/event-stream",
758
758
  "Cache-Control": "no-cache",
759
759
  Connection: "keep-alive",
760
+ "Content-Type": "text/event-stream",
760
761
  "mcp-session-id": sessionId,
761
762
  ...corsHeaders(request, corsOptions)
762
763
  },
@@ -764,12 +765,12 @@ data: ${JSON.stringify(result.data)}
764
765
  });
765
766
  }
766
767
  const body = JSON.stringify({
767
- jsonrpc: "2.0",
768
768
  error: {
769
769
  code: -32e3,
770
770
  message: "Method not allowed"
771
771
  },
772
- id: null
772
+ id: null,
773
+ jsonrpc: "2.0"
773
774
  });
774
775
  return new Response(body, { status: 405 });
775
776
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mcp/index.ts"],"sourcesContent":["import { DurableObject } from \"cloudflare:workers\";\nimport type { Connection, WSMessage } from \"../\";\nimport { Agent } from \"../\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { JSONRPCMessage } from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n InitializeRequestSchema,\n isJSONRPCError,\n isJSONRPCNotification,\n isJSONRPCRequest,\n isJSONRPCResponse,\n JSONRPCMessageSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\n\nconst MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024; // 4MB\n\n// CORS helper functions\nfunction corsHeaders(request: Request, corsOptions: CORSOptions = {}) {\n const origin = \"*\";\n return {\n \"Access-Control-Allow-Origin\": corsOptions.origin || origin,\n \"Access-Control-Allow-Methods\": corsOptions.methods || \"GET, POST, OPTIONS\",\n \"Access-Control-Allow-Headers\":\n corsOptions.headers || \"Content-Type, mcp-session-id\",\n \"Access-Control-Max-Age\": (corsOptions.maxAge || 86400).toString(),\n \"Access-Control-Expose-Headers\":\n corsOptions.exposeHeaders || \"mcp-session-id\",\n };\n}\n\nfunction isDurableObjectNamespace(\n namespace: unknown\n): namespace is DurableObjectNamespace<McpAgent> {\n return (\n typeof namespace === \"object\" &&\n namespace !== null &&\n \"newUniqueId\" in namespace &&\n typeof namespace.newUniqueId === \"function\" &&\n \"idFromName\" in namespace &&\n typeof namespace.idFromName === \"function\"\n );\n}\n\nfunction handleCORS(\n request: Request,\n corsOptions?: CORSOptions\n): Response | null {\n if (request.method === \"OPTIONS\") {\n return new Response(null, { headers: corsHeaders(request, corsOptions) });\n }\n\n return null;\n}\n\ninterface CORSOptions {\n origin?: string;\n methods?: string;\n headers?: string;\n maxAge?: number;\n exposeHeaders?: string;\n}\n\nclass McpSSETransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n sessionId?: string;\n\n private _getWebSocket: () => WebSocket | null;\n private _started = false;\n constructor(getWebSocket: () => WebSocket | null) {\n this._getWebSocket = getWebSocket;\n }\n\n async start() {\n // The transport does not manage the WebSocket connection since it's terminated\n // by the Durable Object in order to allow hibernation. There's nothing to initialize.\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n async send(message: JSONRPCMessage) {\n if (!this._started) {\n throw new Error(\"Transport not started\");\n }\n const websocket = this._getWebSocket();\n if (!websocket) {\n throw new Error(\"WebSocket not connected\");\n }\n try {\n websocket.send(JSON.stringify(message));\n } catch (error) {\n this.onerror?.(error as Error);\n throw error;\n }\n }\n\n async close() {\n // Similar to start, the only thing to do is to pass the event on to the server\n this.onclose?.();\n }\n}\n\ntype TransportType = \"sse\" | \"streamable-http\" | \"unset\";\n\nclass McpStreamableHttpTransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n sessionId?: string;\n\n // TODO: If there is an open connection to send server-initiated messages\n // back, we should use that connection\n private _getWebSocketForGetRequest: () => WebSocket | null;\n\n // Get the appropriate websocket connection for a given message id\n private _getWebSocketForMessageID: (id: string) => WebSocket | null;\n\n // Notify the server that a response has been sent for a given message id\n // so that it may clean up it's mapping of message ids to connections\n // once they are no longer needed\n private _notifyResponseIdSent: (id: string) => void;\n\n private _started = false;\n constructor(\n getWebSocketForMessageID: (id: string) => WebSocket | null,\n notifyResponseIdSent: (id: string | number) => void\n ) {\n this._getWebSocketForMessageID = getWebSocketForMessageID;\n this._notifyResponseIdSent = notifyResponseIdSent;\n // TODO\n this._getWebSocketForGetRequest = () => null;\n }\n\n async start() {\n // The transport does not manage the WebSocket connection since it's terminated\n // by the Durable Object in order to allow hibernation. There's nothing to initialize.\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n async send(message: JSONRPCMessage) {\n if (!this._started) {\n throw new Error(\"Transport not started\");\n }\n\n let websocket: WebSocket | null = null;\n\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n websocket = this._getWebSocketForMessageID(message.id.toString());\n if (!websocket) {\n throw new Error(\n `Could not find WebSocket for message id: ${message.id}`\n );\n }\n } else if (isJSONRPCRequest(message)) {\n // requests originating from the server must be sent over the\n // the connection created by a GET request\n websocket = this._getWebSocketForGetRequest();\n } else if (isJSONRPCNotification(message)) {\n // notifications do not have an id\n // but do have a relatedRequestId field\n // so that they can be sent to the correct connection\n websocket = null;\n }\n\n try {\n websocket?.send(JSON.stringify(message));\n if (isJSONRPCResponse(message)) {\n this._notifyResponseIdSent(message.id.toString());\n }\n } catch (error) {\n this.onerror?.(error as Error);\n throw error;\n }\n }\n\n async close() {\n // Similar to start, the only thing to do is to pass the event on to the server\n this.onclose?.();\n }\n}\n\ntype MaybePromise<T> = T | Promise<T>;\n\nexport abstract class McpAgent<\n Env = unknown,\n State = unknown,\n Props extends Record<string, unknown> = Record<string, unknown>,\n> extends DurableObject<Env> {\n private _status: \"zero\" | \"starting\" | \"started\" = \"zero\";\n private _transport?: Transport;\n private _transportType: TransportType = \"unset\";\n private _requestIdToConnectionId: Map<string | number, string> = new Map();\n\n /**\n * Since McpAgent's _aren't_ yet real \"Agents\", let's only expose a couple of the methods\n * to the outer class: initialState/state/setState/onStateUpdate/sql\n */\n private _agent: Agent<Env, State>;\n\n get mcp() {\n return this._agent.mcp;\n }\n\n protected constructor(ctx: DurableObjectState, env: Env) {\n super(ctx, env);\n const self = this;\n\n this._agent = new (class extends Agent<Env, State> {\n static options = {\n hibernate: true,\n };\n\n onStateUpdate(state: State | undefined, source: Connection | \"server\") {\n return self.onStateUpdate(state, source);\n }\n\n async onMessage(\n connection: Connection,\n message: WSMessage\n ): Promise<void> {\n return self.onMessage(connection, message);\n }\n })(ctx, env);\n }\n\n /**\n * Agents API allowlist\n */\n initialState!: State;\n get state() {\n return this._agent.state;\n }\n sql<T = Record<string, string | number | boolean | null>>(\n strings: TemplateStringsArray,\n ...values: (string | number | boolean | null)[]\n ) {\n return this._agent.sql<T>(strings, ...values);\n }\n\n setState(state: State) {\n return this._agent.setState(state);\n }\n onStateUpdate(state: State | undefined, source: Connection | \"server\") {\n // override this to handle state updates\n }\n async onStart() {\n const self = this;\n\n this._agent = new (class extends Agent<Env, State> {\n initialState: State = self.initialState;\n static options = {\n hibernate: true,\n };\n\n onStateUpdate(state: State | undefined, source: Connection | \"server\") {\n return self.onStateUpdate(state, source);\n }\n\n async onMessage(connection: Connection, event: WSMessage) {\n return self.onMessage(connection, event);\n }\n })(this.ctx, this.env);\n\n this.props = (await this.ctx.storage.get(\"props\")) as Props;\n this._transportType = (await this.ctx.storage.get(\n \"transportType\"\n )) as TransportType;\n await this._init(this.props);\n\n const server = await this.server;\n\n // Connect to the MCP server\n if (this._transportType === \"sse\") {\n this._transport = new McpSSETransport(() => this.getWebSocket());\n await server.connect(this._transport);\n } else if (this._transportType === \"streamable-http\") {\n this._transport = new McpStreamableHttpTransport(\n (id) => this.getWebSocketForResponseID(id),\n (id) => this._requestIdToConnectionId.delete(id)\n );\n await server.connect(this._transport);\n }\n }\n\n /**\n * McpAgent API\n */\n abstract server: MaybePromise<McpServer | Server>;\n props!: Props;\n initRun = false;\n\n abstract init(): Promise<void>;\n\n async _init(props: Props) {\n await this.ctx.storage.put(\"props\", props ?? {});\n if (!this.ctx.storage.get(\"transportType\")) {\n await this.ctx.storage.put(\"transportType\", \"unset\");\n }\n this.props = props;\n if (!this.initRun) {\n this.initRun = true;\n await this.init();\n }\n }\n\n async setInitialized() {\n await this.ctx.storage.put(\"initialized\", true);\n }\n\n async isInitialized() {\n return (await this.ctx.storage.get(\"initialized\")) === true;\n }\n\n private async _initialize(): Promise<void> {\n await this.ctx.blockConcurrencyWhile(async () => {\n this._status = \"starting\";\n await this.onStart();\n this._status = \"started\";\n });\n }\n\n // Allow the worker to fetch a websocket connection to the agent\n async fetch(request: Request): Promise<Response> {\n if (this._status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this._initialize();\n }\n\n // Only handle WebSocket upgrade requests\n if (request.headers.get(\"Upgrade\") !== \"websocket\") {\n return new Response(\"Expected WebSocket Upgrade request\", {\n status: 400,\n });\n }\n\n // This request does not come from the user. The worker generates this\n // request to generate a websocket connection to the agent.\n const url = new URL(request.url);\n // This is not the path that the user requested, but the path that the worker\n // generated. We'll use this path to determine which transport to use.\n const path = url.pathname;\n const server = await this.server;\n\n switch (path) {\n case \"/sse\": {\n // For SSE connections, we can only have one open connection per session\n // If we get an upgrade while already connected, we should error\n const websockets = this.ctx.getWebSockets();\n if (websockets.length > 0) {\n return new Response(\"Websocket already connected\", { status: 400 });\n }\n\n // This session must always use the SSE transporo\n await this.ctx.storage.put(\"transportType\", \"sse\");\n this._transportType = \"sse\";\n\n if (!this._transport) {\n this._transport = new McpSSETransport(() => this.getWebSocket());\n await server.connect(this._transport);\n }\n\n // Defer to the Agent's fetch method to handle the WebSocket connection\n return this._agent.fetch(request);\n }\n case \"/streamable-http\": {\n if (!this._transport) {\n this._transport = new McpStreamableHttpTransport(\n (id) => this.getWebSocketForResponseID(id),\n (id) => this._requestIdToConnectionId.delete(id)\n );\n await server.connect(this._transport);\n }\n\n // This session must always use the streamable-http transport\n await this.ctx.storage.put(\"transportType\", \"streamable-http\");\n this._transportType = \"streamable-http\";\n\n return this._agent.fetch(request);\n }\n default:\n return new Response(\n \"Internal Server Error: Expected /sse or /streamable-http path\",\n {\n status: 500,\n }\n );\n }\n }\n\n getWebSocket() {\n const websockets = this.ctx.getWebSockets();\n if (websockets.length === 0) {\n return null;\n }\n return websockets[0];\n }\n\n getWebSocketForResponseID(id: string): WebSocket | null {\n const connectionId = this._requestIdToConnectionId.get(id);\n if (connectionId === undefined) {\n return null;\n }\n return this._agent.getConnection(connectionId) ?? null;\n }\n\n // All messages received here. This is currently never called\n async onMessage(connection: Connection, event: WSMessage) {\n // Since we address the DO via both the protocol and the session id,\n // this should never happen, but let's enforce it just in case\n if (this._transportType !== \"streamable-http\") {\n const err = new Error(\n \"Internal Server Error: Expected streamable-http protocol\"\n );\n this._transport?.onerror?.(err);\n return;\n }\n\n let message: JSONRPCMessage;\n try {\n // Ensure event is a string\n const data =\n typeof event === \"string\" ? event : new TextDecoder().decode(event);\n message = JSONRPCMessageSchema.parse(JSON.parse(data));\n } catch (error) {\n this._transport?.onerror?.(error as Error);\n return;\n }\n\n // We need to map every incoming message to the connection that it came in on\n // so that we can send relevant responses and notifications back on the same connection\n if (isJSONRPCRequest(message)) {\n this._requestIdToConnectionId.set(message.id.toString(), connection.id);\n }\n\n this._transport?.onmessage?.(message);\n }\n\n // All messages received over SSE after the initial connection has been established\n // will be passed here\n async onSSEMcpMessage(\n sessionId: string,\n request: Request\n ): Promise<Error | null> {\n if (this._status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this._initialize();\n }\n\n // Since we address the DO via both the protocol and the session id,\n // this should never happen, but let's enforce it just in case\n if (this._transportType !== \"sse\") {\n return new Error(\"Internal Server Error: Expected SSE protocol\");\n }\n\n try {\n const message = await request.json();\n let parsedMessage: JSONRPCMessage;\n try {\n parsedMessage = JSONRPCMessageSchema.parse(message);\n } catch (error) {\n this._transport?.onerror?.(error as Error);\n throw error;\n }\n\n this._transport?.onmessage?.(parsedMessage);\n return null;\n } catch (error) {\n console.error(\"Error forwarding message to SSE:\", error);\n this._transport?.onerror?.(error as Error);\n return error as Error;\n }\n }\n\n // Delegate all websocket events to the underlying agent\n async webSocketMessage(\n ws: WebSocket,\n event: ArrayBuffer | string\n ): Promise<void> {\n if (this._status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this._initialize();\n }\n return await this._agent.webSocketMessage(ws, event);\n }\n\n // WebSocket event handlers for hibernation support\n async webSocketError(ws: WebSocket, error: unknown): Promise<void> {\n if (this._status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this._initialize();\n }\n return await this._agent.webSocketError(ws, error);\n }\n\n async webSocketClose(\n ws: WebSocket,\n code: number,\n reason: string,\n wasClean: boolean\n ): Promise<void> {\n if (this._status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this._initialize();\n }\n return await this._agent.webSocketClose(ws, code, reason, wasClean);\n }\n\n static mount(\n path: string,\n {\n binding = \"MCP_OBJECT\",\n corsOptions,\n }: {\n binding?: string;\n corsOptions?: CORSOptions;\n } = {}\n ) {\n return McpAgent.serveSSE(path, { binding, corsOptions });\n }\n\n static serveSSE(\n path: string,\n {\n binding = \"MCP_OBJECT\",\n corsOptions,\n }: {\n binding?: string;\n corsOptions?: CORSOptions;\n } = {}\n ) {\n let pathname = path;\n if (path === \"/\") {\n pathname = \"/*\";\n }\n const basePattern = new URLPattern({ pathname });\n const messagePattern = new URLPattern({ pathname: `${pathname}/message` });\n\n return {\n async fetch<Env>(\n this: void,\n request: Request,\n env: Env,\n ctx: ExecutionContext\n ): Promise<Response> {\n // Handle CORS preflight\n const corsResponse = handleCORS(request, corsOptions);\n if (corsResponse) return corsResponse;\n\n const url = new URL(request.url);\n const bindingValue = env[binding as keyof typeof env] as unknown;\n\n // Ensure we have a binding of some sort\n if (bindingValue == null || typeof bindingValue !== \"object\") {\n console.error(\n `Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`\n );\n return new Response(\"Invalid binding\", { status: 500 });\n }\n\n // Ensure that the binding is to a DurableObject\n if (!isDurableObjectNamespace(bindingValue)) {\n return new Response(\"Invalid binding\", { status: 500 });\n }\n\n const namespace =\n bindingValue satisfies DurableObjectNamespace<McpAgent>;\n\n // Handle initial SSE connection\n if (request.method === \"GET\" && basePattern.test(url)) {\n // Use a session ID if one is passed in, or create a unique\n // session ID for this connection\n const sessionId =\n url.searchParams.get(\"sessionId\") ||\n namespace.newUniqueId().toString();\n\n // Create a Transform Stream for SSE\n const { readable, writable } = new TransformStream();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n // Send the endpoint event\n const endpointUrl = new URL(request.url);\n endpointUrl.pathname = encodeURI(`${pathname}/message`);\n endpointUrl.searchParams.set(\"sessionId\", sessionId);\n const relativeUrlWithSession =\n endpointUrl.pathname + endpointUrl.search + endpointUrl.hash;\n const endpointMessage = `event: endpoint\\ndata: ${relativeUrlWithSession}\\n\\n`;\n writer.write(encoder.encode(endpointMessage));\n\n // Get the Durable Object\n const id = namespace.idFromName(`sse:${sessionId}`);\n const doStub = namespace.get(id);\n\n // Initialize the object\n await doStub._init(ctx.props);\n\n // Connect to the Durable Object via WebSocket\n const upgradeUrl = new URL(request.url);\n // enforce that the path that the DO receives is always /sse\n upgradeUrl.pathname = \"/sse\";\n const response = await doStub.fetch(\n new Request(upgradeUrl, {\n headers: {\n Upgrade: \"websocket\",\n // Required by PartyServer\n \"x-partykit-room\": sessionId,\n },\n })\n );\n\n // Get the WebSocket\n const ws = response.webSocket;\n if (!ws) {\n console.error(\"Failed to establish WebSocket connection\");\n await writer.close();\n return new Response(\"Failed to establish WebSocket connection\", {\n status: 500,\n });\n }\n\n // Accept the WebSocket\n ws.accept();\n\n // Handle messages from the Durable Object\n ws.addEventListener(\"message\", (event) => {\n async function onMessage(event: MessageEvent) {\n try {\n const message = JSON.parse(event.data);\n\n // validate that the message is a valid JSONRPC message\n const result = JSONRPCMessageSchema.safeParse(message);\n if (!result.success) {\n // The message was not a valid JSONRPC message, so we will drop it\n // PartyKit will broadcast state change messages to all connected clients\n // and we need to filter those out so they are not passed to MCP clients\n return;\n }\n\n // Send the message as an SSE event\n const messageText = `event: message\\ndata: ${JSON.stringify(result.data)}\\n\\n`;\n await writer.write(encoder.encode(messageText));\n } catch (error) {\n console.error(\"Error forwarding message to SSE:\", error);\n }\n }\n onMessage(event).catch(console.error);\n });\n\n // Handle WebSocket errors\n ws.addEventListener(\"error\", (error) => {\n async function onError(error: Event) {\n try {\n await writer.close();\n } catch (e) {\n // Ignore errors when closing\n }\n }\n onError(error).catch(console.error);\n });\n\n // Handle WebSocket closure\n ws.addEventListener(\"close\", () => {\n async function onClose() {\n try {\n await writer.close();\n } catch (error) {\n console.error(\"Error closing SSE connection:\", error);\n }\n }\n onClose().catch(console.error);\n });\n\n // Return the SSE response\n return new Response(readable, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n ...corsHeaders(request, corsOptions),\n },\n });\n }\n\n // Handle incoming MCP messages. These will be passed to McpAgent\n // but the response will be sent back via the open SSE connection\n // so we only need to return a 202 Accepted response for success\n if (request.method === \"POST\" && messagePattern.test(url)) {\n const sessionId = url.searchParams.get(\"sessionId\");\n if (!sessionId) {\n return new Response(\n `Missing sessionId. Expected POST to ${pathname} to initiate new one`,\n { status: 400 }\n );\n }\n\n const contentType = request.headers.get(\"content-type\") || \"\";\n if (!contentType.includes(\"application/json\")) {\n return new Response(`Unsupported content-type: ${contentType}`, {\n status: 400,\n });\n }\n\n // check if the request body is too large\n const contentLength = Number.parseInt(\n request.headers.get(\"content-length\") || \"0\",\n 10\n );\n if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {\n return new Response(\n `Request body too large: ${contentLength} bytes`,\n {\n status: 400,\n }\n );\n }\n\n // Get the Durable Object\n const id = namespace.idFromName(`sse:${sessionId}`);\n const doStub = namespace.get(id);\n\n // Forward the request to the Durable Object\n const error = await doStub.onSSEMcpMessage(sessionId, request);\n\n if (error) {\n return new Response(error.message, {\n status: 400,\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n ...corsHeaders(request, corsOptions),\n },\n });\n }\n\n return new Response(\"Accepted\", {\n status: 202,\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n ...corsHeaders(request, corsOptions),\n },\n });\n }\n\n return new Response(\"Not Found\", { status: 404 });\n },\n };\n }\n\n static serve(\n path: string,\n {\n binding = \"MCP_OBJECT\",\n corsOptions,\n }: { binding?: string; corsOptions?: CORSOptions } = {}\n ) {\n let pathname = path;\n if (path === \"/\") {\n pathname = \"/*\";\n }\n const basePattern = new URLPattern({ pathname });\n\n return {\n async fetch<Env>(\n this: void,\n request: Request,\n env: Env,\n ctx: ExecutionContext\n ): Promise<Response> {\n // Handle CORS preflight\n const corsResponse = handleCORS(request, corsOptions);\n if (corsResponse) {\n return corsResponse;\n }\n\n const url = new URL(request.url);\n const bindingValue = env[binding as keyof typeof env] as unknown;\n\n // Ensure we have a binding of some sort\n if (bindingValue == null || typeof bindingValue !== \"object\") {\n console.error(\n `Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`\n );\n return new Response(\"Invalid binding\", { status: 500 });\n }\n\n // Ensure that the binding is to a DurableObject\n if (!isDurableObjectNamespace(bindingValue)) {\n return new Response(\"Invalid binding\", { status: 500 });\n }\n\n const namespace =\n bindingValue satisfies DurableObjectNamespace<McpAgent>;\n\n if (request.method === \"POST\" && basePattern.test(url)) {\n // validate the Accept header\n const acceptHeader = request.headers.get(\"accept\");\n // The client MUST include an Accept header, listing both application/json and text/event-stream as supported content types.\n if (\n !acceptHeader?.includes(\"application/json\") ||\n !acceptHeader.includes(\"text/event-stream\")\n ) {\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message:\n \"Not Acceptable: Client must accept both application/json and text/event-stream\",\n },\n id: null,\n });\n return new Response(body, { status: 406 });\n }\n\n const ct = request.headers.get(\"content-type\");\n if (!ct || !ct.includes(\"application/json\")) {\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message:\n \"Unsupported Media Type: Content-Type must be application/json\",\n },\n id: null,\n });\n return new Response(body, { status: 415 });\n }\n\n // Check content length against maximum allowed size\n const contentLength = Number.parseInt(\n request.headers.get(\"content-length\") ?? \"0\",\n 10\n );\n if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE_BYTES} bytes`,\n },\n id: null,\n });\n return new Response(body, { status: 413 });\n }\n\n let sessionId = request.headers.get(\"mcp-session-id\");\n let rawMessage: unknown;\n\n try {\n rawMessage = await request.json();\n } catch (error) {\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32700,\n message: \"Parse error: Invalid JSON\",\n },\n id: null,\n });\n return new Response(body, { status: 400 });\n }\n\n // Make sure the message is an array to simplify logic\n let arrayMessage: unknown[];\n if (Array.isArray(rawMessage)) {\n arrayMessage = rawMessage;\n } else {\n arrayMessage = [rawMessage];\n }\n\n let messages: JSONRPCMessage[] = [];\n\n // Try to parse each message as JSON RPC. Fail if any message is invalid\n for (const msg of arrayMessage) {\n if (!JSONRPCMessageSchema.safeParse(msg).success) {\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32700,\n message: \"Parse error: Invalid JSON-RPC message\",\n },\n id: null,\n });\n return new Response(body, { status: 400 });\n }\n }\n\n messages = arrayMessage.map((msg) => JSONRPCMessageSchema.parse(msg));\n\n // Before we pass the messages to the agent, there's another error condition we need to enforce\n // Check if this is an initialization request\n // https://spec.modelcontextprotocol.io/specification/2025-03-26/basic/lifecycle/\n const isInitializationRequest = messages.some(\n (msg) => InitializeRequestSchema.safeParse(msg).success\n );\n\n if (isInitializationRequest && sessionId) {\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32600,\n message:\n \"Invalid Request: Initialization requests must not include a sessionId\",\n },\n id: null,\n });\n return new Response(body, { status: 400 });\n }\n\n // The initialization request must be the only request in the batch\n if (isInitializationRequest && messages.length > 1) {\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32600,\n message:\n \"Invalid Request: Only one initialization request is allowed\",\n },\n id: null,\n });\n return new Response(body, { status: 400 });\n }\n\n // If an Mcp-Session-Id is returned by the server during initialization,\n // clients using the Streamable HTTP transport MUST include it\n // in the Mcp-Session-Id header on all of their subsequent HTTP requests.\n if (!isInitializationRequest && !sessionId) {\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Bad Request: Mcp-Session-Id header is required\",\n },\n id: null,\n });\n return new Response(body, { status: 400 });\n }\n\n // If we don't have a sessionId, we are serving an initialization request\n // and need to generate a new sessionId\n sessionId = sessionId ?? namespace.newUniqueId().toString();\n\n // fetch the agent DO\n const id = namespace.idFromName(`streamable-http:${sessionId}`);\n const doStub = namespace.get(id);\n const isInitialized = await doStub.isInitialized();\n\n if (isInitializationRequest) {\n await doStub._init(ctx.props);\n await doStub.setInitialized();\n } else if (!isInitialized) {\n // if we have gotten here, then a session id that was never initialized\n // was provided\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32001,\n message: \"Session not found\",\n },\n id: null,\n });\n return new Response(body, { status: 404 });\n }\n\n // We've evaluated all the error conditions! Now it's time to establish\n // all the streams\n\n // Create a Transform Stream for SSE\n const { readable, writable } = new TransformStream();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n // Connect to the Durable Object via WebSocket\n const upgradeUrl = new URL(request.url);\n upgradeUrl.pathname = \"/streamable-http\";\n const response = await doStub.fetch(\n new Request(upgradeUrl, {\n headers: {\n Upgrade: \"websocket\",\n // Required by PartyServer\n \"x-partykit-room\": sessionId,\n },\n })\n );\n\n // Get the WebSocket\n const ws = response.webSocket;\n if (!ws) {\n console.error(\"Failed to establish WebSocket connection\");\n\n await writer.close();\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32001,\n message: \"Failed to establish WebSocket connection\",\n },\n id: null,\n });\n return new Response(body, { status: 500 });\n }\n\n // Keep track of the request ids that we have sent to the server\n // so that we can close the connection once we have received\n // all the responses\n const requestIds: Set<string | number> = new Set();\n\n // Accept the WebSocket\n ws.accept();\n\n // Handle messages from the Durable Object\n ws.addEventListener(\"message\", (event) => {\n async function onMessage(event: MessageEvent) {\n try {\n const data =\n typeof event.data === \"string\"\n ? event.data\n : new TextDecoder().decode(event.data);\n const message = JSON.parse(data);\n\n // validate that the message is a valid JSONRPC message\n const result = JSONRPCMessageSchema.safeParse(message);\n if (!result.success) {\n // The message was not a valid JSONRPC message, so we will drop it\n // PartyKit will broadcast state change messages to all connected clients\n // and we need to filter those out so they are not passed to MCP clients\n return;\n }\n\n // If the message is a response or an error, remove the id from the set of\n // request ids\n if (\n isJSONRPCResponse(result.data) ||\n isJSONRPCError(result.data)\n ) {\n requestIds.delete(result.data.id);\n }\n\n // Send the message as an SSE event\n const messageText = `event: message\\ndata: ${JSON.stringify(result.data)}\\n\\n`;\n await writer.write(encoder.encode(messageText));\n\n // If we have received all the responses, close the connection\n if (requestIds.size === 0) {\n ws!.close();\n }\n } catch (error) {\n console.error(\"Error forwarding message to SSE:\", error);\n }\n }\n onMessage(event).catch(console.error);\n });\n\n // Handle WebSocket errors\n ws.addEventListener(\"error\", (error) => {\n async function onError(error: Event) {\n try {\n await writer.close();\n } catch (e) {\n // Ignore errors when closing\n }\n }\n onError(error).catch(console.error);\n });\n\n // Handle WebSocket closure\n ws.addEventListener(\"close\", () => {\n async function onClose() {\n try {\n await writer.close();\n } catch (error) {\n console.error(\"Error closing SSE connection:\", error);\n }\n }\n onClose().catch(console.error);\n });\n\n // If there are no requests, we send the messages to the agent and acknowledge the request with a 202\n // since we don't expect any responses back through this connection\n const hasOnlyNotificationsOrResponses = messages.every(\n (msg) => isJSONRPCNotification(msg) || isJSONRPCResponse(msg)\n );\n if (hasOnlyNotificationsOrResponses) {\n for (const message of messages) {\n ws.send(JSON.stringify(message));\n }\n\n // closing the websocket will also close the SSE connection\n ws.close();\n\n return new Response(null, {\n status: 202,\n headers: corsHeaders(request, corsOptions),\n });\n }\n\n for (const message of messages) {\n if (isJSONRPCRequest(message)) {\n // add each request id that we send off to a set\n // so that we can keep track of which requests we\n // still need a response for\n requestIds.add(message.id);\n }\n ws.send(JSON.stringify(message));\n }\n\n // Return the SSE response. We handle closing the stream in the ws \"message\"\n // handler\n return new Response(readable, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"mcp-session-id\": sessionId,\n ...corsHeaders(request, corsOptions),\n },\n status: 200,\n });\n }\n\n // We don't yet support GET or DELETE requests\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Method not allowed\",\n },\n id: null,\n });\n return new Response(body, { status: 405 });\n },\n };\n }\n}\n"],"mappings":"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","names":["event","error","body"]}
1
+ {"version":3,"sources":["../../src/mcp/index.ts"],"sourcesContent":["import { DurableObject } from \"cloudflare:workers\";\nimport type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport type { JSONRPCMessage } from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n InitializeRequestSchema,\n isJSONRPCError,\n isJSONRPCNotification,\n isJSONRPCRequest,\n isJSONRPCResponse,\n JSONRPCMessageSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { Connection, WSMessage } from \"../\";\nimport { Agent } from \"../\";\n\nconst MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024; // 4MB\n\n// CORS helper functions\nfunction corsHeaders(_request: Request, corsOptions: CORSOptions = {}) {\n const origin = \"*\";\n return {\n \"Access-Control-Allow-Headers\":\n corsOptions.headers ||\n \"Content-Type, mcp-session-id, mcp-protocol-version\",\n \"Access-Control-Allow-Methods\": corsOptions.methods || \"GET, POST, OPTIONS\",\n \"Access-Control-Allow-Origin\": corsOptions.origin || origin,\n \"Access-Control-Expose-Headers\":\n corsOptions.exposeHeaders || \"mcp-session-id\",\n \"Access-Control-Max-Age\": (corsOptions.maxAge || 86400).toString(),\n };\n}\n\nfunction isDurableObjectNamespace(\n namespace: unknown\n): namespace is DurableObjectNamespace<McpAgent> {\n return (\n typeof namespace === \"object\" &&\n namespace !== null &&\n \"newUniqueId\" in namespace &&\n typeof namespace.newUniqueId === \"function\" &&\n \"idFromName\" in namespace &&\n typeof namespace.idFromName === \"function\"\n );\n}\n\nfunction handleCORS(\n request: Request,\n corsOptions?: CORSOptions\n): Response | null {\n if (request.method === \"OPTIONS\") {\n return new Response(null, { headers: corsHeaders(request, corsOptions) });\n }\n\n return null;\n}\n\ninterface CORSOptions {\n origin?: string;\n methods?: string;\n headers?: string;\n maxAge?: number;\n exposeHeaders?: string;\n}\n\nclass McpSSETransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n sessionId?: string;\n\n private _getWebSocket: () => WebSocket | null;\n private _started = false;\n constructor(getWebSocket: () => WebSocket | null) {\n this._getWebSocket = getWebSocket;\n }\n\n async start() {\n // The transport does not manage the WebSocket connection since it's terminated\n // by the Durable Object in order to allow hibernation. There's nothing to initialize.\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n async send(message: JSONRPCMessage) {\n if (!this._started) {\n throw new Error(\"Transport not started\");\n }\n const websocket = this._getWebSocket();\n if (!websocket) {\n throw new Error(\"WebSocket not connected\");\n }\n try {\n websocket.send(JSON.stringify(message));\n } catch (error) {\n this.onerror?.(error as Error);\n throw error;\n }\n }\n\n async close() {\n // Similar to start, the only thing to do is to pass the event on to the server\n this.onclose?.();\n }\n}\n\ntype TransportType = \"sse\" | \"streamable-http\" | \"unset\";\n\nclass McpStreamableHttpTransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n sessionId?: string;\n\n // TODO: If there is an open connection to send server-initiated messages\n // back, we should use that connection\n private _getWebSocketForGetRequest: () => WebSocket | null;\n\n // Get the appropriate websocket connection for a given message id\n private _getWebSocketForMessageID: (id: string) => WebSocket | null;\n\n // Notify the server that a response has been sent for a given message id\n // so that it may clean up it's mapping of message ids to connections\n // once they are no longer needed\n private _notifyResponseIdSent: (id: string) => void;\n\n private _started = false;\n constructor(\n getWebSocketForMessageID: (id: string) => WebSocket | null,\n notifyResponseIdSent: (id: string | number) => void\n ) {\n this._getWebSocketForMessageID = getWebSocketForMessageID;\n this._notifyResponseIdSent = notifyResponseIdSent;\n // TODO\n this._getWebSocketForGetRequest = () => null;\n }\n\n async start() {\n // The transport does not manage the WebSocket connection since it's terminated\n // by the Durable Object in order to allow hibernation. There's nothing to initialize.\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n async send(message: JSONRPCMessage) {\n if (!this._started) {\n throw new Error(\"Transport not started\");\n }\n\n let websocket: WebSocket | null = null;\n\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n websocket = this._getWebSocketForMessageID(message.id.toString());\n if (!websocket) {\n throw new Error(\n `Could not find WebSocket for message id: ${message.id}`\n );\n }\n } else if (isJSONRPCRequest(message)) {\n // requests originating from the server must be sent over the\n // the connection created by a GET request\n websocket = this._getWebSocketForGetRequest();\n } else if (isJSONRPCNotification(message)) {\n // notifications do not have an id\n // but do have a relatedRequestId field\n // so that they can be sent to the correct connection\n websocket = null;\n }\n\n try {\n websocket?.send(JSON.stringify(message));\n if (isJSONRPCResponse(message)) {\n this._notifyResponseIdSent(message.id.toString());\n }\n } catch (error) {\n this.onerror?.(error as Error);\n throw error;\n }\n }\n\n async close() {\n // Similar to start, the only thing to do is to pass the event on to the server\n this.onclose?.();\n }\n}\n\ntype MaybePromise<T> = T | Promise<T>;\n\nexport abstract class McpAgent<\n Env = unknown,\n State = unknown,\n Props extends Record<string, unknown> = Record<string, unknown>,\n> extends DurableObject<Env> {\n private _status: \"zero\" | \"starting\" | \"started\" = \"zero\";\n private _transport?: Transport;\n private _transportType: TransportType = \"unset\";\n private _requestIdToConnectionId: Map<string | number, string> = new Map();\n\n /**\n * Since McpAgent's _aren't_ yet real \"Agents\", let's only expose a couple of the methods\n * to the outer class: initialState/state/setState/onStateUpdate/sql\n */\n private _agent: Agent<Env, State>;\n\n get mcp() {\n return this._agent.mcp;\n }\n\n protected constructor(ctx: DurableObjectState, env: Env) {\n super(ctx, env);\n const self = this;\n\n this._agent = new (class extends Agent<Env, State> {\n static options = {\n hibernate: true,\n };\n\n onStateUpdate(state: State | undefined, source: Connection | \"server\") {\n return self.onStateUpdate(state, source);\n }\n\n async onMessage(\n connection: Connection,\n message: WSMessage\n ): Promise<void> {\n return self.onMessage(connection, message);\n }\n })(ctx, env);\n }\n\n /**\n * Agents API allowlist\n */\n initialState!: State;\n get state() {\n return this._agent.state;\n }\n sql<T = Record<string, string | number | boolean | null>>(\n strings: TemplateStringsArray,\n ...values: (string | number | boolean | null)[]\n ) {\n return this._agent.sql<T>(strings, ...values);\n }\n\n setState(state: State) {\n return this._agent.setState(state);\n }\n // biome-ignore lint/correctness/noUnusedFunctionParameters: overriden later\n onStateUpdate(state: State | undefined, source: Connection | \"server\") {\n // override this to handle state updates\n }\n async onStart() {\n const self = this;\n\n this._agent = new (class extends Agent<Env, State> {\n initialState: State = self.initialState;\n static options = {\n hibernate: true,\n };\n\n onStateUpdate(state: State | undefined, source: Connection | \"server\") {\n return self.onStateUpdate(state, source);\n }\n\n async onMessage(connection: Connection, event: WSMessage) {\n return self.onMessage(connection, event);\n }\n })(this.ctx, this.env);\n\n this.props = (await this.ctx.storage.get(\"props\")) as Props;\n this._transportType = (await this.ctx.storage.get(\n \"transportType\"\n )) as TransportType;\n await this._init(this.props);\n\n const server = await this.server;\n\n // Connect to the MCP server\n if (this._transportType === \"sse\") {\n this._transport = new McpSSETransport(() => this.getWebSocket());\n await server.connect(this._transport);\n } else if (this._transportType === \"streamable-http\") {\n this._transport = new McpStreamableHttpTransport(\n (id) => this.getWebSocketForResponseID(id),\n (id) => this._requestIdToConnectionId.delete(id)\n );\n await server.connect(this._transport);\n }\n }\n\n /**\n * McpAgent API\n */\n abstract server: MaybePromise<McpServer | Server>;\n props!: Props;\n initRun = false;\n\n abstract init(): Promise<void>;\n\n async _init(props: Props) {\n await this.ctx.storage.put(\"props\", props ?? {});\n if (!this.ctx.storage.get(\"transportType\")) {\n await this.ctx.storage.put(\"transportType\", \"unset\");\n }\n this.props = props;\n if (!this.initRun) {\n this.initRun = true;\n await this.init();\n }\n }\n\n async setInitialized() {\n await this.ctx.storage.put(\"initialized\", true);\n }\n\n async isInitialized() {\n return (await this.ctx.storage.get(\"initialized\")) === true;\n }\n\n private async _initialize(): Promise<void> {\n await this.ctx.blockConcurrencyWhile(async () => {\n this._status = \"starting\";\n await this.onStart();\n this._status = \"started\";\n });\n }\n\n // Allow the worker to fetch a websocket connection to the agent\n async fetch(request: Request): Promise<Response> {\n if (this._status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this._initialize();\n }\n\n // Only handle WebSocket upgrade requests\n if (request.headers.get(\"Upgrade\") !== \"websocket\") {\n return new Response(\"Expected WebSocket Upgrade request\", {\n status: 400,\n });\n }\n\n // This request does not come from the user. The worker generates this\n // request to generate a websocket connection to the agent.\n const url = new URL(request.url);\n // This is not the path that the user requested, but the path that the worker\n // generated. We'll use this path to determine which transport to use.\n const path = url.pathname;\n const server = await this.server;\n\n switch (path) {\n case \"/sse\": {\n // For SSE connections, we can only have one open connection per session\n // If we get an upgrade while already connected, we should error\n const websockets = this.ctx.getWebSockets();\n if (websockets.length > 0) {\n return new Response(\"Websocket already connected\", { status: 400 });\n }\n\n // This session must always use the SSE transporo\n await this.ctx.storage.put(\"transportType\", \"sse\");\n this._transportType = \"sse\";\n\n if (!this._transport) {\n this._transport = new McpSSETransport(() => this.getWebSocket());\n await server.connect(this._transport);\n }\n\n // Defer to the Agent's fetch method to handle the WebSocket connection\n return this._agent.fetch(request);\n }\n case \"/streamable-http\": {\n if (!this._transport) {\n this._transport = new McpStreamableHttpTransport(\n (id) => this.getWebSocketForResponseID(id),\n (id) => this._requestIdToConnectionId.delete(id)\n );\n await server.connect(this._transport);\n }\n\n // This session must always use the streamable-http transport\n await this.ctx.storage.put(\"transportType\", \"streamable-http\");\n this._transportType = \"streamable-http\";\n\n return this._agent.fetch(request);\n }\n default:\n return new Response(\n \"Internal Server Error: Expected /sse or /streamable-http path\",\n {\n status: 500,\n }\n );\n }\n }\n\n getWebSocket() {\n const websockets = this.ctx.getWebSockets();\n if (websockets.length === 0) {\n return null;\n }\n return websockets[0];\n }\n\n getWebSocketForResponseID(id: string): WebSocket | null {\n const connectionId = this._requestIdToConnectionId.get(id);\n if (connectionId === undefined) {\n return null;\n }\n return this._agent.getConnection(connectionId) ?? null;\n }\n\n // All messages received here. This is currently never called\n async onMessage(connection: Connection, event: WSMessage) {\n // Since we address the DO via both the protocol and the session id,\n // this should never happen, but let's enforce it just in case\n if (this._transportType !== \"streamable-http\") {\n const err = new Error(\n \"Internal Server Error: Expected streamable-http protocol\"\n );\n this._transport?.onerror?.(err);\n return;\n }\n\n let message: JSONRPCMessage;\n try {\n // Ensure event is a string\n const data =\n typeof event === \"string\" ? event : new TextDecoder().decode(event);\n message = JSONRPCMessageSchema.parse(JSON.parse(data));\n } catch (error) {\n this._transport?.onerror?.(error as Error);\n return;\n }\n\n // We need to map every incoming message to the connection that it came in on\n // so that we can send relevant responses and notifications back on the same connection\n if (isJSONRPCRequest(message)) {\n this._requestIdToConnectionId.set(message.id.toString(), connection.id);\n }\n\n this._transport?.onmessage?.(message);\n }\n\n // All messages received over SSE after the initial connection has been established\n // will be passed here\n async onSSEMcpMessage(\n _sessionId: string,\n request: Request\n ): Promise<Error | null> {\n if (this._status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this._initialize();\n }\n\n // Since we address the DO via both the protocol and the session id,\n // this should never happen, but let's enforce it just in case\n if (this._transportType !== \"sse\") {\n return new Error(\"Internal Server Error: Expected SSE protocol\");\n }\n\n try {\n const message = await request.json();\n let parsedMessage: JSONRPCMessage;\n try {\n parsedMessage = JSONRPCMessageSchema.parse(message);\n } catch (error) {\n this._transport?.onerror?.(error as Error);\n throw error;\n }\n\n this._transport?.onmessage?.(parsedMessage);\n return null;\n } catch (error) {\n console.error(\"Error forwarding message to SSE:\", error);\n this._transport?.onerror?.(error as Error);\n return error as Error;\n }\n }\n\n // Delegate all websocket events to the underlying agent\n async webSocketMessage(\n ws: WebSocket,\n event: ArrayBuffer | string\n ): Promise<void> {\n if (this._status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this._initialize();\n }\n return await this._agent.webSocketMessage(ws, event);\n }\n\n // WebSocket event handlers for hibernation support\n async webSocketError(ws: WebSocket, error: unknown): Promise<void> {\n if (this._status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this._initialize();\n }\n return await this._agent.webSocketError(ws, error);\n }\n\n async webSocketClose(\n ws: WebSocket,\n code: number,\n reason: string,\n wasClean: boolean\n ): Promise<void> {\n if (this._status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this._initialize();\n }\n return await this._agent.webSocketClose(ws, code, reason, wasClean);\n }\n\n static mount(\n path: string,\n {\n binding = \"MCP_OBJECT\",\n corsOptions,\n }: {\n binding?: string;\n corsOptions?: CORSOptions;\n } = {}\n ) {\n return McpAgent.serveSSE(path, { binding, corsOptions });\n }\n\n static serveSSE(\n path: string,\n {\n binding = \"MCP_OBJECT\",\n corsOptions,\n }: {\n binding?: string;\n corsOptions?: CORSOptions;\n } = {}\n ) {\n let pathname = path;\n if (path === \"/\") {\n pathname = \"/*\";\n }\n const basePattern = new URLPattern({ pathname });\n const messagePattern = new URLPattern({ pathname: `${pathname}/message` });\n\n return {\n async fetch<Env>(\n this: void,\n request: Request,\n env: Env,\n ctx: ExecutionContext\n ): Promise<Response> {\n // Handle CORS preflight\n const corsResponse = handleCORS(request, corsOptions);\n if (corsResponse) return corsResponse;\n\n const url = new URL(request.url);\n const bindingValue = env[binding as keyof typeof env] as unknown;\n\n // Ensure we have a binding of some sort\n if (bindingValue == null || typeof bindingValue !== \"object\") {\n console.error(\n `Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`\n );\n return new Response(\"Invalid binding\", { status: 500 });\n }\n\n // Ensure that the binding is to a DurableObject\n if (!isDurableObjectNamespace(bindingValue)) {\n return new Response(\"Invalid binding\", { status: 500 });\n }\n\n const namespace =\n bindingValue satisfies DurableObjectNamespace<McpAgent>;\n\n // Handle initial SSE connection\n if (request.method === \"GET\" && basePattern.test(url)) {\n // Use a session ID if one is passed in, or create a unique\n // session ID for this connection\n const sessionId =\n url.searchParams.get(\"sessionId\") ||\n namespace.newUniqueId().toString();\n\n // Create a Transform Stream for SSE\n const { readable, writable } = new TransformStream();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n // Send the endpoint event\n const endpointUrl = new URL(request.url);\n endpointUrl.pathname = encodeURI(`${pathname}/message`);\n endpointUrl.searchParams.set(\"sessionId\", sessionId);\n const relativeUrlWithSession =\n endpointUrl.pathname + endpointUrl.search + endpointUrl.hash;\n const endpointMessage = `event: endpoint\\ndata: ${relativeUrlWithSession}\\n\\n`;\n writer.write(encoder.encode(endpointMessage));\n\n // Get the Durable Object\n const id = namespace.idFromName(`sse:${sessionId}`);\n const doStub = namespace.get(id);\n\n // Initialize the object\n await doStub._init(ctx.props);\n\n // Connect to the Durable Object via WebSocket\n const upgradeUrl = new URL(request.url);\n // enforce that the path that the DO receives is always /sse\n upgradeUrl.pathname = \"/sse\";\n const response = await doStub.fetch(\n new Request(upgradeUrl, {\n headers: {\n Upgrade: \"websocket\",\n // Required by PartyServer\n \"x-partykit-room\": sessionId,\n },\n })\n );\n\n // Get the WebSocket\n const ws = response.webSocket;\n if (!ws) {\n console.error(\"Failed to establish WebSocket connection\");\n await writer.close();\n return new Response(\"Failed to establish WebSocket connection\", {\n status: 500,\n });\n }\n\n // Accept the WebSocket\n ws.accept();\n\n // Handle messages from the Durable Object\n ws.addEventListener(\"message\", (event) => {\n async function onMessage(event: MessageEvent) {\n try {\n const message = JSON.parse(event.data);\n\n // validate that the message is a valid JSONRPC message\n const result = JSONRPCMessageSchema.safeParse(message);\n if (!result.success) {\n // The message was not a valid JSONRPC message, so we will drop it\n // PartyKit will broadcast state change messages to all connected clients\n // and we need to filter those out so they are not passed to MCP clients\n return;\n }\n\n // Send the message as an SSE event\n const messageText = `event: message\\ndata: ${JSON.stringify(result.data)}\\n\\n`;\n await writer.write(encoder.encode(messageText));\n } catch (error) {\n console.error(\"Error forwarding message to SSE:\", error);\n }\n }\n onMessage(event).catch(console.error);\n });\n\n // Handle WebSocket errors\n ws.addEventListener(\"error\", (error) => {\n async function onError(_error: Event) {\n try {\n await writer.close();\n } catch (_e) {\n // Ignore errors when closing\n }\n }\n onError(error).catch(console.error);\n });\n\n // Handle WebSocket closure\n ws.addEventListener(\"close\", () => {\n async function onClose() {\n try {\n await writer.close();\n } catch (error) {\n console.error(\"Error closing SSE connection:\", error);\n }\n }\n onClose().catch(console.error);\n });\n\n // Return the SSE response\n return new Response(readable, {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n ...corsHeaders(request, corsOptions),\n },\n });\n }\n\n // Handle incoming MCP messages. These will be passed to McpAgent\n // but the response will be sent back via the open SSE connection\n // so we only need to return a 202 Accepted response for success\n if (request.method === \"POST\" && messagePattern.test(url)) {\n const sessionId = url.searchParams.get(\"sessionId\");\n if (!sessionId) {\n return new Response(\n `Missing sessionId. Expected POST to ${pathname} to initiate new one`,\n { status: 400 }\n );\n }\n\n const contentType = request.headers.get(\"content-type\") || \"\";\n if (!contentType.includes(\"application/json\")) {\n return new Response(`Unsupported content-type: ${contentType}`, {\n status: 400,\n });\n }\n\n // check if the request body is too large\n const contentLength = Number.parseInt(\n request.headers.get(\"content-length\") || \"0\",\n 10\n );\n if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {\n return new Response(\n `Request body too large: ${contentLength} bytes`,\n {\n status: 400,\n }\n );\n }\n\n // Get the Durable Object\n const id = namespace.idFromName(`sse:${sessionId}`);\n const doStub = namespace.get(id);\n\n // Forward the request to the Durable Object\n const error = await doStub.onSSEMcpMessage(sessionId, request);\n\n if (error) {\n return new Response(error.message, {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n ...corsHeaders(request, corsOptions),\n },\n status: 400,\n });\n }\n\n return new Response(\"Accepted\", {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n ...corsHeaders(request, corsOptions),\n },\n status: 202,\n });\n }\n\n return new Response(\"Not Found\", { status: 404 });\n },\n };\n }\n\n static serve(\n path: string,\n {\n binding = \"MCP_OBJECT\",\n corsOptions,\n }: { binding?: string; corsOptions?: CORSOptions } = {}\n ) {\n let pathname = path;\n if (path === \"/\") {\n pathname = \"/*\";\n }\n const basePattern = new URLPattern({ pathname });\n\n return {\n async fetch<Env>(\n this: void,\n request: Request,\n env: Env,\n ctx: ExecutionContext\n ): Promise<Response> {\n // Handle CORS preflight\n const corsResponse = handleCORS(request, corsOptions);\n if (corsResponse) {\n return corsResponse;\n }\n\n const url = new URL(request.url);\n const bindingValue = env[binding as keyof typeof env] as unknown;\n\n // Ensure we have a binding of some sort\n if (bindingValue == null || typeof bindingValue !== \"object\") {\n console.error(\n `Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`\n );\n return new Response(\"Invalid binding\", { status: 500 });\n }\n\n // Ensure that the binding is to a DurableObject\n if (!isDurableObjectNamespace(bindingValue)) {\n return new Response(\"Invalid binding\", { status: 500 });\n }\n\n const namespace =\n bindingValue satisfies DurableObjectNamespace<McpAgent>;\n\n if (request.method === \"POST\" && basePattern.test(url)) {\n // validate the Accept header\n const acceptHeader = request.headers.get(\"accept\");\n // The client MUST include an Accept header, listing both application/json and text/event-stream as supported content types.\n if (\n !acceptHeader?.includes(\"application/json\") ||\n !acceptHeader.includes(\"text/event-stream\")\n ) {\n const body = JSON.stringify({\n error: {\n code: -32000,\n message:\n \"Not Acceptable: Client must accept both application/json and text/event-stream\",\n },\n id: null,\n jsonrpc: \"2.0\",\n });\n return new Response(body, { status: 406 });\n }\n\n const ct = request.headers.get(\"content-type\");\n if (!ct || !ct.includes(\"application/json\")) {\n const body = JSON.stringify({\n error: {\n code: -32000,\n message:\n \"Unsupported Media Type: Content-Type must be application/json\",\n },\n id: null,\n jsonrpc: \"2.0\",\n });\n return new Response(body, { status: 415 });\n }\n\n // Check content length against maximum allowed size\n const contentLength = Number.parseInt(\n request.headers.get(\"content-length\") ?? \"0\",\n 10\n );\n if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {\n const body = JSON.stringify({\n error: {\n code: -32000,\n message: `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE_BYTES} bytes`,\n },\n id: null,\n jsonrpc: \"2.0\",\n });\n return new Response(body, { status: 413 });\n }\n\n let sessionId = request.headers.get(\"mcp-session-id\");\n let rawMessage: unknown;\n\n try {\n rawMessage = await request.json();\n } catch (_error) {\n const body = JSON.stringify({\n error: {\n code: -32700,\n message: \"Parse error: Invalid JSON\",\n },\n id: null,\n jsonrpc: \"2.0\",\n });\n return new Response(body, { status: 400 });\n }\n\n // Make sure the message is an array to simplify logic\n let arrayMessage: unknown[];\n if (Array.isArray(rawMessage)) {\n arrayMessage = rawMessage;\n } else {\n arrayMessage = [rawMessage];\n }\n\n let messages: JSONRPCMessage[] = [];\n\n // Try to parse each message as JSON RPC. Fail if any message is invalid\n for (const msg of arrayMessage) {\n if (!JSONRPCMessageSchema.safeParse(msg).success) {\n const body = JSON.stringify({\n error: {\n code: -32700,\n message: \"Parse error: Invalid JSON-RPC message\",\n },\n id: null,\n jsonrpc: \"2.0\",\n });\n return new Response(body, { status: 400 });\n }\n }\n\n messages = arrayMessage.map((msg) => JSONRPCMessageSchema.parse(msg));\n\n // Before we pass the messages to the agent, there's another error condition we need to enforce\n // Check if this is an initialization request\n // https://spec.modelcontextprotocol.io/specification/2025-03-26/basic/lifecycle/\n const isInitializationRequest = messages.some(\n (msg) => InitializeRequestSchema.safeParse(msg).success\n );\n\n if (isInitializationRequest && sessionId) {\n const body = JSON.stringify({\n error: {\n code: -32600,\n message:\n \"Invalid Request: Initialization requests must not include a sessionId\",\n },\n id: null,\n jsonrpc: \"2.0\",\n });\n return new Response(body, { status: 400 });\n }\n\n // The initialization request must be the only request in the batch\n if (isInitializationRequest && messages.length > 1) {\n const body = JSON.stringify({\n error: {\n code: -32600,\n message:\n \"Invalid Request: Only one initialization request is allowed\",\n },\n id: null,\n jsonrpc: \"2.0\",\n });\n return new Response(body, { status: 400 });\n }\n\n // If an Mcp-Session-Id is returned by the server during initialization,\n // clients using the Streamable HTTP transport MUST include it\n // in the Mcp-Session-Id header on all of their subsequent HTTP requests.\n if (!isInitializationRequest && !sessionId) {\n const body = JSON.stringify({\n error: {\n code: -32000,\n message: \"Bad Request: Mcp-Session-Id header is required\",\n },\n id: null,\n jsonrpc: \"2.0\",\n });\n return new Response(body, { status: 400 });\n }\n\n // If we don't have a sessionId, we are serving an initialization request\n // and need to generate a new sessionId\n sessionId = sessionId ?? namespace.newUniqueId().toString();\n\n // fetch the agent DO\n const id = namespace.idFromName(`streamable-http:${sessionId}`);\n const doStub = namespace.get(id);\n const isInitialized = await doStub.isInitialized();\n\n if (isInitializationRequest) {\n await doStub._init(ctx.props);\n await doStub.setInitialized();\n } else if (!isInitialized) {\n // if we have gotten here, then a session id that was never initialized\n // was provided\n const body = JSON.stringify({\n error: {\n code: -32001,\n message: \"Session not found\",\n },\n id: null,\n jsonrpc: \"2.0\",\n });\n return new Response(body, { status: 404 });\n }\n\n // We've evaluated all the error conditions! Now it's time to establish\n // all the streams\n\n // Create a Transform Stream for SSE\n const { readable, writable } = new TransformStream();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n // Connect to the Durable Object via WebSocket\n const upgradeUrl = new URL(request.url);\n upgradeUrl.pathname = \"/streamable-http\";\n const response = await doStub.fetch(\n new Request(upgradeUrl, {\n headers: {\n Upgrade: \"websocket\",\n // Required by PartyServer\n \"x-partykit-room\": sessionId,\n },\n })\n );\n\n // Get the WebSocket\n const ws = response.webSocket;\n if (!ws) {\n console.error(\"Failed to establish WebSocket connection\");\n\n await writer.close();\n const body = JSON.stringify({\n error: {\n code: -32001,\n message: \"Failed to establish WebSocket connection\",\n },\n id: null,\n jsonrpc: \"2.0\",\n });\n return new Response(body, { status: 500 });\n }\n\n // Keep track of the request ids that we have sent to the server\n // so that we can close the connection once we have received\n // all the responses\n const requestIds: Set<string | number> = new Set();\n\n // Accept the WebSocket\n ws.accept();\n\n // Handle messages from the Durable Object\n ws.addEventListener(\"message\", (event) => {\n async function onMessage(event: MessageEvent) {\n try {\n const data =\n typeof event.data === \"string\"\n ? event.data\n : new TextDecoder().decode(event.data);\n const message = JSON.parse(data);\n\n // validate that the message is a valid JSONRPC message\n const result = JSONRPCMessageSchema.safeParse(message);\n if (!result.success) {\n // The message was not a valid JSONRPC message, so we will drop it\n // PartyKit will broadcast state change messages to all connected clients\n // and we need to filter those out so they are not passed to MCP clients\n return;\n }\n\n // If the message is a response or an error, remove the id from the set of\n // request ids\n if (\n isJSONRPCResponse(result.data) ||\n isJSONRPCError(result.data)\n ) {\n requestIds.delete(result.data.id);\n }\n\n // Send the message as an SSE event\n const messageText = `event: message\\ndata: ${JSON.stringify(result.data)}\\n\\n`;\n await writer.write(encoder.encode(messageText));\n\n // If we have received all the responses, close the connection\n if (requestIds.size === 0) {\n ws!.close();\n }\n } catch (error) {\n console.error(\"Error forwarding message to SSE:\", error);\n }\n }\n onMessage(event).catch(console.error);\n });\n\n // Handle WebSocket errors\n ws.addEventListener(\"error\", (error) => {\n async function onError(_error: Event) {\n try {\n await writer.close();\n } catch (_e) {\n // Ignore errors when closing\n }\n }\n onError(error).catch(console.error);\n });\n\n // Handle WebSocket closure\n ws.addEventListener(\"close\", () => {\n async function onClose() {\n try {\n await writer.close();\n } catch (error) {\n console.error(\"Error closing SSE connection:\", error);\n }\n }\n onClose().catch(console.error);\n });\n\n // If there are no requests, we send the messages to the agent and acknowledge the request with a 202\n // since we don't expect any responses back through this connection\n const hasOnlyNotificationsOrResponses = messages.every(\n (msg) => isJSONRPCNotification(msg) || isJSONRPCResponse(msg)\n );\n if (hasOnlyNotificationsOrResponses) {\n for (const message of messages) {\n ws.send(JSON.stringify(message));\n }\n\n // closing the websocket will also close the SSE connection\n ws.close();\n\n return new Response(null, {\n headers: corsHeaders(request, corsOptions),\n status: 202,\n });\n }\n\n for (const message of messages) {\n if (isJSONRPCRequest(message)) {\n // add each request id that we send off to a set\n // so that we can keep track of which requests we\n // still need a response for\n requestIds.add(message.id);\n }\n ws.send(JSON.stringify(message));\n }\n\n // Return the SSE response. We handle closing the stream in the ws \"message\"\n // handler\n return new Response(readable, {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n \"mcp-session-id\": sessionId,\n ...corsHeaders(request, corsOptions),\n },\n status: 200,\n });\n }\n\n // We don't yet support GET or DELETE requests\n const body = JSON.stringify({\n error: {\n code: -32000,\n message: \"Method not allowed\",\n },\n id: null,\n jsonrpc: \"2.0\",\n });\n return new Response(body, { status: 405 });\n },\n };\n }\n}\n"],"mappings":"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","names":["event","body"]}