agents 0.1.4 → 0.1.6
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.
- package/dist/_esm-LV5FJ3HK.js +3922 -0
- package/dist/_esm-LV5FJ3HK.js.map +1 -0
- package/dist/ai-chat-agent.js +4 -3
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-chat-v5-migration.js +1 -0
- package/dist/ai-react.d.ts +6 -0
- package/dist/ai-react.js +43 -9
- package/dist/ai-react.js.map +1 -1
- package/dist/ai-types.d.ts +1 -0
- package/dist/ai-types.js +2 -1
- package/dist/ccip-CMBYN64O.js +15 -0
- package/dist/ccip-CMBYN64O.js.map +1 -0
- package/dist/chunk-5Y6BEZDY.js +276 -0
- package/dist/chunk-5Y6BEZDY.js.map +1 -0
- package/dist/{chunk-AVYJQSLW.js → chunk-BER7KXUJ.js} +2 -1
- package/dist/chunk-BER7KXUJ.js.map +1 -0
- package/dist/chunk-JJBFIGUC.js +5202 -0
- package/dist/chunk-JJBFIGUC.js.map +1 -0
- package/dist/{chunk-YDUDMOL6.js → chunk-KK7D3KRW.js} +7 -3
- package/dist/chunk-KK7D3KRW.js.map +1 -0
- package/dist/chunk-PR4QN5HX.js +43 -0
- package/dist/chunk-PR4QN5HX.js.map +1 -0
- package/dist/{chunk-MH46VMM4.js → chunk-THPMWGLS.js} +4 -3
- package/dist/{chunk-MH46VMM4.js.map → chunk-THPMWGLS.js.map} +1 -1
- package/dist/chunk-TYAY6AU6.js +159 -0
- package/dist/chunk-TYAY6AU6.js.map +1 -0
- package/dist/client.js +2 -1
- package/dist/index.js +4 -3
- package/dist/mcp/client.js +2 -1
- package/dist/mcp/do-oauth-client-provider.js +1 -0
- package/dist/mcp/index.d.ts +9 -14
- package/dist/mcp/index.js +232 -162
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/x402.d.ts +31 -0
- package/dist/mcp/x402.js +3195 -0
- package/dist/mcp/x402.js.map +1 -0
- package/dist/observability/index.js +4 -3
- package/dist/react.js +2 -1
- package/dist/react.js.map +1 -1
- package/dist/schedule.js +2 -0
- package/dist/schedule.js.map +1 -1
- package/dist/secp256k1-M22GZP2U.js +2193 -0
- package/dist/secp256k1-M22GZP2U.js.map +1 -0
- package/package.json +11 -5
- package/src/index.ts +8 -2
- package/dist/chunk-AVYJQSLW.js.map +0 -1
- 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
|
-
|
|
3
|
+
getAgentByName,
|
|
4
|
+
getCurrentAgent
|
|
5
|
+
} from "../chunk-KK7D3KRW.js";
|
|
5
6
|
import {
|
|
6
7
|
SSEEdgeClientTransport,
|
|
7
8
|
StreamableHTTPEdgeClientTransport
|
|
8
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-THPMWGLS.js";
|
|
9
10
|
import "../chunk-LL2AFX7V.js";
|
|
10
11
|
import "../chunk-QEVM4BVL.js";
|
|
11
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-BER7KXUJ.js";
|
|
13
|
+
import "../chunk-PR4QN5HX.js";
|
|
12
14
|
|
|
13
15
|
// src/mcp/index.ts
|
|
14
16
|
import {
|
|
15
|
-
JSONRPCMessageSchema as
|
|
16
|
-
isJSONRPCError as
|
|
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
|
-
|
|
28
|
-
isJSONRPCNotification,
|
|
29
|
-
isJSONRPCRequest
|
|
27
|
+
isJSONRPCNotification
|
|
30
28
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
31
|
-
var
|
|
32
|
-
var
|
|
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;
|
|
@@ -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,26 +199,17 @@ 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
|
-
|
|
210
|
-
if (!result.success) {
|
|
208
|
+
if (message.type !== "cf_mcp_agent_event" /* CF_MCP_AGENT_EVENT */) {
|
|
211
209
|
return;
|
|
212
210
|
}
|
|
213
|
-
|
|
214
|
-
|
|
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
214
|
await writer.close().catch(() => {
|
|
224
215
|
});
|
|
@@ -247,21 +238,12 @@ data: ${JSON.stringify(result.data)}
|
|
|
247
238
|
(msg) => isJSONRPCNotification(msg) || isJSONRPCResponse(msg)
|
|
248
239
|
);
|
|
249
240
|
if (hasOnlyNotificationsOrResponses) {
|
|
250
|
-
for (const message of messages) {
|
|
251
|
-
ws.send(JSON.stringify(message));
|
|
252
|
-
}
|
|
253
241
|
ws.close();
|
|
254
242
|
return new Response(null, {
|
|
255
243
|
headers: corsHeaders(request, corsOptions),
|
|
256
244
|
status: 202
|
|
257
245
|
});
|
|
258
246
|
}
|
|
259
|
-
for (const message of messages) {
|
|
260
|
-
if (isJSONRPCRequest(message)) {
|
|
261
|
-
requestIds.add(message.id);
|
|
262
|
-
}
|
|
263
|
-
ws.send(JSON.stringify(message));
|
|
264
|
-
}
|
|
265
247
|
return new Response(readable, {
|
|
266
248
|
headers: {
|
|
267
249
|
"Cache-Control": "no-cache",
|
|
@@ -287,7 +269,17 @@ data: ${JSON.stringify(result.data)}
|
|
|
287
269
|
}
|
|
288
270
|
const sessionId = request.headers.get("mcp-session-id");
|
|
289
271
|
if (!sessionId)
|
|
290
|
-
return new Response(
|
|
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
|
+
);
|
|
291
283
|
const { readable, writable } = new TransformStream();
|
|
292
284
|
const writer = writable.getWriter();
|
|
293
285
|
const encoder = new TextEncoder();
|
|
@@ -316,6 +308,7 @@ data: ${JSON.stringify(result.data)}
|
|
|
316
308
|
new Request(request.url, {
|
|
317
309
|
headers: {
|
|
318
310
|
...existingHeaders,
|
|
311
|
+
[MCP_HTTP_METHOD_HEADER]: "GET",
|
|
319
312
|
Upgrade: "websocket"
|
|
320
313
|
}
|
|
321
314
|
})
|
|
@@ -328,24 +321,15 @@ data: ${JSON.stringify(result.data)}
|
|
|
328
321
|
});
|
|
329
322
|
}
|
|
330
323
|
ws.accept();
|
|
331
|
-
ws.send(
|
|
332
|
-
JSON.stringify({
|
|
333
|
-
jsonrpc: "2.0",
|
|
334
|
-
method: STANDALONE_SSE_METHOD,
|
|
335
|
-
params: {}
|
|
336
|
-
})
|
|
337
|
-
);
|
|
338
324
|
ws.addEventListener("message", (event) => {
|
|
339
325
|
try {
|
|
340
326
|
async function onMessage(ev) {
|
|
341
327
|
const data = typeof ev.data === "string" ? ev.data : new TextDecoder().decode(ev.data);
|
|
342
|
-
const
|
|
343
|
-
if (
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
`;
|
|
348
|
-
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));
|
|
349
333
|
}
|
|
350
334
|
onMessage(event).catch(console.error);
|
|
351
335
|
} catch (e) {
|
|
@@ -588,8 +572,10 @@ function isDurableObjectNamespace(namespace) {
|
|
|
588
572
|
|
|
589
573
|
// src/mcp/transport.ts
|
|
590
574
|
import {
|
|
591
|
-
isJSONRPCError
|
|
592
|
-
|
|
575
|
+
isJSONRPCError,
|
|
576
|
+
isJSONRPCRequest,
|
|
577
|
+
isJSONRPCResponse as isJSONRPCResponse2,
|
|
578
|
+
JSONRPCMessageSchema as JSONRPCMessageSchema2
|
|
593
579
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
594
580
|
var McpSSETransport = class {
|
|
595
581
|
constructor(getWebSocket) {
|
|
@@ -620,59 +606,190 @@ var McpSSETransport = class {
|
|
|
620
606
|
this.onclose?.();
|
|
621
607
|
}
|
|
622
608
|
};
|
|
623
|
-
var
|
|
624
|
-
constructor(
|
|
609
|
+
var StreamableHTTPServerTransport = class {
|
|
610
|
+
constructor(options) {
|
|
625
611
|
this._started = false;
|
|
626
|
-
|
|
627
|
-
this
|
|
628
|
-
|
|
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;
|
|
629
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
|
+
*/
|
|
630
626
|
async start() {
|
|
631
627
|
if (this._started) {
|
|
632
628
|
throw new Error("Transport already started");
|
|
633
629
|
}
|
|
634
630
|
this._started = true;
|
|
635
631
|
}
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
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
|
+
}
|
|
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
|
+
}
|
|
639
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");
|
|
640
742
|
let requestId = options?.relatedRequestId;
|
|
641
|
-
if (isJSONRPCResponse2(message) ||
|
|
743
|
+
if (isJSONRPCResponse2(message) || isJSONRPCError(message)) {
|
|
642
744
|
requestId = message.id;
|
|
643
745
|
}
|
|
644
746
|
if (requestId === void 0) {
|
|
645
|
-
if (isJSONRPCResponse2(message) ||
|
|
747
|
+
if (isJSONRPCResponse2(message) || isJSONRPCError(message)) {
|
|
646
748
|
throw new Error(
|
|
647
749
|
"Cannot send a response on a standalone SSE stream unless resuming a previous client request"
|
|
648
750
|
);
|
|
649
751
|
}
|
|
650
|
-
|
|
651
|
-
|
|
752
|
+
let standaloneConnection;
|
|
753
|
+
for (const conn of agent.getConnections()) {
|
|
754
|
+
if (conn.state?._standaloneSse) standaloneConnection = conn;
|
|
755
|
+
}
|
|
756
|
+
if (standaloneConnection === void 0) {
|
|
652
757
|
return;
|
|
653
758
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
759
|
+
let eventId2;
|
|
760
|
+
if (this._eventStore) {
|
|
761
|
+
eventId2 = await this._eventStore.storeEvent(
|
|
762
|
+
standaloneConnection.id,
|
|
763
|
+
message
|
|
764
|
+
);
|
|
658
765
|
}
|
|
766
|
+
this.writeSSEEvent(standaloneConnection, message, eventId2);
|
|
659
767
|
return;
|
|
660
768
|
}
|
|
661
|
-
const
|
|
662
|
-
|
|
663
|
-
|
|
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
|
+
);
|
|
664
776
|
}
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
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
|
+
}
|
|
669
790
|
}
|
|
670
|
-
} catch (error) {
|
|
671
|
-
this.onerror?.(error);
|
|
672
791
|
}
|
|
673
|
-
|
|
674
|
-
async close() {
|
|
675
|
-
this.onclose?.();
|
|
792
|
+
this.writeSSEEvent(connection, message, eventId, shouldClose);
|
|
676
793
|
}
|
|
677
794
|
};
|
|
678
795
|
|
|
@@ -681,17 +798,6 @@ import {
|
|
|
681
798
|
ElicitRequestSchema
|
|
682
799
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
683
800
|
var McpAgent = class _McpAgent extends Agent {
|
|
684
|
-
constructor(ctx, env) {
|
|
685
|
-
super(ctx, env);
|
|
686
|
-
this._requestIdToConnectionId = /* @__PURE__ */ new Map();
|
|
687
|
-
for (const connection of this.getConnections()) {
|
|
688
|
-
const meta = connection.state;
|
|
689
|
-
if (meta?.role === STANDALONE_SSE_MARKER) {
|
|
690
|
-
this._standaloneSseConnectionId = connection.id;
|
|
691
|
-
return;
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
801
|
/*
|
|
696
802
|
* Helpers
|
|
697
803
|
*/
|
|
@@ -718,10 +824,18 @@ var McpAgent = class _McpAgent extends Agent {
|
|
|
718
824
|
);
|
|
719
825
|
}
|
|
720
826
|
}
|
|
721
|
-
/**
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
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;
|
|
725
839
|
}
|
|
726
840
|
/** Get the unique WebSocket. SSE transport only. */
|
|
727
841
|
getWebSocket() {
|
|
@@ -731,14 +845,6 @@ var McpAgent = class _McpAgent extends Agent {
|
|
|
731
845
|
}
|
|
732
846
|
return websockets[0];
|
|
733
847
|
}
|
|
734
|
-
/** Get the corresponding WebSocket for a responseId. Streamable HTTP only. */
|
|
735
|
-
getWebSocketForResponseID(id) {
|
|
736
|
-
const connectionId = this._requestIdToConnectionId.get(id);
|
|
737
|
-
if (connectionId === void 0) {
|
|
738
|
-
return null;
|
|
739
|
-
}
|
|
740
|
-
return this.getConnection(connectionId) ?? null;
|
|
741
|
-
}
|
|
742
848
|
/** Returns a new transport matching the type of the Agent. */
|
|
743
849
|
initTransport() {
|
|
744
850
|
switch (this.getTransportType()) {
|
|
@@ -746,11 +852,7 @@ var McpAgent = class _McpAgent extends Agent {
|
|
|
746
852
|
return new McpSSETransport(() => this.getWebSocket());
|
|
747
853
|
}
|
|
748
854
|
case "streamable-http": {
|
|
749
|
-
return new
|
|
750
|
-
(id) => this.getWebSocketForResponseID(id),
|
|
751
|
-
(id) => this._requestIdToConnectionId.delete(id),
|
|
752
|
-
() => this.getWebSocketForStandaloneSse()
|
|
753
|
-
);
|
|
855
|
+
return new StreamableHTTPServerTransport({});
|
|
754
856
|
}
|
|
755
857
|
}
|
|
756
858
|
}
|
|
@@ -759,6 +861,12 @@ var McpAgent = class _McpAgent extends Agent {
|
|
|
759
861
|
await this.ctx.storage.put("props", props ?? {});
|
|
760
862
|
this.props = props;
|
|
761
863
|
}
|
|
864
|
+
async reinitializeServer() {
|
|
865
|
+
const initializeRequest = await this.getInitializeRequest();
|
|
866
|
+
if (initializeRequest) {
|
|
867
|
+
this._transport?.onmessage?.(initializeRequest);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
762
870
|
/*
|
|
763
871
|
* Base Agent / Parykit Server overrides
|
|
764
872
|
*/
|
|
@@ -770,13 +878,10 @@ var McpAgent = class _McpAgent extends Agent {
|
|
|
770
878
|
const server = await this.server;
|
|
771
879
|
this._transport = this.initTransport();
|
|
772
880
|
await server.connect(this._transport);
|
|
773
|
-
|
|
774
|
-
if (initializeRequest) {
|
|
775
|
-
this._transport.onmessage?.(initializeRequest);
|
|
776
|
-
}
|
|
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
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
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 =
|
|
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 (
|
|
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(
|