agents 0.1.3 → 0.1.5

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 (49) hide show
  1. package/README.md +103 -5
  2. package/dist/_esm-LV5FJ3HK.js +3922 -0
  3. package/dist/_esm-LV5FJ3HK.js.map +1 -0
  4. package/dist/ai-chat-agent.js +12 -3
  5. package/dist/ai-chat-agent.js.map +1 -1
  6. package/dist/ai-chat-v5-migration.js +1 -0
  7. package/dist/ai-react.d.ts +6 -0
  8. package/dist/ai-react.js +43 -9
  9. package/dist/ai-react.js.map +1 -1
  10. package/dist/ai-types.d.ts +1 -0
  11. package/dist/ai-types.js +2 -1
  12. package/dist/ccip-CMBYN64O.js +15 -0
  13. package/dist/ccip-CMBYN64O.js.map +1 -0
  14. package/dist/chunk-5Y6BEZDY.js +276 -0
  15. package/dist/chunk-5Y6BEZDY.js.map +1 -0
  16. package/dist/{chunk-AVYJQSLW.js → chunk-BER7KXUJ.js} +2 -1
  17. package/dist/chunk-BER7KXUJ.js.map +1 -0
  18. package/dist/{chunk-YDUDMOL6.js → chunk-HS7VEROK.js} +7 -3
  19. package/dist/chunk-HS7VEROK.js.map +1 -0
  20. package/dist/chunk-JJBFIGUC.js +5202 -0
  21. package/dist/chunk-JJBFIGUC.js.map +1 -0
  22. package/dist/chunk-PR4QN5HX.js +43 -0
  23. package/dist/chunk-PR4QN5HX.js.map +1 -0
  24. package/dist/{chunk-MH46VMM4.js → chunk-SKACXF37.js} +2 -2
  25. package/dist/chunk-SKACXF37.js.map +1 -0
  26. package/dist/chunk-TYAY6AU6.js +159 -0
  27. package/dist/chunk-TYAY6AU6.js.map +1 -0
  28. package/dist/client.js +2 -1
  29. package/dist/index.js +4 -3
  30. package/dist/mcp/client.js +2 -1
  31. package/dist/mcp/do-oauth-client-provider.js +1 -0
  32. package/dist/mcp/index.d.ts +12 -17
  33. package/dist/mcp/index.js +252 -182
  34. package/dist/mcp/index.js.map +1 -1
  35. package/dist/mcp/x402.d.ts +31 -0
  36. package/dist/mcp/x402.js +3195 -0
  37. package/dist/mcp/x402.js.map +1 -0
  38. package/dist/observability/index.js +4 -3
  39. package/dist/react.js +2 -1
  40. package/dist/react.js.map +1 -1
  41. package/dist/schedule.js +2 -0
  42. package/dist/schedule.js.map +1 -1
  43. package/dist/secp256k1-M22GZP2U.js +2193 -0
  44. package/dist/secp256k1-M22GZP2U.js.map +1 -0
  45. package/package.json +10 -5
  46. package/src/index.ts +8 -2
  47. package/dist/chunk-AVYJQSLW.js.map +0 -1
  48. package/dist/chunk-MH46VMM4.js.map +0 -1
  49. package/dist/chunk-YDUDMOL6.js.map +0 -1
package/dist/mcp/index.js CHANGED
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  Agent,
3
- getAgentByName
4
- } from "../chunk-YDUDMOL6.js";
3
+ getAgentByName,
4
+ getCurrentAgent
5
+ } from "../chunk-HS7VEROK.js";
5
6
  import {
6
7
  SSEEdgeClientTransport,
7
8
  StreamableHTTPEdgeClientTransport
8
- } from "../chunk-MH46VMM4.js";
9
+ } from "../chunk-SKACXF37.js";
9
10
  import "../chunk-LL2AFX7V.js";
10
11
  import "../chunk-QEVM4BVL.js";
11
- import "../chunk-AVYJQSLW.js";
12
+ import "../chunk-BER7KXUJ.js";
13
+ import "../chunk-PR4QN5HX.js";
12
14
 
13
15
  // src/mcp/index.ts
14
16
  import {
15
- JSONRPCMessageSchema as JSONRPCMessageSchema2,
16
- isJSONRPCError as isJSONRPCError3,
17
- isJSONRPCNotification as isJSONRPCNotification2,
18
- isJSONRPCRequest as isJSONRPCRequest2,
17
+ JSONRPCMessageSchema as JSONRPCMessageSchema3,
18
+ isJSONRPCError as isJSONRPCError2,
19
19
  isJSONRPCResponse as isJSONRPCResponse3
20
20
  } from "@modelcontextprotocol/sdk/types.js";
21
21
 
@@ -24,12 +24,10 @@ import {
24
24
  JSONRPCMessageSchema,
25
25
  InitializeRequestSchema,
26
26
  isJSONRPCResponse,
27
- isJSONRPCError,
28
- isJSONRPCNotification,
29
- isJSONRPCRequest
27
+ isJSONRPCNotification
30
28
  } from "@modelcontextprotocol/sdk/types.js";
31
- var STANDALONE_SSE_MARKER = "standalone-sse";
32
- var STANDALONE_SSE_METHOD = "cf/standalone_sse/attach";
29
+ var MCP_HTTP_METHOD_HEADER = "cf-mcp-method";
30
+ var MCP_MESSAGE_HEADER = "cf-mcp-message";
33
31
  var MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
34
32
  var createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
35
33
  let pathname = basePath;
@@ -114,10 +112,10 @@ var createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
114
112
  }
115
113
  }
116
114
  messages = arrayMessage.map((msg) => JSONRPCMessageSchema.parse(msg));
117
- const isInitializationRequest = messages.some(
115
+ const maybeInitializeRequest = messages.find(
118
116
  (msg) => InitializeRequestSchema.safeParse(msg).success
119
117
  );
120
- if (isInitializationRequest && sessionId) {
118
+ if (!!maybeInitializeRequest && sessionId) {
121
119
  const body2 = JSON.stringify({
122
120
  error: {
123
121
  code: -32600,
@@ -128,7 +126,7 @@ var createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
128
126
  });
129
127
  return new Response(body2, { status: 400 });
130
128
  }
131
- if (isInitializationRequest && messages.length > 1) {
129
+ if (!!maybeInitializeRequest && messages.length > 1) {
132
130
  const body2 = JSON.stringify({
133
131
  error: {
134
132
  code: -32600,
@@ -139,7 +137,7 @@ var createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
139
137
  });
140
138
  return new Response(body2, { status: 400 });
141
139
  }
142
- if (!isInitializationRequest && !sessionId) {
140
+ if (!maybeInitializeRequest && !sessionId) {
143
141
  const body2 = JSON.stringify({
144
142
  error: {
145
143
  code: -32e3,
@@ -156,9 +154,9 @@ var createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
156
154
  `streamable-http:${sessionId}`,
157
155
  { props: ctx.props }
158
156
  );
159
- const isInitialized = await agent.isInitialized();
160
- if (isInitializationRequest) {
161
- await agent.setInitialized();
157
+ const isInitialized = await agent.getInitializeRequest();
158
+ if (maybeInitializeRequest) {
159
+ await agent.setInitializeRequest(maybeInitializeRequest);
162
160
  } else if (!isInitialized) {
163
161
  const body2 = JSON.stringify({
164
162
  error: {
@@ -180,6 +178,8 @@ var createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
180
178
  const req = new Request(request.url, {
181
179
  headers: {
182
180
  ...existingHeaders,
181
+ [MCP_HTTP_METHOD_HEADER]: "POST",
182
+ [MCP_MESSAGE_HEADER]: JSON.stringify(messages),
183
183
  Upgrade: "websocket"
184
184
  }
185
185
  });
@@ -199,28 +199,20 @@ var createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
199
199
  });
200
200
  return new Response(body2, { status: 500 });
201
201
  }
202
- const requestIds = /* @__PURE__ */ new Set();
203
202
  ws.accept();
204
203
  ws.addEventListener("message", (event) => {
205
204
  async function onMessage(event2) {
206
205
  try {
207
206
  const data = typeof event2.data === "string" ? event2.data : new TextDecoder().decode(event2.data);
208
207
  const message = JSON.parse(data);
209
- const result = JSONRPCMessageSchema.safeParse(message);
210
- if (!result.success) {
208
+ if (message.type !== "cf_mcp_agent_event" /* CF_MCP_AGENT_EVENT */) {
211
209
  return;
212
210
  }
213
- if (isJSONRPCResponse(result.data) || isJSONRPCError(result.data)) {
214
- requestIds.delete(result.data.id);
215
- }
216
- const messageText = `event: message
217
- data: ${JSON.stringify(result.data)}
218
-
219
- `;
220
- await writer.write(encoder.encode(messageText));
221
- if (requestIds.size === 0) {
211
+ await writer.write(encoder.encode(message.event));
212
+ if (message.close) {
222
213
  ws?.close();
223
- await writer.close();
214
+ await writer.close().catch(() => {
215
+ });
224
216
  }
225
217
  } catch (error) {
226
218
  console.error("Error forwarding message to SSE:", error);
@@ -230,20 +222,15 @@ data: ${JSON.stringify(result.data)}
230
222
  });
231
223
  ws.addEventListener("error", (error) => {
232
224
  async function onError(_error) {
233
- try {
234
- await writer.close();
235
- } catch (_e) {
236
- }
225
+ await writer.close().catch(() => {
226
+ });
237
227
  }
238
228
  onError(error).catch(console.error);
239
229
  });
240
230
  ws.addEventListener("close", () => {
241
231
  async function onClose() {
242
- try {
243
- await writer.close();
244
- } catch (error) {
245
- console.error("Error closing SSE connection:", error);
246
- }
232
+ await writer.close().catch(() => {
233
+ });
247
234
  }
248
235
  onClose().catch(console.error);
249
236
  });
@@ -251,21 +238,12 @@ data: ${JSON.stringify(result.data)}
251
238
  (msg) => isJSONRPCNotification(msg) || isJSONRPCResponse(msg)
252
239
  );
253
240
  if (hasOnlyNotificationsOrResponses) {
254
- for (const message of messages) {
255
- ws.send(JSON.stringify(message));
256
- }
257
241
  ws.close();
258
242
  return new Response(null, {
259
243
  headers: corsHeaders(request, corsOptions),
260
244
  status: 202
261
245
  });
262
246
  }
263
- for (const message of messages) {
264
- if (isJSONRPCRequest(message)) {
265
- requestIds.add(message.id);
266
- }
267
- ws.send(JSON.stringify(message));
268
- }
269
247
  return new Response(readable, {
270
248
  headers: {
271
249
  "Cache-Control": "no-cache",
@@ -289,9 +267,19 @@ data: ${JSON.stringify(result.data)}
289
267
  });
290
268
  return new Response(body2, { status: 406 });
291
269
  }
292
- const sessionId = url.searchParams.get("sessionId");
270
+ const sessionId = request.headers.get("mcp-session-id");
293
271
  if (!sessionId)
294
- return new Response("Missing sessionId", { status: 400 });
272
+ return new Response(
273
+ JSON.stringify({
274
+ error: {
275
+ code: -32e3,
276
+ message: "Bad Request: Mcp-Session-Id header is required"
277
+ },
278
+ id: null,
279
+ jsonrpc: "2.0"
280
+ }),
281
+ { status: 400 }
282
+ );
295
283
  const { readable, writable } = new TransformStream();
296
284
  const writer = writable.getWriter();
297
285
  const encoder = new TextEncoder();
@@ -300,7 +288,7 @@ data: ${JSON.stringify(result.data)}
300
288
  `streamable-http:${sessionId}`,
301
289
  { props: ctx.props }
302
290
  );
303
- const isInitialized = await agent.isInitialized();
291
+ const isInitialized = await agent.getInitializeRequest();
304
292
  if (!isInitialized) {
305
293
  return new Response(
306
294
  JSON.stringify({
@@ -320,6 +308,7 @@ data: ${JSON.stringify(result.data)}
320
308
  new Request(request.url, {
321
309
  headers: {
322
310
  ...existingHeaders,
311
+ [MCP_HTTP_METHOD_HEADER]: "GET",
323
312
  Upgrade: "websocket"
324
313
  }
325
314
  })
@@ -332,24 +321,15 @@ data: ${JSON.stringify(result.data)}
332
321
  });
333
322
  }
334
323
  ws.accept();
335
- ws.send(
336
- JSON.stringify({
337
- jsonrpc: "2.0",
338
- method: STANDALONE_SSE_METHOD,
339
- params: {}
340
- })
341
- );
342
324
  ws.addEventListener("message", (event) => {
343
325
  try {
344
326
  async function onMessage(ev) {
345
327
  const data = typeof ev.data === "string" ? ev.data : new TextDecoder().decode(ev.data);
346
- const parsed = JSONRPCMessageSchema.safeParse(JSON.parse(data));
347
- if (!parsed.success) return;
348
- const frame = `event: message
349
- data: ${JSON.stringify(parsed.data)}
350
-
351
- `;
352
- await writer.write(encoder.encode(frame));
328
+ const message = JSON.parse(data);
329
+ if (message.type !== "cf_mcp_agent_event" /* CF_MCP_AGENT_EVENT */) {
330
+ return;
331
+ }
332
+ await writer.write(encoder.encode(message.event));
353
333
  }
354
334
  onMessage(event).catch(console.error);
355
335
  } catch (e) {
@@ -393,7 +373,7 @@ data: ${JSON.stringify(parsed.data)}
393
373
  namespace,
394
374
  `streamable-http:${sessionId}`
395
375
  );
396
- const isInitialized = await agent.isInitialized();
376
+ const isInitialized = await agent.getInitializeRequest();
397
377
  if (!isInitialized) {
398
378
  return new Response(
399
379
  JSON.stringify({
@@ -592,8 +572,10 @@ function isDurableObjectNamespace(namespace) {
592
572
 
593
573
  // src/mcp/transport.ts
594
574
  import {
595
- isJSONRPCError as isJSONRPCError2,
596
- isJSONRPCResponse as isJSONRPCResponse2
575
+ isJSONRPCError,
576
+ isJSONRPCRequest,
577
+ isJSONRPCResponse as isJSONRPCResponse2,
578
+ JSONRPCMessageSchema as JSONRPCMessageSchema2
597
579
  } from "@modelcontextprotocol/sdk/types.js";
598
580
  var McpSSETransport = class {
599
581
  constructor(getWebSocket) {
@@ -624,59 +606,190 @@ var McpSSETransport = class {
624
606
  this.onclose?.();
625
607
  }
626
608
  };
627
- var McpStreamableHttpTransport = class {
628
- constructor(getWebSocketForMessageID, notifyResponseIdSent, getWebSocketForStandaloneSse) {
609
+ var StreamableHTTPServerTransport = class {
610
+ constructor(options) {
629
611
  this._started = false;
630
- this._getWebSocketForMessageID = getWebSocketForMessageID;
631
- this._notifyResponseIdSent = notifyResponseIdSent;
632
- this._getWebSocketForStandaloneSse = getWebSocketForStandaloneSse;
612
+ // This is to keep track whether all messages from a single POST request have been answered.
613
+ // I's fine that we don't persist this since it's only for backwards compatibility as clients
614
+ // should no longer batch requests, per the spec.
615
+ this._requestResponseMap = /* @__PURE__ */ new Map();
616
+ const { agent } = getCurrentAgent();
617
+ if (!agent)
618
+ throw new Error("McpAgent was not found in Transport constructor");
619
+ this.sessionId = agent.getSessionId();
620
+ this._eventStore = options.eventStore;
633
621
  }
622
+ /**
623
+ * Starts the transport. This is required by the Transport interface but is a no-op
624
+ * for the Streamable HTTP transport as connections are managed per-request.
625
+ */
634
626
  async start() {
635
627
  if (this._started) {
636
628
  throw new Error("Transport already started");
637
629
  }
638
630
  this._started = true;
639
631
  }
640
- async send(message, options) {
641
- if (!this._started) {
642
- throw new Error("Transport not started");
632
+ /**
633
+ * Handles GET requests for SSE stream
634
+ */
635
+ async handleGetRequest(req) {
636
+ const { connection } = getCurrentAgent();
637
+ if (!connection)
638
+ throw new Error("Connection was not found in handleGetRequest");
639
+ if (this._eventStore) {
640
+ const lastEventId = req.headers.get("last-event-id");
641
+ if (lastEventId) {
642
+ await this.replayEvents(lastEventId);
643
+ return;
644
+ }
643
645
  }
646
+ connection.setState({
647
+ _standaloneSse: true
648
+ });
649
+ }
650
+ /**
651
+ * Replays events that would have been sent after the specified event ID
652
+ * Only used when resumability is enabled
653
+ */
654
+ async replayEvents(lastEventId) {
655
+ if (!this._eventStore) {
656
+ return;
657
+ }
658
+ const { connection } = getCurrentAgent();
659
+ if (!connection)
660
+ throw new Error("Connection was not available in replayEvents");
661
+ try {
662
+ await this._eventStore?.replayEventsAfter(lastEventId, {
663
+ send: async (eventId, message) => {
664
+ try {
665
+ this.writeSSEEvent(connection, message, eventId);
666
+ } catch (error) {
667
+ this.onerror?.(error);
668
+ }
669
+ }
670
+ });
671
+ } catch (error) {
672
+ this.onerror?.(error);
673
+ }
674
+ }
675
+ /**
676
+ * Writes an event to the SSE stream with proper formatting
677
+ */
678
+ writeSSEEvent(connection, message, eventId, close) {
679
+ let eventData = "event: message\n";
680
+ if (eventId) {
681
+ eventData += `id: ${eventId}
682
+ `;
683
+ }
684
+ eventData += `data: ${JSON.stringify(message)}
685
+
686
+ `;
687
+ return connection.send(
688
+ JSON.stringify({
689
+ type: "cf_mcp_agent_event" /* CF_MCP_AGENT_EVENT */,
690
+ event: eventData,
691
+ close
692
+ })
693
+ );
694
+ }
695
+ /**
696
+ * Handles POST requests containing JSON-RPC messages
697
+ */
698
+ async handlePostRequest(req, parsedBody) {
699
+ const authInfo = req.auth;
700
+ const requestInfo = {
701
+ headers: Object.fromEntries(req.headers.entries())
702
+ };
703
+ delete requestInfo.headers[MCP_HTTP_METHOD_HEADER];
704
+ delete requestInfo.headers[MCP_MESSAGE_HEADER];
705
+ delete requestInfo.headers.upgrade;
706
+ const rawMessage = parsedBody;
707
+ let messages;
708
+ if (Array.isArray(rawMessage)) {
709
+ messages = rawMessage.map((msg) => JSONRPCMessageSchema2.parse(msg));
710
+ } else {
711
+ messages = [JSONRPCMessageSchema2.parse(rawMessage)];
712
+ }
713
+ const hasRequests = messages.some(isJSONRPCRequest);
714
+ if (!hasRequests) {
715
+ for (const message of messages) {
716
+ this.onmessage?.(message, { authInfo, requestInfo });
717
+ }
718
+ } else if (hasRequests) {
719
+ const { connection } = getCurrentAgent();
720
+ if (!connection)
721
+ throw new Error("Connection was not found in handlePostRequest");
722
+ const requestIds = messages.filter(isJSONRPCRequest).map((message) => message.id);
723
+ connection.setState({
724
+ requestIds
725
+ });
726
+ for (const message of messages) {
727
+ this.onmessage?.(message, { authInfo, requestInfo });
728
+ }
729
+ }
730
+ }
731
+ async close() {
732
+ const { agent } = getCurrentAgent();
733
+ if (!agent) throw new Error("Agent was not found in close");
734
+ for (const conn of agent.getConnections()) {
735
+ conn.close(1e3, "Session closed");
736
+ }
737
+ this.onclose?.();
738
+ }
739
+ async send(message, options) {
740
+ const { agent } = getCurrentAgent();
741
+ if (!agent) throw new Error("Agent was not found in send");
644
742
  let requestId = options?.relatedRequestId;
645
- if (isJSONRPCResponse2(message) || isJSONRPCError2(message)) {
743
+ if (isJSONRPCResponse2(message) || isJSONRPCError(message)) {
646
744
  requestId = message.id;
647
745
  }
648
746
  if (requestId === void 0) {
649
- if (isJSONRPCResponse2(message) || isJSONRPCError2(message)) {
747
+ if (isJSONRPCResponse2(message) || isJSONRPCError(message)) {
650
748
  throw new Error(
651
749
  "Cannot send a response on a standalone SSE stream unless resuming a previous client request"
652
750
  );
653
751
  }
654
- const standaloneSseSocket = this._getWebSocketForStandaloneSse();
655
- if (!standaloneSseSocket) {
752
+ let standaloneConnection;
753
+ for (const conn of agent.getConnections()) {
754
+ if (conn.state?._standaloneSse) standaloneConnection = conn;
755
+ }
756
+ if (standaloneConnection === void 0) {
656
757
  return;
657
758
  }
658
- try {
659
- standaloneSseSocket?.send(JSON.stringify(message));
660
- } catch (error) {
661
- this.onerror?.(error);
759
+ let eventId2;
760
+ if (this._eventStore) {
761
+ eventId2 = await this._eventStore.storeEvent(
762
+ standaloneConnection.id,
763
+ message
764
+ );
662
765
  }
766
+ this.writeSSEEvent(standaloneConnection, message, eventId2);
663
767
  return;
664
768
  }
665
- const websocket = this._getWebSocketForMessageID(requestId.toString());
666
- if (!websocket) {
667
- throw new Error(`Could not find WebSocket for message id: ${requestId}`);
769
+ const connection = Array.from(
770
+ agent.getConnections()
771
+ ).find((conn) => conn.state?.requestIds?.includes(requestId));
772
+ if (!connection) {
773
+ throw new Error(
774
+ `No connection established for request ID: ${String(requestId)}`
775
+ );
668
776
  }
669
- try {
670
- websocket?.send(JSON.stringify(message));
671
- if (isJSONRPCResponse2(message) || isJSONRPCError2(message)) {
672
- this._notifyResponseIdSent(message.id.toString());
777
+ let eventId;
778
+ if (this._eventStore) {
779
+ eventId = await this._eventStore.storeEvent(connection.id, message);
780
+ }
781
+ let shouldClose = false;
782
+ if (isJSONRPCResponse2(message) || isJSONRPCError(message)) {
783
+ this._requestResponseMap.set(requestId, message);
784
+ const relatedIds = connection.state?.requestIds ?? [];
785
+ shouldClose = relatedIds.every((id) => this._requestResponseMap.has(id));
786
+ if (shouldClose) {
787
+ for (const id of relatedIds) {
788
+ this._requestResponseMap.delete(id);
789
+ }
673
790
  }
674
- } catch (error) {
675
- this.onerror?.(error);
676
791
  }
677
- }
678
- async close() {
679
- this.onclose?.();
792
+ this.writeSSEEvent(connection, message, eventId, shouldClose);
680
793
  }
681
794
  };
682
795
 
@@ -685,25 +798,14 @@ import {
685
798
  ElicitRequestSchema
686
799
  } from "@modelcontextprotocol/sdk/types.js";
687
800
  var McpAgent = class _McpAgent extends Agent {
688
- constructor(ctx, env) {
689
- super(ctx, env);
690
- this._requestIdToConnectionId = /* @__PURE__ */ new Map();
691
- for (const connection of this.getConnections()) {
692
- const meta = connection.state;
693
- if (meta?.role === STANDALONE_SSE_MARKER) {
694
- this._standaloneSseConnectionId = connection.id;
695
- return;
696
- }
697
- }
698
- }
699
801
  /*
700
802
  * Helpers
701
803
  */
702
- async setInitialized() {
703
- await this.ctx.storage.put("initialized", true);
804
+ async setInitializeRequest(initializeRequest) {
805
+ await this.ctx.storage.put("initializeRequest", initializeRequest);
704
806
  }
705
- async isInitialized() {
706
- return await this.ctx.storage.get("initialized") === true;
807
+ async getInitializeRequest() {
808
+ return this.ctx.storage.get("initializeRequest");
707
809
  }
708
810
  /** Read the transport type for this agent.
709
811
  * This relies on the naming scheme being `sse:${sessionId}`
@@ -722,10 +824,18 @@ var McpAgent = class _McpAgent extends Agent {
722
824
  );
723
825
  }
724
826
  }
725
- /** Get the WebSocket for the standalone SSE if any. Streamable HTTP only. */
726
- getWebSocketForStandaloneSse() {
727
- if (!this._standaloneSseConnectionId) return null;
728
- return this.getConnection(this._standaloneSseConnectionId) ?? null;
827
+ /** Read the sessionId for this agent.
828
+ * This relies on the naming scheme being `sse:${sessionId}`
829
+ * or `streamable-http:${sessionId}`.
830
+ */
831
+ getSessionId() {
832
+ const [_, sessionId] = this.name.split(":");
833
+ if (!sessionId) {
834
+ throw new Error(
835
+ "Invalid session id. McpAgent must be addressed with a valid session id."
836
+ );
837
+ }
838
+ return sessionId;
729
839
  }
730
840
  /** Get the unique WebSocket. SSE transport only. */
731
841
  getWebSocket() {
@@ -735,14 +845,6 @@ var McpAgent = class _McpAgent extends Agent {
735
845
  }
736
846
  return websockets[0];
737
847
  }
738
- /** Get the corresponding WebSocket for a responseId. Streamable HTTP only. */
739
- getWebSocketForResponseID(id) {
740
- const connectionId = this._requestIdToConnectionId.get(id);
741
- if (connectionId === void 0) {
742
- return null;
743
- }
744
- return this.getConnection(connectionId) ?? null;
745
- }
746
848
  /** Returns a new transport matching the type of the Agent. */
747
849
  initTransport() {
748
850
  switch (this.getTransportType()) {
@@ -750,11 +852,7 @@ var McpAgent = class _McpAgent extends Agent {
750
852
  return new McpSSETransport(() => this.getWebSocket());
751
853
  }
752
854
  case "streamable-http": {
753
- return new McpStreamableHttpTransport(
754
- (id) => this.getWebSocketForResponseID(id),
755
- (id) => this._requestIdToConnectionId.delete(id),
756
- () => this.getWebSocketForStandaloneSse()
757
- );
855
+ return new StreamableHTTPServerTransport({});
758
856
  }
759
857
  }
760
858
  }
@@ -763,6 +861,12 @@ var McpAgent = class _McpAgent extends Agent {
763
861
  await this.ctx.storage.put("props", props ?? {});
764
862
  this.props = props;
765
863
  }
864
+ async reinitializeServer() {
865
+ const initializeRequest = await this.getInitializeRequest();
866
+ if (initializeRequest) {
867
+ this._transport?.onmessage?.(initializeRequest);
868
+ }
869
+ }
766
870
  /*
767
871
  * Base Agent / Parykit Server overrides
768
872
  */
@@ -774,9 +878,10 @@ var McpAgent = class _McpAgent extends Agent {
774
878
  const server = await this.server;
775
879
  this._transport = this.initTransport();
776
880
  await server.connect(this._transport);
881
+ await this.reinitializeServer();
777
882
  }
778
883
  /** Validates new WebSocket connections. */
779
- async onConnect(conn, _) {
884
+ async onConnect(conn, { request: req }) {
780
885
  switch (this.getTransportType()) {
781
886
  case "sse": {
782
887
  const websockets = Array.from(this.getConnections());
@@ -787,54 +892,19 @@ var McpAgent = class _McpAgent extends Agent {
787
892
  break;
788
893
  }
789
894
  case "streamable-http":
790
- break;
791
- }
792
- }
793
- /** Handles MCP Messages for Streamable HTTP. */
794
- async onMessage(connection, event) {
795
- if (this.getTransportType() !== "streamable-http") {
796
- const err = new Error(
797
- "Internal Server Error: Expected streamable-http protocol"
798
- );
799
- this._transport?.onerror?.(err);
800
- return;
801
- }
802
- let message;
803
- try {
804
- const data = typeof event === "string" ? event : new TextDecoder().decode(event);
805
- message = JSONRPCMessageSchema2.parse(JSON.parse(data));
806
- } catch (error) {
807
- this._transport?.onerror?.(error);
808
- return;
809
- }
810
- if (isJSONRPCNotification2(message) && message.method === STANDALONE_SSE_METHOD) {
811
- if (this._standaloneSseConnectionId && this._standaloneSseConnectionId !== connection.id) {
812
- const standaloneSseSocket = this.getConnection(
813
- this._standaloneSseConnectionId
814
- );
815
- standaloneSseSocket?.close(1e3, "replaced");
816
- }
817
- connection.setState({
818
- role: STANDALONE_SSE_MARKER
819
- });
820
- this._standaloneSseConnectionId = connection.id;
821
- return;
822
- }
823
- if (await this._handleElicitationResponse(message)) {
824
- return;
825
- }
826
- if (isJSONRPCRequest2(message)) {
827
- this._requestIdToConnectionId.set(message.id.toString(), connection.id);
828
- }
829
- this._transport?.onmessage?.(message);
830
- }
831
- /** Remove clients from our cache when they disconnect */
832
- async onClose(conn, _code, _reason, _wasClean) {
833
- for (const [reqId, connId] of this._requestIdToConnectionId) {
834
- if (connId === conn.id) this._requestIdToConnectionId.delete(reqId);
835
- }
836
- if (this._standaloneSseConnectionId === conn.id) {
837
- this._standaloneSseConnectionId = void 0;
895
+ if (this._transport instanceof StreamableHTTPServerTransport) {
896
+ switch (req.headers.get(MCP_HTTP_METHOD_HEADER)) {
897
+ case "POST": {
898
+ const payloadHeader = req.headers.get(MCP_MESSAGE_HEADER);
899
+ const parsedBody = await JSON.parse(payloadHeader ?? "{}");
900
+ this._transport?.handlePostRequest(req, parsedBody);
901
+ break;
902
+ }
903
+ case "GET":
904
+ this._transport?.handleGetRequest(req);
905
+ break;
906
+ }
907
+ }
838
908
  }
839
909
  }
840
910
  /*
@@ -848,7 +918,7 @@ var McpAgent = class _McpAgent extends Agent {
848
918
  try {
849
919
  let parsedMessage;
850
920
  try {
851
- parsedMessage = JSONRPCMessageSchema2.parse(messageBody);
921
+ parsedMessage = JSONRPCMessageSchema3.parse(messageBody);
852
922
  } catch (error) {
853
923
  this._transport?.onerror?.(error);
854
924
  throw error;
@@ -937,7 +1007,7 @@ var McpAgent = class _McpAgent extends Agent {
937
1007
  );
938
1008
  return true;
939
1009
  }
940
- if (isJSONRPCError3(message)) {
1010
+ if (isJSONRPCError2(message)) {
941
1011
  const requestId = message.id?.toString();
942
1012
  if (!requestId || !requestId.startsWith("elicit_")) return false;
943
1013
  const pendingRequest = await this.ctx.storage.get(