agents 0.2.18 → 0.2.20
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/ai-chat-agent.d.ts +2 -2
- package/dist/ai-react.d.ts +3 -3
- package/dist/{client-BFM__vih.d.ts → client-Csp_m13H.d.ts} +6 -5
- package/dist/{index-CNkDU-oA.d.ts → index-DFqsR7mb.d.ts} +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/mcp/client.d.ts +1 -1
- package/dist/mcp/index.d.ts +6 -5
- package/dist/mcp/index.js +44 -22
- package/dist/mcp/index.js.map +1 -1
- package/dist/{react-Osg_QWor.d.ts → react-NCPvtyCY.d.ts} +2 -2
- package/dist/react.d.ts +3 -3
- package/package.json +1 -1
package/dist/ai-chat-agent.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./client-
|
|
1
|
+
import "./client-Csp_m13H.js";
|
|
2
2
|
import "./mcp-Dw5vDrY8.js";
|
|
3
3
|
import "./do-oauth-client-provider-DGc5pP0l.js";
|
|
4
4
|
import "./index-DhJCaDWd.js";
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
s as Connection,
|
|
9
9
|
t as Agent,
|
|
10
10
|
x as WSMessage
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-DFqsR7mb.js";
|
|
12
12
|
import { StreamTextOnFinishCallback, ToolSet, UIMessage } from "ai";
|
|
13
13
|
|
|
14
14
|
//#region src/ai-chat-agent.d.ts
|
package/dist/ai-react.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import "./client-
|
|
1
|
+
import "./client-Csp_m13H.js";
|
|
2
2
|
import "./mcp-Dw5vDrY8.js";
|
|
3
3
|
import "./do-oauth-client-provider-DGc5pP0l.js";
|
|
4
4
|
import "./index-DhJCaDWd.js";
|
|
5
5
|
import "./ai-types-D5YoPrBZ.js";
|
|
6
|
-
import "./index-
|
|
6
|
+
import "./index-DFqsR7mb.js";
|
|
7
7
|
import "./serializable-CymX8ovI.js";
|
|
8
8
|
import "./client-CbWe9FBd.js";
|
|
9
|
-
import { n as useAgent } from "./react-
|
|
9
|
+
import { n as useAgent } from "./react-NCPvtyCY.js";
|
|
10
10
|
import { UseChatOptions, useChat } from "@ai-sdk/react";
|
|
11
11
|
import { ChatInit, UIMessage } from "ai";
|
|
12
12
|
|
|
@@ -79,6 +79,7 @@ interface ServeOptions {
|
|
|
79
79
|
binding?: string;
|
|
80
80
|
corsOptions?: CORSOptions;
|
|
81
81
|
transport?: BaseTransportType;
|
|
82
|
+
jurisdiction?: DurableObjectJurisdiction;
|
|
82
83
|
}
|
|
83
84
|
//#endregion
|
|
84
85
|
//#region src/mcp/client-connection.d.ts
|
|
@@ -168,13 +169,13 @@ declare class MCPClientConnection {
|
|
|
168
169
|
| undefined;
|
|
169
170
|
required?: string[] | undefined;
|
|
170
171
|
};
|
|
172
|
+
description?: string | undefined;
|
|
171
173
|
_meta?:
|
|
172
174
|
| {
|
|
173
175
|
[x: string]: unknown;
|
|
174
176
|
}
|
|
175
177
|
| undefined;
|
|
176
178
|
title?: string | undefined;
|
|
177
|
-
description?: string | undefined;
|
|
178
179
|
icons?:
|
|
179
180
|
| {
|
|
180
181
|
[x: string]: unknown;
|
|
@@ -212,6 +213,7 @@ declare class MCPClientConnection {
|
|
|
212
213
|
[x: string]: unknown;
|
|
213
214
|
name: string;
|
|
214
215
|
uri: string;
|
|
216
|
+
description?: string | undefined;
|
|
215
217
|
_meta?:
|
|
216
218
|
| {
|
|
217
219
|
[x: string]: unknown;
|
|
@@ -219,7 +221,6 @@ declare class MCPClientConnection {
|
|
|
219
221
|
| undefined;
|
|
220
222
|
mimeType?: string | undefined;
|
|
221
223
|
title?: string | undefined;
|
|
222
|
-
description?: string | undefined;
|
|
223
224
|
icons?:
|
|
224
225
|
| {
|
|
225
226
|
[x: string]: unknown;
|
|
@@ -234,6 +235,7 @@ declare class MCPClientConnection {
|
|
|
234
235
|
{
|
|
235
236
|
[x: string]: unknown;
|
|
236
237
|
name: string;
|
|
238
|
+
description?: string | undefined;
|
|
237
239
|
_meta?:
|
|
238
240
|
| {
|
|
239
241
|
[x: string]: unknown;
|
|
@@ -248,7 +250,6 @@ declare class MCPClientConnection {
|
|
|
248
250
|
}[]
|
|
249
251
|
| undefined;
|
|
250
252
|
title?: string | undefined;
|
|
251
|
-
description?: string | undefined;
|
|
252
253
|
icons?:
|
|
253
254
|
| {
|
|
254
255
|
[x: string]: unknown;
|
|
@@ -264,6 +265,7 @@ declare class MCPClientConnection {
|
|
|
264
265
|
[x: string]: unknown;
|
|
265
266
|
name: string;
|
|
266
267
|
uriTemplate: string;
|
|
268
|
+
description?: string | undefined;
|
|
267
269
|
_meta?:
|
|
268
270
|
| {
|
|
269
271
|
[x: string]: unknown;
|
|
@@ -271,7 +273,6 @@ declare class MCPClientConnection {
|
|
|
271
273
|
| undefined;
|
|
272
274
|
mimeType?: string | undefined;
|
|
273
275
|
title?: string | undefined;
|
|
274
|
-
description?: string | undefined;
|
|
275
276
|
icons?:
|
|
276
277
|
| {
|
|
277
278
|
[x: string]: unknown;
|
|
@@ -5311,4 +5312,4 @@ export {
|
|
|
5311
5312
|
MCPClientManager as t,
|
|
5312
5313
|
TransportType as u
|
|
5313
5314
|
};
|
|
5314
|
-
//# sourceMappingURL=client-
|
|
5315
|
+
//# sourceMappingURL=client-Csp_m13H.d.ts.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
a as MCPConnectionState,
|
|
3
3
|
t as MCPClientManager,
|
|
4
4
|
u as TransportType
|
|
5
|
-
} from "./client-
|
|
5
|
+
} from "./client-Csp_m13H.js";
|
|
6
6
|
import { t as Observability } from "./index-DhJCaDWd.js";
|
|
7
7
|
import { n as MessageType } from "./ai-types-D5YoPrBZ.js";
|
|
8
8
|
import {
|
|
@@ -557,4 +557,4 @@ export {
|
|
|
557
557
|
WSMessage as x,
|
|
558
558
|
StateUpdateMessage as y
|
|
559
559
|
};
|
|
560
|
-
//# sourceMappingURL=index-
|
|
560
|
+
//# sourceMappingURL=index-DFqsR7mb.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as TransportType } from "./client-
|
|
1
|
+
import { u as TransportType } from "./client-Csp_m13H.js";
|
|
2
2
|
import "./mcp-Dw5vDrY8.js";
|
|
3
3
|
import "./do-oauth-client-provider-DGc5pP0l.js";
|
|
4
4
|
import "./index-DhJCaDWd.js";
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
w as createCatchAllEmailResolver,
|
|
35
35
|
x as WSMessage,
|
|
36
36
|
y as StateUpdateMessage
|
|
37
|
-
} from "./index-
|
|
37
|
+
} from "./index-DFqsR7mb.js";
|
|
38
38
|
export {
|
|
39
39
|
Agent,
|
|
40
40
|
AgentContext,
|
package/dist/mcp/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as getNamespacedData, n as MCPClientOAuthCallbackConfig, r as MCPClientOAuthResult, t as MCPClientManager } from "../client-
|
|
1
|
+
import { i as getNamespacedData, n as MCPClientOAuthCallbackConfig, r as MCPClientOAuthResult, t as MCPClientManager } from "../client-Csp_m13H.js";
|
|
2
2
|
import "../mcp-Dw5vDrY8.js";
|
|
3
3
|
import "../do-oauth-client-provider-DGc5pP0l.js";
|
|
4
4
|
export { MCPClientManager, MCPClientOAuthCallbackConfig, MCPClientOAuthResult, getNamespacedData };
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { c as MaybePromise, d as StreamableHTTPEdgeClientTransport, f as SSEEdgeClientTransport, l as ServeOptions, n as MCPClientOAuthCallbackConfig, o as BaseTransportType, r as MCPClientOAuthResult, s as CORSOptions } from "../client-
|
|
1
|
+
import { c as MaybePromise, d as StreamableHTTPEdgeClientTransport, f as SSEEdgeClientTransport, l as ServeOptions, n as MCPClientOAuthCallbackConfig, o as BaseTransportType, r as MCPClientOAuthResult, s as CORSOptions } from "../client-Csp_m13H.js";
|
|
2
2
|
import "../mcp-Dw5vDrY8.js";
|
|
3
3
|
import "../do-oauth-client-provider-DGc5pP0l.js";
|
|
4
4
|
import "../index-DhJCaDWd.js";
|
|
5
5
|
import "../ai-types-D5YoPrBZ.js";
|
|
6
|
-
import { c as ConnectionContext, s as Connection, t as Agent } from "../index-
|
|
7
|
-
import { ElicitRequest, ElicitRequestSchema, ElicitResult, ElicitResult as ElicitResult$1, JSONRPCMessage } from "@modelcontextprotocol/sdk/types.js";
|
|
6
|
+
import { c as ConnectionContext, s as Connection, t as Agent } from "../index-DFqsR7mb.js";
|
|
7
|
+
import { ElicitRequest, ElicitRequestSchema, ElicitResult, ElicitResult as ElicitResult$1, JSONRPCMessage, MessageExtraInfo } from "@modelcontextprotocol/sdk/types.js";
|
|
8
8
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
9
9
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
10
|
import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
|
|
@@ -31,7 +31,7 @@ declare class WorkerTransport implements Transport {
|
|
|
31
31
|
sessionId?: string;
|
|
32
32
|
onclose?: () => void;
|
|
33
33
|
onerror?: (error: Error) => void;
|
|
34
|
-
onmessage?: (message: JSONRPCMessage) => void;
|
|
34
|
+
onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void;
|
|
35
35
|
constructor(options?: WorkerTransportOptions);
|
|
36
36
|
start(): Promise<void>;
|
|
37
37
|
private validateProtocolVersion;
|
|
@@ -134,7 +134,8 @@ declare abstract class McpAgent<Env = unknown, State = unknown, Props extends Re
|
|
|
134
134
|
static serve(path: string, {
|
|
135
135
|
binding,
|
|
136
136
|
corsOptions,
|
|
137
|
-
transport
|
|
137
|
+
transport,
|
|
138
|
+
jurisdiction
|
|
138
139
|
}?: ServeOptions): {
|
|
139
140
|
fetch<Env>(this: void, request: Request, env: Env, ctx: ExecutionContext): Promise<Response>;
|
|
140
141
|
};
|
package/dist/mcp/index.js
CHANGED
|
@@ -21,7 +21,7 @@ const MCP_HTTP_METHOD_HEADER = "cf-mcp-method";
|
|
|
21
21
|
*/
|
|
22
22
|
const MCP_MESSAGE_HEADER = "cf-mcp-message";
|
|
23
23
|
const MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
|
|
24
|
-
const createStreamingHttpHandler = (basePath, namespace,
|
|
24
|
+
const createStreamingHttpHandler = (basePath, namespace, options = {}) => {
|
|
25
25
|
let pathname = basePath;
|
|
26
26
|
if (basePath === "/") pathname = "/*";
|
|
27
27
|
const basePattern = new URLPattern({ pathname });
|
|
@@ -130,7 +130,10 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
130
130
|
return new Response(body$1, { status: 400 });
|
|
131
131
|
}
|
|
132
132
|
sessionId = sessionId ?? namespace.newUniqueId().toString();
|
|
133
|
-
const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, {
|
|
133
|
+
const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, {
|
|
134
|
+
props: ctx.props,
|
|
135
|
+
jurisdiction: options.jurisdiction
|
|
136
|
+
});
|
|
134
137
|
const isInitialized = await agent.getInitializeRequest();
|
|
135
138
|
if (maybeInitializeRequest) await agent.setInitializeRequest(maybeInitializeRequest);
|
|
136
139
|
else if (!isInitialized) {
|
|
@@ -205,7 +208,7 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
205
208
|
if (messages.every((msg) => isJSONRPCNotification(msg) || isJSONRPCResponse(msg))) {
|
|
206
209
|
ws.close();
|
|
207
210
|
return new Response(null, {
|
|
208
|
-
headers: corsHeaders(request, corsOptions),
|
|
211
|
+
headers: corsHeaders(request, options.corsOptions),
|
|
209
212
|
status: 202
|
|
210
213
|
});
|
|
211
214
|
}
|
|
@@ -215,7 +218,7 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
215
218
|
Connection: "keep-alive",
|
|
216
219
|
"Content-Type": "text/event-stream",
|
|
217
220
|
"mcp-session-id": sessionId,
|
|
218
|
-
...corsHeaders(request, corsOptions)
|
|
221
|
+
...corsHeaders(request, options.corsOptions)
|
|
219
222
|
},
|
|
220
223
|
status: 200
|
|
221
224
|
});
|
|
@@ -243,7 +246,10 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
243
246
|
const { readable, writable } = new TransformStream();
|
|
244
247
|
const writer = writable.getWriter();
|
|
245
248
|
const encoder = new TextEncoder();
|
|
246
|
-
const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, {
|
|
249
|
+
const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, {
|
|
250
|
+
props: ctx.props,
|
|
251
|
+
jurisdiction: options.jurisdiction
|
|
252
|
+
});
|
|
247
253
|
if (!await agent.getInitializeRequest()) return new Response(JSON.stringify({
|
|
248
254
|
jsonrpc: "2.0",
|
|
249
255
|
error: {
|
|
@@ -292,7 +298,7 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
292
298
|
Connection: "keep-alive",
|
|
293
299
|
"Content-Type": "text/event-stream",
|
|
294
300
|
"mcp-session-id": sessionId,
|
|
295
|
-
...corsHeaders(request, corsOptions)
|
|
301
|
+
...corsHeaders(request, options.corsOptions)
|
|
296
302
|
},
|
|
297
303
|
status: 200
|
|
298
304
|
});
|
|
@@ -307,9 +313,9 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
307
313
|
id: null
|
|
308
314
|
}), {
|
|
309
315
|
status: 400,
|
|
310
|
-
headers: corsHeaders(request, corsOptions)
|
|
316
|
+
headers: corsHeaders(request, options.corsOptions)
|
|
311
317
|
});
|
|
312
|
-
const agent = await getAgentByName(namespace, `streamable-http:${sessionId}
|
|
318
|
+
const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, { jurisdiction: options.jurisdiction });
|
|
313
319
|
if (!await agent.getInitializeRequest()) return new Response(JSON.stringify({
|
|
314
320
|
jsonrpc: "2.0",
|
|
315
321
|
error: {
|
|
@@ -319,12 +325,12 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
319
325
|
id: null
|
|
320
326
|
}), {
|
|
321
327
|
status: 404,
|
|
322
|
-
headers: corsHeaders(request, corsOptions)
|
|
328
|
+
headers: corsHeaders(request, options.corsOptions)
|
|
323
329
|
});
|
|
324
330
|
ctx.waitUntil(agent.destroy().catch(() => {}));
|
|
325
331
|
return new Response(null, {
|
|
326
332
|
status: 204,
|
|
327
|
-
headers: corsHeaders(request, corsOptions)
|
|
333
|
+
headers: corsHeaders(request, options.corsOptions)
|
|
328
334
|
});
|
|
329
335
|
}
|
|
330
336
|
}
|
|
@@ -339,7 +345,7 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
339
345
|
return new Response(body, { status: 404 });
|
|
340
346
|
};
|
|
341
347
|
};
|
|
342
|
-
const createLegacySseHandler = (basePath, namespace,
|
|
348
|
+
const createLegacySseHandler = (basePath, namespace, options = {}) => {
|
|
343
349
|
let pathname = basePath;
|
|
344
350
|
if (basePath === "/") pathname = "/*";
|
|
345
351
|
const basePattern = new URLPattern({ pathname });
|
|
@@ -356,7 +362,10 @@ const createLegacySseHandler = (basePath, namespace, corsOptions) => {
|
|
|
356
362
|
endpointUrl.searchParams.set("sessionId", sessionId);
|
|
357
363
|
const endpointMessage = `event: endpoint\ndata: ${endpointUrl.pathname + endpointUrl.search + endpointUrl.hash}\n\n`;
|
|
358
364
|
writer.write(encoder.encode(endpointMessage));
|
|
359
|
-
const agent = await getAgentByName(namespace, `sse:${sessionId}`, {
|
|
365
|
+
const agent = await getAgentByName(namespace, `sse:${sessionId}`, {
|
|
366
|
+
props: ctx.props,
|
|
367
|
+
jurisdiction: options.jurisdiction
|
|
368
|
+
});
|
|
360
369
|
const existingHeaders = {};
|
|
361
370
|
request.headers.forEach((value, key) => {
|
|
362
371
|
existingHeaders[key] = value;
|
|
@@ -408,7 +417,7 @@ const createLegacySseHandler = (basePath, namespace, corsOptions) => {
|
|
|
408
417
|
"Cache-Control": "no-cache",
|
|
409
418
|
Connection: "keep-alive",
|
|
410
419
|
"Content-Type": "text/event-stream",
|
|
411
|
-
...corsHeaders(request, corsOptions)
|
|
420
|
+
...corsHeaders(request, options.corsOptions)
|
|
412
421
|
} });
|
|
413
422
|
}
|
|
414
423
|
if (request.method === "POST" && messagePattern.test(url)) {
|
|
@@ -418,7 +427,10 @@ const createLegacySseHandler = (basePath, namespace, corsOptions) => {
|
|
|
418
427
|
if (!contentType.includes("application/json")) return new Response(`Unsupported content-type: ${contentType}`, { status: 400 });
|
|
419
428
|
const contentLength = Number.parseInt(request.headers.get("content-length") || "0", 10);
|
|
420
429
|
if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) return new Response(`Request body too large: ${contentLength} bytes`, { status: 400 });
|
|
421
|
-
const agent = await getAgentByName(namespace, `sse:${sessionId}`, {
|
|
430
|
+
const agent = await getAgentByName(namespace, `sse:${sessionId}`, {
|
|
431
|
+
props: ctx.props,
|
|
432
|
+
jurisdiction: options.jurisdiction
|
|
433
|
+
});
|
|
422
434
|
const messageBody = await request.json();
|
|
423
435
|
const error = await agent.onSSEMcpMessage(sessionId, messageBody);
|
|
424
436
|
if (error) return new Response(error.message, {
|
|
@@ -426,7 +438,7 @@ const createLegacySseHandler = (basePath, namespace, corsOptions) => {
|
|
|
426
438
|
"Cache-Control": "no-cache",
|
|
427
439
|
Connection: "keep-alive",
|
|
428
440
|
"Content-Type": "text/event-stream",
|
|
429
|
-
...corsHeaders(request, corsOptions)
|
|
441
|
+
...corsHeaders(request, options.corsOptions)
|
|
430
442
|
},
|
|
431
443
|
status: 400
|
|
432
444
|
});
|
|
@@ -435,7 +447,7 @@ const createLegacySseHandler = (basePath, namespace, corsOptions) => {
|
|
|
435
447
|
"Cache-Control": "no-cache",
|
|
436
448
|
Connection: "keep-alive",
|
|
437
449
|
"Content-Type": "text/event-stream",
|
|
438
|
-
...corsHeaders(request, corsOptions)
|
|
450
|
+
...corsHeaders(request, options.corsOptions)
|
|
439
451
|
},
|
|
440
452
|
status: 202
|
|
441
453
|
});
|
|
@@ -856,6 +868,10 @@ var WorkerTransport = class {
|
|
|
856
868
|
}
|
|
857
869
|
});
|
|
858
870
|
}
|
|
871
|
+
const requestInfo = {
|
|
872
|
+
headers: Object.fromEntries(request.headers.entries()),
|
|
873
|
+
url: request.url
|
|
874
|
+
};
|
|
859
875
|
const isInitializationRequest = messages.some(isInitializeRequest);
|
|
860
876
|
if (isInitializationRequest) {
|
|
861
877
|
if (this.initialized && this.sessionId !== void 0) return new Response(JSON.stringify({
|
|
@@ -903,7 +919,7 @@ var WorkerTransport = class {
|
|
|
903
919
|
if (versionError) return versionError;
|
|
904
920
|
}
|
|
905
921
|
if (!messages.some(isJSONRPCRequest)) {
|
|
906
|
-
for (const message of messages) this.onmessage?.(message);
|
|
922
|
+
for (const message of messages) this.onmessage?.(message, { requestInfo });
|
|
907
923
|
return new Response(null, {
|
|
908
924
|
status: 202,
|
|
909
925
|
headers: { ...this.getHeaders() }
|
|
@@ -918,7 +934,7 @@ var WorkerTransport = class {
|
|
|
918
934
|
}
|
|
919
935
|
});
|
|
920
936
|
for (const message of messages) if (isJSONRPCRequest(message)) this.requestToStreamMapping.set(message.id, streamId);
|
|
921
|
-
for (const message of messages) this.onmessage?.(message);
|
|
937
|
+
for (const message of messages) this.onmessage?.(message, { requestInfo });
|
|
922
938
|
});
|
|
923
939
|
const { readable, writable } = new TransformStream();
|
|
924
940
|
const writer = writable.getWriter();
|
|
@@ -939,7 +955,7 @@ var WorkerTransport = class {
|
|
|
939
955
|
}
|
|
940
956
|
});
|
|
941
957
|
for (const message of messages) if (isJSONRPCRequest(message)) this.requestToStreamMapping.set(message.id, streamId);
|
|
942
|
-
for (const message of messages) this.onmessage?.(message);
|
|
958
|
+
for (const message of messages) this.onmessage?.(message, { requestInfo });
|
|
943
959
|
return new Response(readable, { headers });
|
|
944
960
|
}
|
|
945
961
|
async handleDeleteRequest(request) {
|
|
@@ -1317,7 +1333,7 @@ var McpAgent = class McpAgent extends Agent {
|
|
|
1317
1333
|
/** Return a handler for the given path for this MCP.
|
|
1318
1334
|
* Defaults to Streamable HTTP transport.
|
|
1319
1335
|
*/
|
|
1320
|
-
static serve(path, { binding = "MCP_OBJECT", corsOptions, transport = "streamable-http" } = {}) {
|
|
1336
|
+
static serve(path, { binding = "MCP_OBJECT", corsOptions, transport = "streamable-http", jurisdiction } = {}) {
|
|
1321
1337
|
return { async fetch(request, env, ctx) {
|
|
1322
1338
|
const corsResponse = handleCORS(request, corsOptions);
|
|
1323
1339
|
if (corsResponse) return corsResponse;
|
|
@@ -1326,8 +1342,14 @@ var McpAgent = class McpAgent extends Agent {
|
|
|
1326
1342
|
if (!isDurableObjectNamespace(bindingValue)) throw new Error(`Invalid McpAgent binding for ${binding}. Make sure it's a Durable Object binding.`);
|
|
1327
1343
|
const namespace = bindingValue;
|
|
1328
1344
|
switch (transport) {
|
|
1329
|
-
case "streamable-http": return createStreamingHttpHandler(path, namespace,
|
|
1330
|
-
|
|
1345
|
+
case "streamable-http": return createStreamingHttpHandler(path, namespace, {
|
|
1346
|
+
corsOptions,
|
|
1347
|
+
jurisdiction
|
|
1348
|
+
})(request, ctx);
|
|
1349
|
+
case "sse": return createLegacySseHandler(path, namespace, {
|
|
1350
|
+
corsOptions,
|
|
1351
|
+
jurisdiction
|
|
1352
|
+
})(request, ctx);
|
|
1331
1353
|
default: return new Response("Invalid MCP transport mode. Only `streamable-http` or `sse` are allowed.", { status: 500 });
|
|
1332
1354
|
}
|
|
1333
1355
|
} };
|
package/dist/mcp/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["body","rawMessage: unknown","arrayMessage: unknown[]","messages: JSONRPCMessage[]","existingHeaders: Record<string, string>","event","authInfo: AuthInfo | undefined","requestInfo: RequestInfo","messages: JSONRPCMessage[]","standaloneConnection: Connection | undefined","eventId: string | undefined","eventId","messages: JSONRPCMessage[]","requestId: RequestId | undefined","authContext: McpAuthContext | undefined","rawPayload: string","parsedMessage: JSONRPCMessage","errorResult: ElicitResult"],"sources":["../../src/mcp/utils.ts","../../src/mcp/transport.ts","../../src/mcp/worker-transport.ts","../../src/mcp/auth-context.ts","../../src/mcp/handler.ts","../../src/mcp/index.ts"],"sourcesContent":["import {\n JSONRPCMessageSchema,\n type JSONRPCMessage,\n InitializeRequestSchema,\n isJSONRPCResponse,\n isJSONRPCNotification\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { McpAgent } from \".\";\nimport { getAgentByName } from \"..\";\nimport type { CORSOptions } from \"./types\";\nimport { MessageType } from \"../ai-types\";\n\n/**\n * Since we use WebSockets to bridge the client to the\n * MCP transport in the Agent, we use this header to signal\n * the method of the original request the user made, while\n * leaving the WS Upgrade request as GET.\n */\nexport const MCP_HTTP_METHOD_HEADER = \"cf-mcp-method\";\n\n/**\n * Since we use WebSockets to bridge the client to the\n * MCP transport in the Agent, we use this header to include\n * the original request body.\n */\nexport const MCP_MESSAGE_HEADER = \"cf-mcp-message\";\n\nconst MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024; // 4MB\n\nexport const createStreamingHttpHandler = (\n basePath: string,\n namespace: DurableObjectNamespace<McpAgent>,\n corsOptions?: CORSOptions\n) => {\n let pathname = basePath;\n if (basePath === \"/\") pathname = \"/*\";\n\n const basePattern = new URLPattern({ pathname });\n return async (request: Request, ctx: ExecutionContext) => {\n const url = new URL(request.url);\n if (basePattern.test(url)) {\n if (request.method === \"POST\") {\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 maybeInitializeRequest = messages.find(\n (msg) => InitializeRequestSchema.safeParse(msg).success\n );\n\n if (!!maybeInitializeRequest && 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 (!!maybeInitializeRequest && 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 (!maybeInitializeRequest && !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 // Get the agent and set props\n const agent = await getAgentByName(\n namespace,\n `streamable-http:${sessionId}`,\n { props: ctx.props as Record<string, unknown> | undefined }\n );\n const isInitialized = await agent.getInitializeRequest();\n\n if (maybeInitializeRequest) {\n await agent.setInitializeRequest(maybeInitializeRequest);\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 existingHeaders: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n\n const req = new Request(request.url, {\n headers: {\n ...existingHeaders,\n [MCP_HTTP_METHOD_HEADER]: \"POST\",\n [MCP_MESSAGE_HEADER]: Buffer.from(\n JSON.stringify(messages)\n ).toString(\"base64\"),\n Upgrade: \"websocket\"\n }\n });\n if (ctx.props) agent.updateProps(ctx.props as Record<string, unknown>);\n const response = await agent.fetch(req);\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 // 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 // We only forward events from the MCP server\n if (message.type !== MessageType.CF_MCP_AGENT_EVENT) {\n return;\n }\n\n // Send the message as an SSE event\n await writer.write(encoder.encode(message.event));\n\n // If we have received all the responses, close the connection\n if (message.close) {\n ws?.close();\n await writer.close().catch(() => {});\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 await writer.close().catch(() => {});\n }\n onError(error).catch(console.error);\n });\n\n // Handle WebSocket closure\n ws.addEventListener(\"close\", () => {\n async function onClose() {\n await writer.close().catch(() => {});\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 // 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 // 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 } else if (request.method === \"GET\") {\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 (!acceptHeader?.includes(\"text/event-stream\")) {\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Not Acceptable: Client must accept text/event-stream\"\n },\n id: null\n });\n return new Response(body, { status: 406 });\n }\n\n // Require sessionId\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (!sessionId)\n return new Response(\n 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 { status: 400 }\n );\n\n // Create SSE stream\n const { readable, writable } = new TransformStream();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n const agent = await getAgentByName(\n namespace,\n `streamable-http:${sessionId}`,\n { props: ctx.props as Record<string, unknown> | undefined }\n );\n const isInitialized = await agent.getInitializeRequest();\n if (!isInitialized) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32001, message: \"Session not found\" },\n id: null\n }),\n { status: 404 }\n );\n }\n\n const existingHeaders: Record<string, string> = {};\n request.headers.forEach((v, k) => {\n existingHeaders[k] = v;\n });\n\n if (ctx.props) agent.updateProps(ctx.props as Record<string, unknown>);\n const response = await agent.fetch(\n new Request(request.url, {\n headers: {\n ...existingHeaders,\n [MCP_HTTP_METHOD_HEADER]: \"GET\",\n Upgrade: \"websocket\"\n }\n })\n );\n\n const ws = response.webSocket;\n if (!ws) {\n await writer.close();\n return new Response(\"Failed to establish WS to DO\", {\n status: 500\n });\n }\n ws.accept();\n\n // Forward DO messages as SSE\n ws.addEventListener(\"message\", (event) => {\n try {\n async function onMessage(ev: MessageEvent) {\n const data =\n typeof ev.data === \"string\"\n ? ev.data\n : new TextDecoder().decode(ev.data);\n const message = JSON.parse(data);\n\n // We only forward events from the MCP server\n if (message.type !== MessageType.CF_MCP_AGENT_EVENT) {\n return;\n }\n await writer.write(encoder.encode(message.event));\n }\n onMessage(event).catch(console.error);\n } catch (e) {\n console.error(\"Error forwarding message to SSE:\", e);\n }\n });\n\n ws.addEventListener(\"error\", () => {\n writer.close().catch(() => {});\n });\n ws.addEventListener(\"close\", () => {\n writer.close().catch(() => {});\n });\n\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 } else if (request.method === \"DELETE\") {\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (!sessionId) {\n return new Response(\n 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 { status: 400, headers: corsHeaders(request, corsOptions) }\n );\n }\n const agent = await getAgentByName(\n namespace,\n `streamable-http:${sessionId}`\n );\n const isInitialized = await agent.getInitializeRequest();\n if (!isInitialized) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32001, message: \"Session not found\" },\n id: null\n }),\n { status: 404, headers: corsHeaders(request, corsOptions) }\n );\n }\n // .destroy() passes an uncatchable Error, so we make sure we first return\n // the response to the client.\n ctx.waitUntil(\n agent.destroy().catch(() => {\n /* This will always throw. We silently catch here */\n })\n );\n return new Response(null, {\n status: 204,\n headers: corsHeaders(request, corsOptions)\n });\n }\n }\n\n // Route not found\n const body = JSON.stringify({\n error: {\n code: -32000,\n message: \"Not found\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 404 });\n };\n};\n\nexport const createLegacySseHandler = (\n basePath: string,\n namespace: DurableObjectNamespace<McpAgent>,\n corsOptions?: CORSOptions\n) => {\n let pathname = basePath;\n if (basePath === \"/\") pathname = \"/*\";\n\n const basePattern = new URLPattern({ pathname });\n const messagePattern = new URLPattern({ pathname: `${basePath}/message` }); // SSE only\n return async (request: Request, ctx: ExecutionContext) => {\n const url = new URL(request.url);\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\") || 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(`${basePath}/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 agent = await getAgentByName(namespace, `sse:${sessionId}`, {\n props: ctx.props as Record<string, unknown> | undefined\n });\n\n // Connect to the Durable Object via WebSocket\n const existingHeaders: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n if (ctx.props) agent.updateProps(ctx.props as Record<string, unknown>);\n const response = await agent.fetch(\n new Request(request.url, {\n headers: {\n ...existingHeaders,\n Upgrade: \"websocket\"\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 ${basePath} 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(`Request body too large: ${contentLength} bytes`, {\n status: 400\n });\n }\n\n // Get the Durable Object\n const agent = await getAgentByName(namespace, `sse:${sessionId}`, {\n props: ctx.props as Record<string, unknown> | undefined\n });\n\n const messageBody = await request.json();\n const error = await agent.onSSEMcpMessage(sessionId, messageBody);\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// CORS helper functions\nexport function corsHeaders(_request: Request, corsOptions: CORSOptions = {}) {\n const origin = \"*\";\n return {\n \"Access-Control-Allow-Headers\":\n corsOptions.headers ||\n \"Content-Type, Accept, mcp-session-id, mcp-protocol-version\",\n \"Access-Control-Allow-Methods\":\n corsOptions.methods || \"GET, POST, DELETE, 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\nexport function 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\nexport function 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","import type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport {\n type MessageExtraInfo,\n type RequestInfo,\n isJSONRPCError,\n isJSONRPCRequest,\n isJSONRPCResponse,\n type JSONRPCMessage,\n JSONRPCMessageSchema,\n type RequestId\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { AuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\nimport { getCurrentAgent, type Connection } from \"..\";\nimport type { McpAgent } from \".\";\nimport { MessageType } from \"../ai-types\";\nimport { MCP_HTTP_METHOD_HEADER, MCP_MESSAGE_HEADER } from \"./utils\";\n\nexport class McpSSETransport implements Transport {\n sessionId?: string;\n // Set by the server in `server.connect(transport)`\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\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 }\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\nexport type StreamId = string;\nexport type EventId = string;\n\n// TODO: Implement this and make it opt-in?\n/**\n * Interface for resumability support via event storage\n */\nexport interface EventStore {\n /**\n * Stores an event for later retrieval\n * @param streamId ID of the stream the event belongs to\n * @param message The JSON-RPC message to store\n * @returns The generated event ID for the stored event\n */\n storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId>;\n\n replayEventsAfter(\n lastEventId: EventId,\n {\n send\n }: {\n send: (eventId: EventId, message: JSONRPCMessage) => Promise<void>;\n }\n ): Promise<StreamId>;\n}\n\n/**\n * Configuration options for StreamableHTTPServerTransport\n */\nexport interface StreamableHTTPServerTransportOptions {\n /**\n * Event store for resumability support\n * If provided, resumability will be enabled, allowing clients to reconnect and resume messages\n */\n eventStore?: EventStore;\n}\n\n/**\n * Adapted from: https://github.com/modelcontextprotocol/typescript-sdk/blob/main/src/client/streamableHttp.ts\n * - Validation and initialization are removed as they're handled in `McpAgent.serve()` handler.\n * - Replaces the Node-style `req`/`res` with Worker's `Request`.\n * - Writes events as WS messages that the Worker forwards to the client as SSE events.\n * - Replaces the in-memory maps that track requestID/stream by using `connection.setState()` and `agent.getConnections()`.\n *\n * Besides these points, the implementation is the same and should be updated to match the original as new features are added.\n */\nexport class StreamableHTTPServerTransport implements Transport {\n private _started = false;\n private _eventStore?: EventStore;\n\n // This is to keep track whether all messages from a single POST request have been answered.\n // I's fine that we don't persist this since it's only for backwards compatibility as clients\n // should no longer batch requests, per the spec.\n private _requestResponseMap: Map<RequestId, JSONRPCMessage> = new Map();\n\n sessionId: string;\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void;\n\n constructor(options: StreamableHTTPServerTransportOptions) {\n const { agent } = getCurrentAgent<McpAgent>();\n if (!agent)\n throw new Error(\"McpAgent was not found in Transport constructor\");\n\n // Initialization is handled in `McpAgent.serve()` and agents are addressed by sessionId,\n // so we'll always have this available.\n this.sessionId = agent.getSessionId();\n this._eventStore = options.eventStore;\n }\n\n /**\n * Starts the transport. This is required by the Transport interface but is a no-op\n * for the Streamable HTTP transport as connections are managed per-request.\n */\n async start(): Promise<void> {\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n /**\n * Handles GET requests for SSE stream\n */\n async handleGetRequest(req: Request): Promise<void> {\n // Get the WS connection so we can tag it as the standalone stream\n const { connection } = getCurrentAgent();\n if (!connection)\n throw new Error(\"Connection was not found in handleGetRequest\");\n\n // Handle resumability: check for Last-Event-ID header\n if (this._eventStore) {\n const lastEventId = req.headers.get(\"last-event-id\");\n if (lastEventId) {\n await this.replayEvents(lastEventId);\n return;\n }\n }\n\n connection.setState({\n _standaloneSse: true\n });\n }\n\n /**\n * Replays events that would have been sent after the specified event ID\n * Only used when resumability is enabled\n */\n private async replayEvents(lastEventId: string): Promise<void> {\n if (!this._eventStore) {\n return;\n }\n\n const { connection } = getCurrentAgent();\n if (!connection)\n throw new Error(\"Connection was not available in replayEvents\");\n\n try {\n await this._eventStore?.replayEventsAfter(lastEventId, {\n send: async (eventId: string, message: JSONRPCMessage) => {\n try {\n this.writeSSEEvent(connection, message, eventId);\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n });\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n\n /**\n * Writes an event to the SSE stream with proper formatting\n */\n private writeSSEEvent(\n connection: Connection,\n message: JSONRPCMessage,\n eventId?: string,\n close?: boolean\n ) {\n let eventData = \"event: message\\n\";\n // Include event ID if provided - this is important for resumability\n if (eventId) {\n eventData += `id: ${eventId}\\n`;\n }\n eventData += `data: ${JSON.stringify(message)}\\n\\n`;\n\n return connection.send(\n JSON.stringify({\n type: MessageType.CF_MCP_AGENT_EVENT,\n event: eventData,\n close\n })\n );\n }\n\n /**\n * Handles POST requests containing JSON-RPC messages\n */\n async handlePostRequest(\n req: Request & { auth?: AuthInfo },\n parsedBody: unknown\n ): Promise<void> {\n const authInfo: AuthInfo | undefined = req.auth;\n const requestInfo: RequestInfo = {\n headers: Object.fromEntries(req.headers.entries())\n };\n // Remove headers that are not part of the original request\n delete requestInfo.headers[MCP_HTTP_METHOD_HEADER];\n delete requestInfo.headers[MCP_MESSAGE_HEADER];\n delete requestInfo.headers.upgrade;\n\n const rawMessage = parsedBody;\n let messages: JSONRPCMessage[];\n\n // handle batch and single messages\n if (Array.isArray(rawMessage)) {\n messages = rawMessage.map((msg) => JSONRPCMessageSchema.parse(msg));\n } else {\n messages = [JSONRPCMessageSchema.parse(rawMessage)];\n }\n\n // check if it contains requests\n const hasRequests = messages.some(isJSONRPCRequest);\n\n if (!hasRequests) {\n // We process without sending anything\n for (const message of messages) {\n this.onmessage?.(message, { authInfo, requestInfo });\n }\n } else if (hasRequests) {\n const { connection } = getCurrentAgent();\n if (!connection)\n throw new Error(\"Connection was not found in handlePostRequest\");\n\n // We need to track by request ID to maintain the connection\n const requestIds = messages\n .filter(isJSONRPCRequest)\n .map((message) => message.id);\n\n connection.setState({\n requestIds\n });\n\n // handle each message\n for (const message of messages) {\n this.onmessage?.(message, { authInfo, requestInfo });\n }\n // The server SHOULD NOT close the SSE stream before sending all JSON-RPC responses\n // This will be handled by the send() method when responses are ready\n }\n }\n\n async close(): Promise<void> {\n // Close all SSE connections\n const { agent } = getCurrentAgent();\n if (!agent) throw new Error(\"Agent was not found in close\");\n\n for (const conn of agent.getConnections()) {\n conn.close(1000, \"Session closed\");\n }\n this.onclose?.();\n }\n\n async send(\n message: JSONRPCMessage,\n options?: { relatedRequestId?: RequestId }\n ): Promise<void> {\n const { agent } = getCurrentAgent();\n if (!agent) throw new Error(\"Agent was not found in send\");\n\n let requestId = options?.relatedRequestId;\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n // If the message is a response, use the request ID from the message\n requestId = message.id;\n }\n\n // Check if this message should be sent on the standalone SSE stream (no request ID)\n // Ignore notifications from tools (which have relatedRequestId set)\n // Those will be sent via dedicated response SSE streams\n if (requestId === undefined) {\n // For standalone SSE streams, we can only send requests and notifications\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n throw new Error(\n \"Cannot send a response on a standalone SSE stream unless resuming a previous client request\"\n );\n }\n\n let standaloneConnection: Connection | undefined;\n for (const conn of agent.getConnections<{ _standaloneSse?: boolean }>()) {\n if (conn.state?._standaloneSse) standaloneConnection = conn;\n }\n\n if (standaloneConnection === undefined) {\n // The spec says the server MAY send messages on the stream, so it's ok to discard if no stream\n return;\n }\n\n // Generate and store event ID if event store is provided\n let eventId: string | undefined;\n if (this._eventStore) {\n // Stores the event and gets the generated event ID\n eventId = await this._eventStore.storeEvent(\n standaloneConnection.id,\n message\n );\n }\n\n // Send the message to the standalone SSE stream\n this.writeSSEEvent(standaloneConnection, message, eventId);\n return;\n }\n\n // Get the response for this request\n const connection = Array.from(\n agent.getConnections<{ requestIds?: number[] }>()\n ).find((conn) => conn.state?.requestIds?.includes(requestId as number));\n if (!connection) {\n throw new Error(\n `No connection established for request ID: ${String(requestId)}`\n );\n }\n\n let eventId: string | undefined;\n\n if (this._eventStore) {\n eventId = await this._eventStore.storeEvent(connection.id, message);\n }\n\n let shouldClose = false;\n\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n this._requestResponseMap.set(requestId, message);\n const relatedIds = connection.state?.requestIds ?? [];\n // Check if we have responses for all requests using this connection\n shouldClose = relatedIds.every((id) => this._requestResponseMap.has(id));\n\n if (shouldClose) {\n // Clean up\n for (const id of relatedIds) {\n this._requestResponseMap.delete(id);\n }\n }\n }\n this.writeSSEEvent(connection, message, eventId, shouldClose);\n }\n}\n","/**\n * Based on @hono/mcp transport implementation (https://github.com/honojs/middleware/tree/main/packages/mcp)\n */\n\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport type {\n JSONRPCMessage,\n RequestId,\n InitializeRequest\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n isInitializeRequest,\n isJSONRPCError,\n isJSONRPCRequest,\n isJSONRPCResponse,\n JSONRPCMessageSchema\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { CORSOptions } from \"./types\";\n\n// MCP Protocol Version constants\nconst SUPPORTED_PROTOCOL_VERSIONS = [\"2025-03-26\", \"2025-06-18\"] as const;\nconst DEFAULT_PROTOCOL_VERSION = \"2025-03-26\"; // For backwards compatibility\nconst MCP_PROTOCOL_VERSION_HEADER = \"MCP-Protocol-Version\";\n\ntype ProtocolVersion = (typeof SUPPORTED_PROTOCOL_VERSIONS)[number];\n\ninterface StreamMapping {\n writer?: WritableStreamDefaultWriter<Uint8Array>;\n encoder?: TextEncoder;\n resolveJson?: (response: Response) => void;\n cleanup: () => void;\n}\n\nexport interface WorkerTransportOptions {\n sessionIdGenerator?: () => string;\n enableJsonResponse?: boolean;\n onsessioninitialized?: (sessionId: string) => void;\n corsOptions?: CORSOptions;\n}\n\nexport class WorkerTransport implements Transport {\n private started = false;\n private initialized = false;\n private sessionIdGenerator?: () => string;\n private enableJsonResponse = false;\n private onsessioninitialized?: (sessionId: string) => void;\n private standaloneSseStreamId = \"_GET_stream\";\n private streamMapping = new Map<string, StreamMapping>();\n private requestToStreamMapping = new Map<RequestId, string>();\n private requestResponseMap = new Map<RequestId, JSONRPCMessage>();\n private corsOptions?: CORSOptions;\n private protocolVersion?: ProtocolVersion;\n\n sessionId?: string;\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n\n constructor(options?: WorkerTransportOptions) {\n this.sessionIdGenerator = options?.sessionIdGenerator;\n this.enableJsonResponse = options?.enableJsonResponse ?? false;\n this.onsessioninitialized = options?.onsessioninitialized;\n this.corsOptions = options?.corsOptions;\n }\n\n async start(): Promise<void> {\n if (this.started) {\n throw new Error(\"Transport already started\");\n }\n this.started = true;\n }\n\n private validateProtocolVersion(request: Request): Response | undefined {\n const versionHeader = request.headers.get(MCP_PROTOCOL_VERSION_HEADER);\n\n if (!versionHeader) {\n if (\n !this.protocolVersion ||\n this.protocolVersion === DEFAULT_PROTOCOL_VERSION\n ) {\n return undefined;\n }\n // If we negotiated a different version, the client MUST send the header\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: `Bad Request: ${MCP_PROTOCOL_VERSION_HEADER} header is required`\n },\n id: null\n }),\n {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n if (\n !SUPPORTED_PROTOCOL_VERSIONS.includes(versionHeader as ProtocolVersion)\n ) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: `Bad Request: Unsupported ${MCP_PROTOCOL_VERSION_HEADER}: ${versionHeader}. Supported versions: ${SUPPORTED_PROTOCOL_VERSIONS.join(\", \")}`\n },\n id: null\n }),\n {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n // Check if it matches the negotiated version\n if (this.protocolVersion && versionHeader !== this.protocolVersion) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: `Bad Request: ${MCP_PROTOCOL_VERSION_HEADER} mismatch. Expected: ${this.protocolVersion}, Got: ${versionHeader}`\n },\n id: null\n }),\n {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n return undefined;\n }\n\n private getHeaders({ forPreflight }: { forPreflight?: boolean } = {}): Record<\n string,\n string\n > {\n const defaults: CORSOptions = {\n origin: \"*\",\n headers:\n \"Content-Type, Accept, Authorization, mcp-session-id, MCP-Protocol-Version\",\n methods: \"GET, POST, DELETE, OPTIONS\",\n exposeHeaders: \"mcp-session-id\",\n maxAge: 86400\n };\n\n const options = { ...defaults, ...this.corsOptions };\n\n // For OPTIONS preflight, return all CORS headers\n if (forPreflight) {\n return {\n \"Access-Control-Allow-Origin\": options.origin!,\n \"Access-Control-Allow-Headers\": options.headers!,\n \"Access-Control-Allow-Methods\": options.methods!,\n \"Access-Control-Max-Age\": options.maxAge!.toString()\n };\n }\n\n // For actual requests, only return origin and expose headers\n return {\n \"Access-Control-Allow-Origin\": options.origin!,\n \"Access-Control-Expose-Headers\": options.exposeHeaders!\n };\n }\n\n async handleRequest(\n request: Request,\n parsedBody?: unknown\n ): Promise<Response> {\n switch (request.method) {\n case \"OPTIONS\":\n return this.handleOptionsRequest(request);\n case \"GET\":\n return this.handleGetRequest(request);\n case \"POST\":\n return this.handlePostRequest(request, parsedBody);\n case \"DELETE\":\n return this.handleDeleteRequest(request);\n default:\n return this.handleUnsupportedRequest();\n }\n }\n\n private async handleGetRequest(request: Request): Promise<Response> {\n const acceptHeader = request.headers.get(\"Accept\");\n if (!acceptHeader?.includes(\"text/event-stream\")) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Not Acceptable: Client must accept text/event-stream\"\n },\n id: null\n }),\n {\n status: 406,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n const sessionError = this.validateSession(request);\n if (sessionError) {\n return sessionError;\n }\n\n // Validate protocol version on subsequent requests\n const versionError = this.validateProtocolVersion(request);\n if (versionError) {\n return versionError;\n }\n\n const streamId = this.standaloneSseStreamId;\n\n if (this.streamMapping.get(streamId) !== undefined) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Conflict: Only one SSE stream is allowed per session\"\n },\n id: null\n }),\n {\n status: 409,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n const headers = new Headers({\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n ...this.getHeaders()\n });\n\n if (this.sessionId !== undefined) {\n headers.set(\"mcp-session-id\", this.sessionId);\n }\n\n const keepAlive = setInterval(() => {\n try {\n writer.write(encoder.encode(\"event: ping\\ndata: \\n\\n\"));\n } catch {\n clearInterval(keepAlive);\n }\n }, 30000);\n\n this.streamMapping.set(streamId, {\n writer,\n encoder,\n cleanup: () => {\n clearInterval(keepAlive);\n this.streamMapping.delete(streamId);\n writer.close().catch(() => {});\n }\n });\n\n return new Response(readable, { headers });\n }\n\n private async handlePostRequest(\n request: Request,\n parsedBody?: unknown\n ): Promise<Response> {\n const acceptHeader = request.headers.get(\"Accept\");\n if (\n !acceptHeader?.includes(\"application/json\") ||\n !acceptHeader.includes(\"text/event-stream\")\n ) {\n return new Response(\n 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 {\n status: 406,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n const contentType = request.headers.get(\"Content-Type\");\n if (!contentType?.includes(\"application/json\")) {\n return new Response(\n 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 {\n status: 415,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n let rawMessage = parsedBody;\n if (rawMessage === undefined) {\n try {\n rawMessage = await request.json();\n } catch {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32700,\n message: \"Parse error: Invalid JSON\"\n },\n id: null\n }),\n {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n }\n\n let messages: JSONRPCMessage[];\n try {\n if (Array.isArray(rawMessage)) {\n messages = rawMessage.map((msg) => JSONRPCMessageSchema.parse(msg));\n } else {\n messages = [JSONRPCMessageSchema.parse(rawMessage)];\n }\n } catch {\n return new Response(\n 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 {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n const isInitializationRequest = messages.some(isInitializeRequest);\n\n if (isInitializationRequest) {\n if (this.initialized && this.sessionId !== undefined) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32600,\n message: \"Invalid Request: Server already initialized\"\n },\n id: null\n }),\n {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n if (messages.length > 1) {\n return new Response(\n 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 {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n // Capture protocol version from initialization request\n const initRequest = messages.find(isInitializeRequest) as\n | InitializeRequest\n | undefined;\n if (initRequest?.params) {\n const version = initRequest.params.protocolVersion;\n if (\n version &&\n SUPPORTED_PROTOCOL_VERSIONS.includes(version as ProtocolVersion)\n ) {\n this.protocolVersion = version as ProtocolVersion;\n } else {\n // Default to 2025-03-26 if not specified or unsupported\n this.protocolVersion = DEFAULT_PROTOCOL_VERSION;\n }\n }\n\n this.sessionId = this.sessionIdGenerator?.();\n this.initialized = true;\n\n if (this.sessionId && this.onsessioninitialized) {\n this.onsessioninitialized(this.sessionId);\n }\n }\n\n if (!isInitializationRequest) {\n const sessionError = this.validateSession(request);\n if (sessionError) {\n return sessionError;\n }\n\n // Validate protocol version on subsequent requests\n const versionError = this.validateProtocolVersion(request);\n if (versionError) {\n return versionError;\n }\n }\n\n const hasRequests = messages.some(isJSONRPCRequest);\n\n if (!hasRequests) {\n for (const message of messages) {\n this.onmessage?.(message);\n }\n return new Response(null, {\n status: 202,\n headers: { ...this.getHeaders() }\n });\n }\n\n const streamId = crypto.randomUUID();\n\n if (this.enableJsonResponse) {\n return new Promise<Response>((resolve) => {\n this.streamMapping.set(streamId, {\n resolveJson: resolve,\n cleanup: () => {\n this.streamMapping.delete(streamId);\n }\n });\n\n for (const message of messages) {\n if (isJSONRPCRequest(message)) {\n this.requestToStreamMapping.set(message.id, streamId);\n }\n }\n\n for (const message of messages) {\n this.onmessage?.(message);\n }\n });\n }\n\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n const headers = new Headers({\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n ...this.getHeaders()\n });\n\n if (this.sessionId !== undefined) {\n headers.set(\"mcp-session-id\", this.sessionId);\n }\n\n this.streamMapping.set(streamId, {\n writer,\n encoder,\n cleanup: () => {\n this.streamMapping.delete(streamId);\n writer.close().catch(() => {});\n }\n });\n\n for (const message of messages) {\n if (isJSONRPCRequest(message)) {\n this.requestToStreamMapping.set(message.id, streamId);\n }\n }\n\n for (const message of messages) {\n this.onmessage?.(message);\n }\n\n return new Response(readable, { headers });\n }\n\n private async handleDeleteRequest(request: Request): Promise<Response> {\n const sessionError = this.validateSession(request);\n if (sessionError) {\n return sessionError;\n }\n\n // Validate protocol version on subsequent requests\n const versionError = this.validateProtocolVersion(request);\n if (versionError) {\n return versionError;\n }\n\n await this.close();\n return new Response(null, {\n status: 200,\n headers: { ...this.getHeaders() }\n });\n }\n\n private handleOptionsRequest(_request: Request): Response {\n return new Response(null, {\n status: 200,\n headers: { ...this.getHeaders({ forPreflight: true }) }\n });\n }\n\n private handleUnsupportedRequest(): Response {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Method not allowed.\"\n },\n id: null\n }),\n {\n status: 405,\n headers: {\n Allow: \"GET, POST, DELETE, OPTIONS\",\n \"Content-Type\": \"application/json\"\n }\n }\n );\n }\n\n private validateSession(request: Request): Response | undefined {\n if (this.sessionIdGenerator === undefined) {\n return undefined;\n }\n\n if (!this.initialized) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Bad Request: Server not initialized\"\n },\n id: null\n }),\n {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n const sessionId = request.headers.get(\"mcp-session-id\");\n\n if (!sessionId) {\n return new Response(\n 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 {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n if (sessionId !== this.sessionId) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32001,\n message: \"Session not found\"\n },\n id: null\n }),\n {\n status: 404,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n return undefined;\n }\n\n async close(): Promise<void> {\n for (const { cleanup } of this.streamMapping.values()) {\n cleanup();\n }\n\n this.streamMapping.clear();\n this.requestResponseMap.clear();\n this.onclose?.();\n }\n\n async send(message: JSONRPCMessage): Promise<void> {\n let requestId: RequestId | undefined;\n\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n requestId = message.id;\n }\n\n if (requestId === undefined) {\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n throw new Error(\n \"Cannot send a response on a standalone SSE stream unless resuming a previous client request\"\n );\n }\n\n const standaloneSse = this.streamMapping.get(this.standaloneSseStreamId);\n if (standaloneSse === undefined) {\n return;\n }\n\n if (standaloneSse.writer && standaloneSse.encoder) {\n const data = `event: message\\ndata: ${JSON.stringify(message)}\\n\\n`;\n await standaloneSse.writer.write(standaloneSse.encoder.encode(data));\n }\n return;\n }\n\n const streamId = this.requestToStreamMapping.get(requestId);\n if (!streamId) {\n throw new Error(\n `No connection established for request ID: ${String(requestId)}`\n );\n }\n\n const response = this.streamMapping.get(streamId);\n if (!response) {\n throw new Error(\n `No connection established for request ID: ${String(requestId)}`\n );\n }\n\n if (!this.enableJsonResponse) {\n if (response.writer && response.encoder) {\n const data = `event: message\\ndata: ${JSON.stringify(message)}\\n\\n`;\n await response.writer.write(response.encoder.encode(data));\n }\n }\n\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n this.requestResponseMap.set(requestId, message);\n\n const relatedIds = Array.from(this.requestToStreamMapping.entries())\n .filter(([, sid]) => sid === streamId)\n .map(([id]) => id);\n\n const allResponsesReady = relatedIds.every((id) =>\n this.requestResponseMap.has(id)\n );\n\n if (allResponsesReady) {\n if (this.enableJsonResponse && response.resolveJson) {\n const responses = relatedIds.map(\n (id) => this.requestResponseMap.get(id)!\n );\n\n const headers = new Headers({\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n });\n\n if (this.sessionId !== undefined) {\n headers.set(\"mcp-session-id\", this.sessionId);\n }\n\n const body = responses.length === 1 ? responses[0] : responses;\n response.resolveJson(new Response(JSON.stringify(body), { headers }));\n } else {\n response.cleanup();\n }\n\n for (const id of relatedIds) {\n this.requestResponseMap.delete(id);\n this.requestToStreamMapping.delete(id);\n }\n }\n }\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport interface McpAuthContext {\n props: Record<string, unknown>;\n}\n\nconst authContextStorage = new AsyncLocalStorage<McpAuthContext>();\n\nexport function getMcpAuthContext(): McpAuthContext | undefined {\n return authContextStorage.getStore();\n}\n\nexport function runWithAuthContext<T>(context: McpAuthContext, fn: () => T): T {\n return authContextStorage.run(context, fn);\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport {\n WorkerTransport,\n type WorkerTransportOptions\n} from \"./worker-transport\";\nimport { runWithAuthContext, type McpAuthContext } from \"./auth-context\";\nimport type { CORSOptions } from \"./types\";\n\nexport interface CreateMcpHandlerOptions extends WorkerTransportOptions {\n /**\n * The route path that this MCP handler should respond to.\n * If specified, the handler will only process requests that match this route.\n * @default \"/mcp\"\n */\n route?: string;\n /**\n * CORS configuration options for handling cross-origin requests.\n * These options are passed to the WorkerTransport which handles adding\n * CORS headers to all responses.\n *\n * Default values are:\n * - origin: \"*\"\n * - headers: \"Content-Type, Accept, Authorization, mcp-session-id, MCP-Protocol-Version\"\n * - methods: \"GET, POST, DELETE, OPTIONS\"\n * - exposeHeaders: \"mcp-session-id\"\n * - maxAge: 86400\n *\n * Provided options will overwrite the defaults.\n */\n corsOptions?: CORSOptions;\n}\n\nexport type OAuthExecutionContext = ExecutionContext & {\n props?: Record<string, unknown>;\n};\n\nexport function createMcpHandler(\n server: McpServer | Server,\n options: CreateMcpHandlerOptions = {}\n): (\n request: Request,\n env: unknown,\n ctx: ExecutionContext\n) => Promise<Response> {\n const route = options.route ?? \"/mcp\";\n\n return async (\n request: Request,\n _env: unknown,\n ctx: ExecutionContext\n ): Promise<Response> => {\n // Check if the request path matches the configured route\n const url = new URL(request.url);\n if (route && url.pathname !== route) {\n return new Response(\"Not Found\", { status: 404 });\n }\n\n const oauthCtx = ctx as OAuthExecutionContext;\n const authContext: McpAuthContext | undefined = oauthCtx.props\n ? { props: oauthCtx.props }\n : undefined;\n\n const transport = new WorkerTransport(options);\n await server.connect(transport);\n\n const handleRequest = async () => {\n return await transport.handleRequest(request);\n };\n\n try {\n if (authContext) {\n return await runWithAuthContext(authContext, handleRequest);\n } else {\n return await handleRequest();\n }\n } catch (error) {\n console.error(\"MCP handler error:\", error);\n\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32603,\n message:\n error instanceof Error ? error.message : \"Internal server error\"\n },\n id: null\n }),\n { status: 500, headers: { \"Content-Type\": \"application/json\" } }\n );\n }\n };\n}\n\nlet didWarnAboutExperimentalCreateMcpHandler = false;\n\n/**\n * @deprecated This has been renamed to createMcpHandler, and experimental_createMcpHandler will be removed in the next major version\n */\nexport function experimental_createMcpHandler(\n server: McpServer | Server,\n options: CreateMcpHandlerOptions = {}\n): (\n request: Request,\n env: unknown,\n ctx: ExecutionContext\n) => Promise<Response> {\n if (!didWarnAboutExperimentalCreateMcpHandler) {\n didWarnAboutExperimentalCreateMcpHandler = true;\n console.warn(\n \"experimental_createMcpHandler is deprecated, use createMcpHandler instead. experimental_createMcpHandler will be removed in the next major version.\"\n );\n }\n return createMcpHandler(server, options);\n}\n","import 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 JSONRPCMessageSchema,\n isJSONRPCError,\n isJSONRPCResponse,\n type ElicitResult\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { Connection, ConnectionContext } from \"../\";\nimport { Agent } from \"../index\";\nimport type { BaseTransportType, MaybePromise, ServeOptions } from \"./types\";\nimport {\n createLegacySseHandler,\n createStreamingHttpHandler,\n handleCORS,\n isDurableObjectNamespace,\n MCP_HTTP_METHOD_HEADER,\n MCP_MESSAGE_HEADER\n} from \"./utils\";\nimport { McpSSETransport, StreamableHTTPServerTransport } from \"./transport\";\n\nexport abstract class McpAgent<\n Env = unknown,\n State = unknown,\n Props extends Record<string, unknown> = Record<string, unknown>\n> extends Agent<Env, State, Props> {\n private _transport?: Transport;\n props?: Props;\n\n abstract server: MaybePromise<McpServer | Server>;\n abstract init(): Promise<void>;\n\n /*\n * Helpers\n */\n\n async setInitializeRequest(initializeRequest: JSONRPCMessage) {\n await this.ctx.storage.put(\"initializeRequest\", initializeRequest);\n }\n\n async getInitializeRequest() {\n return this.ctx.storage.get<JSONRPCMessage>(\"initializeRequest\");\n }\n\n /** Read the transport type for this agent.\n * This relies on the naming scheme being `sse:${sessionId}`\n * or `streamable-http:${sessionId}`.\n */\n getTransportType(): BaseTransportType {\n const [t, ..._] = this.name.split(\":\");\n switch (t) {\n case \"sse\":\n return \"sse\";\n case \"streamable-http\":\n return \"streamable-http\";\n default:\n throw new Error(\n \"Invalid transport type. McpAgent must be addressed with a valid protocol.\"\n );\n }\n }\n\n /** Read the sessionId for this agent.\n * This relies on the naming scheme being `sse:${sessionId}`\n * or `streamable-http:${sessionId}`.\n */\n getSessionId(): string {\n const [_, sessionId] = this.name.split(\":\");\n if (!sessionId) {\n throw new Error(\n \"Invalid session id. McpAgent must be addressed with a valid session id.\"\n );\n }\n return sessionId;\n }\n\n /** Get the unique WebSocket. SSE transport only. */\n private getWebSocket() {\n const websockets = Array.from(this.getConnections());\n if (websockets.length === 0) {\n return null;\n }\n return websockets[0];\n }\n\n /** Returns a new transport matching the type of the Agent. */\n private initTransport() {\n switch (this.getTransportType()) {\n case \"sse\": {\n return new McpSSETransport(() => this.getWebSocket());\n }\n case \"streamable-http\": {\n return new StreamableHTTPServerTransport({});\n }\n }\n }\n\n /** Update and store the props */\n async updateProps(props?: Props) {\n await this.ctx.storage.put(\"props\", props ?? {});\n this.props = props;\n }\n\n async reinitializeServer() {\n // If the agent was previously initialized, we have to populate\n // the server again by sending the initialize request to make\n // client information available to the server.\n const initializeRequest = await this.getInitializeRequest();\n if (initializeRequest) {\n this._transport?.onmessage?.(initializeRequest);\n }\n }\n\n /*\n * Base Agent / Parykit Server overrides\n */\n\n /** Sets up the MCP transport and server every time the Agent is started.*/\n async onStart(props?: Props) {\n // If onStart was passed props, save them in storage\n if (props) await this.updateProps(props);\n this.props = await this.ctx.storage.get(\"props\");\n\n await this.init();\n const server = await this.server;\n // Connect to the MCP server\n this._transport = this.initTransport();\n await server.connect(this._transport);\n await this.reinitializeServer();\n }\n\n /** Validates new WebSocket connections. */\n async onConnect(\n conn: Connection,\n { request: req }: ConnectionContext\n ): Promise<void> {\n switch (this.getTransportType()) {\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 = Array.from(this.getConnections());\n if (websockets.length > 1) {\n conn.close(1008, \"Websocket already connected\");\n return;\n }\n break;\n }\n case \"streamable-http\":\n if (this._transport instanceof StreamableHTTPServerTransport) {\n switch (req.headers.get(MCP_HTTP_METHOD_HEADER)) {\n case \"POST\": {\n // This returns the response directly to the client\n const payloadHeader = req.headers.get(MCP_MESSAGE_HEADER);\n let rawPayload: string;\n\n if (!payloadHeader) {\n rawPayload = \"{}\";\n } else {\n try {\n rawPayload = Buffer.from(payloadHeader, \"base64\").toString(\n \"utf-8\"\n );\n } catch (_error) {\n throw new Error(\n \"Internal Server Error: Failed to decode MCP message header\"\n );\n }\n }\n\n const parsedBody = JSON.parse(rawPayload);\n this._transport?.handlePostRequest(req, parsedBody);\n break;\n }\n case \"GET\":\n this._transport?.handleGetRequest(req);\n break;\n }\n }\n }\n }\n\n /*\n * Transport ingress and routing\n */\n\n /** Handles MCP Messages for the legacy SSE transport. */\n async onSSEMcpMessage(\n _sessionId: string,\n messageBody: unknown\n ): Promise<Error | null> {\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.getTransportType() !== \"sse\") {\n return new Error(\"Internal Server Error: Expected SSE transport\");\n }\n\n try {\n let parsedMessage: JSONRPCMessage;\n try {\n parsedMessage = JSONRPCMessageSchema.parse(messageBody);\n } catch (error) {\n this._transport?.onerror?.(error as Error);\n throw error;\n }\n\n // Check if this is an elicitation response before passing to transport\n if (await this._handleElicitationResponse(parsedMessage)) {\n return null; // Message was handled by elicitation system\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 /** Elicit user input with a message and schema */\n async elicitInput(params: {\n message: string;\n requestedSchema: unknown;\n }): Promise<ElicitResult> {\n const requestId = `elicit_${Math.random().toString(36).substring(2, 11)}`;\n\n // Store pending request in durable storage\n await this.ctx.storage.put(`elicitation:${requestId}`, {\n message: params.message,\n requestedSchema: params.requestedSchema,\n timestamp: Date.now()\n });\n\n const elicitRequest = {\n jsonrpc: \"2.0\" as const,\n id: requestId,\n method: \"elicitation/create\",\n params: {\n message: params.message,\n requestedSchema: params.requestedSchema\n }\n };\n\n // Send through MCP transport\n if (this._transport) {\n await this._transport.send(elicitRequest);\n } else {\n const connections = this.getConnections();\n if (!connections || Array.from(connections).length === 0) {\n await this.ctx.storage.delete(`elicitation:${requestId}`);\n throw new Error(\"No active connections available for elicitation\");\n }\n\n const connectionList = Array.from(connections);\n for (const connection of connectionList) {\n try {\n connection.send(JSON.stringify(elicitRequest));\n } catch (error) {\n console.error(\"Failed to send elicitation request:\", error);\n }\n }\n }\n\n // Wait for response through MCP\n return this._waitForElicitationResponse(requestId);\n }\n\n /** Wait for elicitation response through storage polling */\n private async _waitForElicitationResponse(\n requestId: string\n ): Promise<ElicitResult> {\n const startTime = Date.now();\n const timeout = 60000; // 60 second timeout\n\n try {\n while (Date.now() - startTime < timeout) {\n // Check if response has been stored\n const response = await this.ctx.storage.get<ElicitResult>(\n `elicitation:response:${requestId}`\n );\n if (response) {\n // Immediately clean up both request and response\n await this.ctx.storage.delete(`elicitation:${requestId}`);\n await this.ctx.storage.delete(`elicitation:response:${requestId}`);\n return response;\n }\n\n // Sleep briefly before checking again\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n throw new Error(\"Elicitation request timed out\");\n } finally {\n // Always clean up on timeout or error\n await this.ctx.storage.delete(`elicitation:${requestId}`);\n await this.ctx.storage.delete(`elicitation:response:${requestId}`);\n }\n }\n\n /** Handle elicitation responses */\n private async _handleElicitationResponse(\n message: JSONRPCMessage\n ): Promise<boolean> {\n // Check if this is a response to an elicitation request\n if (isJSONRPCResponse(message) && message.result) {\n const requestId = message.id?.toString();\n if (!requestId || !requestId.startsWith(\"elicit_\")) return false;\n\n // Check if we have a pending request for this ID\n const pendingRequest = await this.ctx.storage.get(\n `elicitation:${requestId}`\n );\n if (!pendingRequest) return false;\n\n // Store the response in durable storage\n await this.ctx.storage.put(\n `elicitation:response:${requestId}`,\n message.result as ElicitResult\n );\n return true;\n }\n\n // Check if this is an error response to an elicitation request\n if (isJSONRPCError(message)) {\n const requestId = message.id?.toString();\n if (!requestId || !requestId.startsWith(\"elicit_\")) return false;\n\n // Check if we have a pending request for this ID\n const pendingRequest = await this.ctx.storage.get(\n `elicitation:${requestId}`\n );\n if (!pendingRequest) return false;\n\n // Store error response\n const errorResult: ElicitResult = {\n action: \"cancel\",\n content: {\n error: message.error.message || \"Elicitation request failed\"\n }\n };\n await this.ctx.storage.put(\n `elicitation:response:${requestId}`,\n errorResult\n );\n return true;\n }\n\n return false;\n }\n\n /** Return a handler for the given path for this MCP.\n * Defaults to Streamable HTTP transport.\n */\n static serve(\n path: string,\n {\n binding = \"MCP_OBJECT\",\n corsOptions,\n transport = \"streamable-http\"\n }: ServeOptions = {}\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 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 throw new Error(\n `Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`\n );\n }\n\n // Ensure that the binding is to a DurableObject\n if (!isDurableObjectNamespace(bindingValue)) {\n throw new Error(\n `Invalid McpAgent binding for ${binding}. Make sure it's a Durable Object binding.`\n );\n }\n\n const namespace =\n bindingValue satisfies DurableObjectNamespace<McpAgent>;\n\n switch (transport) {\n case \"streamable-http\": {\n // Streamable HTTP transport handling\n const handleStreamableHttp = createStreamingHttpHandler(\n path,\n namespace,\n corsOptions\n );\n return handleStreamableHttp(request, ctx);\n }\n case \"sse\": {\n // Legacy SSE transport handling\n const handleLegacySse = createLegacySseHandler(\n path,\n namespace,\n corsOptions\n );\n return handleLegacySse(request, ctx);\n }\n default:\n return new Response(\n \"Invalid MCP transport mode. Only `streamable-http` or `sse` are allowed.\",\n { status: 500 }\n );\n }\n }\n };\n }\n /**\n * Legacy api\n **/\n static mount(path: string, opts: Omit<ServeOptions, \"transport\"> = {}) {\n return McpAgent.serveSSE(path, opts);\n }\n\n static serveSSE(path: string, opts: Omit<ServeOptions, \"transport\"> = {}) {\n return McpAgent.serve(path, { ...opts, transport: \"sse\" });\n }\n}\n\nexport { SSEEdgeClientTransport } from \"./sse-edge\";\nexport { StreamableHTTPEdgeClientTransport } from \"./streamable-http-edge\";\n\nexport {\n ElicitRequestSchema,\n type ElicitRequest,\n type ElicitResult\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nexport type {\n MCPClientOAuthResult,\n MCPClientOAuthCallbackConfig\n} from \"./client\";\n\nexport {\n createMcpHandler,\n experimental_createMcpHandler,\n type CreateMcpHandlerOptions,\n type OAuthExecutionContext\n} from \"./handler\";\n\nexport { getMcpAuthContext, type McpAuthContext } from \"./auth-context\";\n\nexport {\n WorkerTransport,\n type WorkerTransportOptions\n} from \"./worker-transport\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["body","rawMessage: unknown","arrayMessage: unknown[]","messages: JSONRPCMessage[]","existingHeaders: Record<string, string>","event","authInfo: AuthInfo | undefined","requestInfo: RequestInfo","messages: JSONRPCMessage[]","standaloneConnection: Connection | undefined","eventId: string | undefined","eventId","messages: JSONRPCMessage[]","requestInfo: RequestInfo & { url?: string }","requestId: RequestId | undefined","authContext: McpAuthContext | undefined","rawPayload: string","parsedMessage: JSONRPCMessage","errorResult: ElicitResult"],"sources":["../../src/mcp/utils.ts","../../src/mcp/transport.ts","../../src/mcp/worker-transport.ts","../../src/mcp/auth-context.ts","../../src/mcp/handler.ts","../../src/mcp/index.ts"],"sourcesContent":["import {\n JSONRPCMessageSchema,\n type JSONRPCMessage,\n InitializeRequestSchema,\n isJSONRPCResponse,\n isJSONRPCNotification\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { McpAgent } from \".\";\nimport { getAgentByName } from \"..\";\nimport type { CORSOptions } from \"./types\";\nimport { MessageType } from \"../ai-types\";\n\n/**\n * Since we use WebSockets to bridge the client to the\n * MCP transport in the Agent, we use this header to signal\n * the method of the original request the user made, while\n * leaving the WS Upgrade request as GET.\n */\nexport const MCP_HTTP_METHOD_HEADER = \"cf-mcp-method\";\n\n/**\n * Since we use WebSockets to bridge the client to the\n * MCP transport in the Agent, we use this header to include\n * the original request body.\n */\nexport const MCP_MESSAGE_HEADER = \"cf-mcp-message\";\n\nconst MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024; // 4MB\n\nexport const createStreamingHttpHandler = (\n basePath: string,\n namespace: DurableObjectNamespace<McpAgent>,\n options: {\n corsOptions?: CORSOptions;\n jurisdiction?: DurableObjectJurisdiction;\n } = {}\n) => {\n let pathname = basePath;\n if (basePath === \"/\") pathname = \"/*\";\n\n const basePattern = new URLPattern({ pathname });\n return async (request: Request, ctx: ExecutionContext) => {\n const url = new URL(request.url);\n if (basePattern.test(url)) {\n if (request.method === \"POST\") {\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 maybeInitializeRequest = messages.find(\n (msg) => InitializeRequestSchema.safeParse(msg).success\n );\n\n if (!!maybeInitializeRequest && 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 (!!maybeInitializeRequest && 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 (!maybeInitializeRequest && !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 // Get the agent and set props\n const agent = await getAgentByName(\n namespace,\n `streamable-http:${sessionId}`,\n {\n props: ctx.props as Record<string, unknown> | undefined,\n jurisdiction: options.jurisdiction\n }\n );\n const isInitialized = await agent.getInitializeRequest();\n\n if (maybeInitializeRequest) {\n await agent.setInitializeRequest(maybeInitializeRequest);\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 existingHeaders: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n\n const req = new Request(request.url, {\n headers: {\n ...existingHeaders,\n [MCP_HTTP_METHOD_HEADER]: \"POST\",\n [MCP_MESSAGE_HEADER]: Buffer.from(\n JSON.stringify(messages)\n ).toString(\"base64\"),\n Upgrade: \"websocket\"\n }\n });\n if (ctx.props) agent.updateProps(ctx.props as Record<string, unknown>);\n const response = await agent.fetch(req);\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 // 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 // We only forward events from the MCP server\n if (message.type !== MessageType.CF_MCP_AGENT_EVENT) {\n return;\n }\n\n // Send the message as an SSE event\n await writer.write(encoder.encode(message.event));\n\n // If we have received all the responses, close the connection\n if (message.close) {\n ws?.close();\n await writer.close().catch(() => {});\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 await writer.close().catch(() => {});\n }\n onError(error).catch(console.error);\n });\n\n // Handle WebSocket closure\n ws.addEventListener(\"close\", () => {\n async function onClose() {\n await writer.close().catch(() => {});\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 // closing the websocket will also close the SSE connection\n ws.close();\n\n return new Response(null, {\n headers: corsHeaders(request, options.corsOptions),\n status: 202\n });\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, options.corsOptions)\n },\n status: 200\n });\n } else if (request.method === \"GET\") {\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 (!acceptHeader?.includes(\"text/event-stream\")) {\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Not Acceptable: Client must accept text/event-stream\"\n },\n id: null\n });\n return new Response(body, { status: 406 });\n }\n\n // Require sessionId\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (!sessionId)\n return new Response(\n 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 { status: 400 }\n );\n\n // Create SSE stream\n const { readable, writable } = new TransformStream();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n const agent = await getAgentByName(\n namespace,\n `streamable-http:${sessionId}`,\n {\n props: ctx.props as Record<string, unknown> | undefined,\n jurisdiction: options.jurisdiction\n }\n );\n const isInitialized = await agent.getInitializeRequest();\n if (!isInitialized) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32001, message: \"Session not found\" },\n id: null\n }),\n { status: 404 }\n );\n }\n\n const existingHeaders: Record<string, string> = {};\n request.headers.forEach((v, k) => {\n existingHeaders[k] = v;\n });\n\n if (ctx.props) agent.updateProps(ctx.props as Record<string, unknown>);\n const response = await agent.fetch(\n new Request(request.url, {\n headers: {\n ...existingHeaders,\n [MCP_HTTP_METHOD_HEADER]: \"GET\",\n Upgrade: \"websocket\"\n }\n })\n );\n\n const ws = response.webSocket;\n if (!ws) {\n await writer.close();\n return new Response(\"Failed to establish WS to DO\", {\n status: 500\n });\n }\n ws.accept();\n\n // Forward DO messages as SSE\n ws.addEventListener(\"message\", (event) => {\n try {\n async function onMessage(ev: MessageEvent) {\n const data =\n typeof ev.data === \"string\"\n ? ev.data\n : new TextDecoder().decode(ev.data);\n const message = JSON.parse(data);\n\n // We only forward events from the MCP server\n if (message.type !== MessageType.CF_MCP_AGENT_EVENT) {\n return;\n }\n await writer.write(encoder.encode(message.event));\n }\n onMessage(event).catch(console.error);\n } catch (e) {\n console.error(\"Error forwarding message to SSE:\", e);\n }\n });\n\n ws.addEventListener(\"error\", () => {\n writer.close().catch(() => {});\n });\n ws.addEventListener(\"close\", () => {\n writer.close().catch(() => {});\n });\n\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, options.corsOptions)\n },\n status: 200\n });\n } else if (request.method === \"DELETE\") {\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (!sessionId) {\n return new Response(\n 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 { status: 400, headers: corsHeaders(request, options.corsOptions) }\n );\n }\n const agent = await getAgentByName(\n namespace,\n `streamable-http:${sessionId}`,\n { jurisdiction: options.jurisdiction }\n );\n const isInitialized = await agent.getInitializeRequest();\n if (!isInitialized) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32001, message: \"Session not found\" },\n id: null\n }),\n { status: 404, headers: corsHeaders(request, options.corsOptions) }\n );\n }\n // .destroy() passes an uncatchable Error, so we make sure we first return\n // the response to the client.\n ctx.waitUntil(\n agent.destroy().catch(() => {\n /* This will always throw. We silently catch here */\n })\n );\n return new Response(null, {\n status: 204,\n headers: corsHeaders(request, options.corsOptions)\n });\n }\n }\n\n // Route not found\n const body = JSON.stringify({\n error: {\n code: -32000,\n message: \"Not found\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 404 });\n };\n};\n\nexport const createLegacySseHandler = (\n basePath: string,\n namespace: DurableObjectNamespace<McpAgent>,\n options: {\n corsOptions?: CORSOptions;\n jurisdiction?: DurableObjectJurisdiction;\n } = {}\n) => {\n let pathname = basePath;\n if (basePath === \"/\") pathname = \"/*\";\n\n const basePattern = new URLPattern({ pathname });\n const messagePattern = new URLPattern({ pathname: `${basePath}/message` }); // SSE only\n return async (request: Request, ctx: ExecutionContext) => {\n const url = new URL(request.url);\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\") || 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(`${basePath}/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 agent = await getAgentByName(namespace, `sse:${sessionId}`, {\n props: ctx.props as Record<string, unknown> | undefined,\n jurisdiction: options.jurisdiction\n });\n\n // Connect to the Durable Object via WebSocket\n const existingHeaders: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n if (ctx.props) agent.updateProps(ctx.props as Record<string, unknown>);\n const response = await agent.fetch(\n new Request(request.url, {\n headers: {\n ...existingHeaders,\n Upgrade: \"websocket\"\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, options.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 ${basePath} 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(`Request body too large: ${contentLength} bytes`, {\n status: 400\n });\n }\n\n // Get the Durable Object\n const agent = await getAgentByName(namespace, `sse:${sessionId}`, {\n props: ctx.props as Record<string, unknown> | undefined,\n jurisdiction: options.jurisdiction\n });\n\n const messageBody = await request.json();\n const error = await agent.onSSEMcpMessage(sessionId, messageBody);\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, options.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, options.corsOptions)\n },\n status: 202\n });\n }\n\n return new Response(\"Not Found\", { status: 404 });\n };\n};\n\n// CORS helper functions\nexport function corsHeaders(_request: Request, corsOptions: CORSOptions = {}) {\n const origin = \"*\";\n return {\n \"Access-Control-Allow-Headers\":\n corsOptions.headers ||\n \"Content-Type, Accept, mcp-session-id, mcp-protocol-version\",\n \"Access-Control-Allow-Methods\":\n corsOptions.methods || \"GET, POST, DELETE, 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\nexport function 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\nexport function 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","import type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport {\n type MessageExtraInfo,\n type RequestInfo,\n isJSONRPCError,\n isJSONRPCRequest,\n isJSONRPCResponse,\n type JSONRPCMessage,\n JSONRPCMessageSchema,\n type RequestId\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { AuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\nimport { getCurrentAgent, type Connection } from \"..\";\nimport type { McpAgent } from \".\";\nimport { MessageType } from \"../ai-types\";\nimport { MCP_HTTP_METHOD_HEADER, MCP_MESSAGE_HEADER } from \"./utils\";\n\nexport class McpSSETransport implements Transport {\n sessionId?: string;\n // Set by the server in `server.connect(transport)`\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\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 }\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\nexport type StreamId = string;\nexport type EventId = string;\n\n// TODO: Implement this and make it opt-in?\n/**\n * Interface for resumability support via event storage\n */\nexport interface EventStore {\n /**\n * Stores an event for later retrieval\n * @param streamId ID of the stream the event belongs to\n * @param message The JSON-RPC message to store\n * @returns The generated event ID for the stored event\n */\n storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId>;\n\n replayEventsAfter(\n lastEventId: EventId,\n {\n send\n }: {\n send: (eventId: EventId, message: JSONRPCMessage) => Promise<void>;\n }\n ): Promise<StreamId>;\n}\n\n/**\n * Configuration options for StreamableHTTPServerTransport\n */\nexport interface StreamableHTTPServerTransportOptions {\n /**\n * Event store for resumability support\n * If provided, resumability will be enabled, allowing clients to reconnect and resume messages\n */\n eventStore?: EventStore;\n}\n\n/**\n * Adapted from: https://github.com/modelcontextprotocol/typescript-sdk/blob/main/src/client/streamableHttp.ts\n * - Validation and initialization are removed as they're handled in `McpAgent.serve()` handler.\n * - Replaces the Node-style `req`/`res` with Worker's `Request`.\n * - Writes events as WS messages that the Worker forwards to the client as SSE events.\n * - Replaces the in-memory maps that track requestID/stream by using `connection.setState()` and `agent.getConnections()`.\n *\n * Besides these points, the implementation is the same and should be updated to match the original as new features are added.\n */\nexport class StreamableHTTPServerTransport implements Transport {\n private _started = false;\n private _eventStore?: EventStore;\n\n // This is to keep track whether all messages from a single POST request have been answered.\n // I's fine that we don't persist this since it's only for backwards compatibility as clients\n // should no longer batch requests, per the spec.\n private _requestResponseMap: Map<RequestId, JSONRPCMessage> = new Map();\n\n sessionId: string;\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void;\n\n constructor(options: StreamableHTTPServerTransportOptions) {\n const { agent } = getCurrentAgent<McpAgent>();\n if (!agent)\n throw new Error(\"McpAgent was not found in Transport constructor\");\n\n // Initialization is handled in `McpAgent.serve()` and agents are addressed by sessionId,\n // so we'll always have this available.\n this.sessionId = agent.getSessionId();\n this._eventStore = options.eventStore;\n }\n\n /**\n * Starts the transport. This is required by the Transport interface but is a no-op\n * for the Streamable HTTP transport as connections are managed per-request.\n */\n async start(): Promise<void> {\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n /**\n * Handles GET requests for SSE stream\n */\n async handleGetRequest(req: Request): Promise<void> {\n // Get the WS connection so we can tag it as the standalone stream\n const { connection } = getCurrentAgent();\n if (!connection)\n throw new Error(\"Connection was not found in handleGetRequest\");\n\n // Handle resumability: check for Last-Event-ID header\n if (this._eventStore) {\n const lastEventId = req.headers.get(\"last-event-id\");\n if (lastEventId) {\n await this.replayEvents(lastEventId);\n return;\n }\n }\n\n connection.setState({\n _standaloneSse: true\n });\n }\n\n /**\n * Replays events that would have been sent after the specified event ID\n * Only used when resumability is enabled\n */\n private async replayEvents(lastEventId: string): Promise<void> {\n if (!this._eventStore) {\n return;\n }\n\n const { connection } = getCurrentAgent();\n if (!connection)\n throw new Error(\"Connection was not available in replayEvents\");\n\n try {\n await this._eventStore?.replayEventsAfter(lastEventId, {\n send: async (eventId: string, message: JSONRPCMessage) => {\n try {\n this.writeSSEEvent(connection, message, eventId);\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n });\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n\n /**\n * Writes an event to the SSE stream with proper formatting\n */\n private writeSSEEvent(\n connection: Connection,\n message: JSONRPCMessage,\n eventId?: string,\n close?: boolean\n ) {\n let eventData = \"event: message\\n\";\n // Include event ID if provided - this is important for resumability\n if (eventId) {\n eventData += `id: ${eventId}\\n`;\n }\n eventData += `data: ${JSON.stringify(message)}\\n\\n`;\n\n return connection.send(\n JSON.stringify({\n type: MessageType.CF_MCP_AGENT_EVENT,\n event: eventData,\n close\n })\n );\n }\n\n /**\n * Handles POST requests containing JSON-RPC messages\n */\n async handlePostRequest(\n req: Request & { auth?: AuthInfo },\n parsedBody: unknown\n ): Promise<void> {\n const authInfo: AuthInfo | undefined = req.auth;\n const requestInfo: RequestInfo = {\n headers: Object.fromEntries(req.headers.entries())\n };\n // Remove headers that are not part of the original request\n delete requestInfo.headers[MCP_HTTP_METHOD_HEADER];\n delete requestInfo.headers[MCP_MESSAGE_HEADER];\n delete requestInfo.headers.upgrade;\n\n const rawMessage = parsedBody;\n let messages: JSONRPCMessage[];\n\n // handle batch and single messages\n if (Array.isArray(rawMessage)) {\n messages = rawMessage.map((msg) => JSONRPCMessageSchema.parse(msg));\n } else {\n messages = [JSONRPCMessageSchema.parse(rawMessage)];\n }\n\n // check if it contains requests\n const hasRequests = messages.some(isJSONRPCRequest);\n\n if (!hasRequests) {\n // We process without sending anything\n for (const message of messages) {\n this.onmessage?.(message, { authInfo, requestInfo });\n }\n } else if (hasRequests) {\n const { connection } = getCurrentAgent();\n if (!connection)\n throw new Error(\"Connection was not found in handlePostRequest\");\n\n // We need to track by request ID to maintain the connection\n const requestIds = messages\n .filter(isJSONRPCRequest)\n .map((message) => message.id);\n\n connection.setState({\n requestIds\n });\n\n // handle each message\n for (const message of messages) {\n this.onmessage?.(message, { authInfo, requestInfo });\n }\n // The server SHOULD NOT close the SSE stream before sending all JSON-RPC responses\n // This will be handled by the send() method when responses are ready\n }\n }\n\n async close(): Promise<void> {\n // Close all SSE connections\n const { agent } = getCurrentAgent();\n if (!agent) throw new Error(\"Agent was not found in close\");\n\n for (const conn of agent.getConnections()) {\n conn.close(1000, \"Session closed\");\n }\n this.onclose?.();\n }\n\n async send(\n message: JSONRPCMessage,\n options?: { relatedRequestId?: RequestId }\n ): Promise<void> {\n const { agent } = getCurrentAgent();\n if (!agent) throw new Error(\"Agent was not found in send\");\n\n let requestId = options?.relatedRequestId;\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n // If the message is a response, use the request ID from the message\n requestId = message.id;\n }\n\n // Check if this message should be sent on the standalone SSE stream (no request ID)\n // Ignore notifications from tools (which have relatedRequestId set)\n // Those will be sent via dedicated response SSE streams\n if (requestId === undefined) {\n // For standalone SSE streams, we can only send requests and notifications\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n throw new Error(\n \"Cannot send a response on a standalone SSE stream unless resuming a previous client request\"\n );\n }\n\n let standaloneConnection: Connection | undefined;\n for (const conn of agent.getConnections<{ _standaloneSse?: boolean }>()) {\n if (conn.state?._standaloneSse) standaloneConnection = conn;\n }\n\n if (standaloneConnection === undefined) {\n // The spec says the server MAY send messages on the stream, so it's ok to discard if no stream\n return;\n }\n\n // Generate and store event ID if event store is provided\n let eventId: string | undefined;\n if (this._eventStore) {\n // Stores the event and gets the generated event ID\n eventId = await this._eventStore.storeEvent(\n standaloneConnection.id,\n message\n );\n }\n\n // Send the message to the standalone SSE stream\n this.writeSSEEvent(standaloneConnection, message, eventId);\n return;\n }\n\n // Get the response for this request\n const connection = Array.from(\n agent.getConnections<{ requestIds?: number[] }>()\n ).find((conn) => conn.state?.requestIds?.includes(requestId as number));\n if (!connection) {\n throw new Error(\n `No connection established for request ID: ${String(requestId)}`\n );\n }\n\n let eventId: string | undefined;\n\n if (this._eventStore) {\n eventId = await this._eventStore.storeEvent(connection.id, message);\n }\n\n let shouldClose = false;\n\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n this._requestResponseMap.set(requestId, message);\n const relatedIds = connection.state?.requestIds ?? [];\n // Check if we have responses for all requests using this connection\n shouldClose = relatedIds.every((id) => this._requestResponseMap.has(id));\n\n if (shouldClose) {\n // Clean up\n for (const id of relatedIds) {\n this._requestResponseMap.delete(id);\n }\n }\n }\n this.writeSSEEvent(connection, message, eventId, shouldClose);\n }\n}\n","/**\n * Based on @hono/mcp transport implementation (https://github.com/honojs/middleware/tree/main/packages/mcp)\n */\n\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport type {\n JSONRPCMessage,\n RequestId,\n InitializeRequest,\n RequestInfo,\n MessageExtraInfo\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n isInitializeRequest,\n isJSONRPCError,\n isJSONRPCRequest,\n isJSONRPCResponse,\n JSONRPCMessageSchema\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { CORSOptions } from \"./types\";\n\n// MCP Protocol Version constants\nconst SUPPORTED_PROTOCOL_VERSIONS = [\"2025-03-26\", \"2025-06-18\"] as const;\nconst DEFAULT_PROTOCOL_VERSION = \"2025-03-26\"; // For backwards compatibility\nconst MCP_PROTOCOL_VERSION_HEADER = \"MCP-Protocol-Version\";\n\ntype ProtocolVersion = (typeof SUPPORTED_PROTOCOL_VERSIONS)[number];\n\ninterface StreamMapping {\n writer?: WritableStreamDefaultWriter<Uint8Array>;\n encoder?: TextEncoder;\n resolveJson?: (response: Response) => void;\n cleanup: () => void;\n}\n\nexport interface WorkerTransportOptions {\n sessionIdGenerator?: () => string;\n enableJsonResponse?: boolean;\n onsessioninitialized?: (sessionId: string) => void;\n corsOptions?: CORSOptions;\n}\n\nexport class WorkerTransport implements Transport {\n private started = false;\n private initialized = false;\n private sessionIdGenerator?: () => string;\n private enableJsonResponse = false;\n private onsessioninitialized?: (sessionId: string) => void;\n private standaloneSseStreamId = \"_GET_stream\";\n private streamMapping = new Map<string, StreamMapping>();\n private requestToStreamMapping = new Map<RequestId, string>();\n private requestResponseMap = new Map<RequestId, JSONRPCMessage>();\n private corsOptions?: CORSOptions;\n private protocolVersion?: ProtocolVersion;\n\n sessionId?: string;\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void;\n\n constructor(options?: WorkerTransportOptions) {\n this.sessionIdGenerator = options?.sessionIdGenerator;\n this.enableJsonResponse = options?.enableJsonResponse ?? false;\n this.onsessioninitialized = options?.onsessioninitialized;\n this.corsOptions = options?.corsOptions;\n }\n\n async start(): Promise<void> {\n if (this.started) {\n throw new Error(\"Transport already started\");\n }\n this.started = true;\n }\n\n private validateProtocolVersion(request: Request): Response | undefined {\n const versionHeader = request.headers.get(MCP_PROTOCOL_VERSION_HEADER);\n\n if (!versionHeader) {\n if (\n !this.protocolVersion ||\n this.protocolVersion === DEFAULT_PROTOCOL_VERSION\n ) {\n return undefined;\n }\n // If we negotiated a different version, the client MUST send the header\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: `Bad Request: ${MCP_PROTOCOL_VERSION_HEADER} header is required`\n },\n id: null\n }),\n {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n if (\n !SUPPORTED_PROTOCOL_VERSIONS.includes(versionHeader as ProtocolVersion)\n ) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: `Bad Request: Unsupported ${MCP_PROTOCOL_VERSION_HEADER}: ${versionHeader}. Supported versions: ${SUPPORTED_PROTOCOL_VERSIONS.join(\", \")}`\n },\n id: null\n }),\n {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n // Check if it matches the negotiated version\n if (this.protocolVersion && versionHeader !== this.protocolVersion) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: `Bad Request: ${MCP_PROTOCOL_VERSION_HEADER} mismatch. Expected: ${this.protocolVersion}, Got: ${versionHeader}`\n },\n id: null\n }),\n {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n return undefined;\n }\n\n private getHeaders({ forPreflight }: { forPreflight?: boolean } = {}): Record<\n string,\n string\n > {\n const defaults: CORSOptions = {\n origin: \"*\",\n headers:\n \"Content-Type, Accept, Authorization, mcp-session-id, MCP-Protocol-Version\",\n methods: \"GET, POST, DELETE, OPTIONS\",\n exposeHeaders: \"mcp-session-id\",\n maxAge: 86400\n };\n\n const options = { ...defaults, ...this.corsOptions };\n\n // For OPTIONS preflight, return all CORS headers\n if (forPreflight) {\n return {\n \"Access-Control-Allow-Origin\": options.origin!,\n \"Access-Control-Allow-Headers\": options.headers!,\n \"Access-Control-Allow-Methods\": options.methods!,\n \"Access-Control-Max-Age\": options.maxAge!.toString()\n };\n }\n\n // For actual requests, only return origin and expose headers\n return {\n \"Access-Control-Allow-Origin\": options.origin!,\n \"Access-Control-Expose-Headers\": options.exposeHeaders!\n };\n }\n\n async handleRequest(\n request: Request,\n parsedBody?: unknown\n ): Promise<Response> {\n switch (request.method) {\n case \"OPTIONS\":\n return this.handleOptionsRequest(request);\n case \"GET\":\n return this.handleGetRequest(request);\n case \"POST\":\n return this.handlePostRequest(request, parsedBody);\n case \"DELETE\":\n return this.handleDeleteRequest(request);\n default:\n return this.handleUnsupportedRequest();\n }\n }\n\n private async handleGetRequest(request: Request): Promise<Response> {\n const acceptHeader = request.headers.get(\"Accept\");\n if (!acceptHeader?.includes(\"text/event-stream\")) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Not Acceptable: Client must accept text/event-stream\"\n },\n id: null\n }),\n {\n status: 406,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n const sessionError = this.validateSession(request);\n if (sessionError) {\n return sessionError;\n }\n\n // Validate protocol version on subsequent requests\n const versionError = this.validateProtocolVersion(request);\n if (versionError) {\n return versionError;\n }\n\n const streamId = this.standaloneSseStreamId;\n\n if (this.streamMapping.get(streamId) !== undefined) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Conflict: Only one SSE stream is allowed per session\"\n },\n id: null\n }),\n {\n status: 409,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n const headers = new Headers({\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n ...this.getHeaders()\n });\n\n if (this.sessionId !== undefined) {\n headers.set(\"mcp-session-id\", this.sessionId);\n }\n\n const keepAlive = setInterval(() => {\n try {\n writer.write(encoder.encode(\"event: ping\\ndata: \\n\\n\"));\n } catch {\n clearInterval(keepAlive);\n }\n }, 30000);\n\n this.streamMapping.set(streamId, {\n writer,\n encoder,\n cleanup: () => {\n clearInterval(keepAlive);\n this.streamMapping.delete(streamId);\n writer.close().catch(() => {});\n }\n });\n\n return new Response(readable, { headers });\n }\n\n private async handlePostRequest(\n request: Request,\n parsedBody?: unknown\n ): Promise<Response> {\n const acceptHeader = request.headers.get(\"Accept\");\n if (\n !acceptHeader?.includes(\"application/json\") ||\n !acceptHeader.includes(\"text/event-stream\")\n ) {\n return new Response(\n 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 {\n status: 406,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n const contentType = request.headers.get(\"Content-Type\");\n if (!contentType?.includes(\"application/json\")) {\n return new Response(\n 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 {\n status: 415,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n let rawMessage = parsedBody;\n if (rawMessage === undefined) {\n try {\n rawMessage = await request.json();\n } catch {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32700,\n message: \"Parse error: Invalid JSON\"\n },\n id: null\n }),\n {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n }\n\n let messages: JSONRPCMessage[];\n try {\n if (Array.isArray(rawMessage)) {\n messages = rawMessage.map((msg) => JSONRPCMessageSchema.parse(msg));\n } else {\n messages = [JSONRPCMessageSchema.parse(rawMessage)];\n }\n } catch {\n return new Response(\n 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 {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n // TODO: push this upstream to the mcp sdk asap\n const requestInfo: RequestInfo & { url?: string } = {\n headers: Object.fromEntries(request.headers.entries()),\n url: request.url\n };\n\n const isInitializationRequest = messages.some(isInitializeRequest);\n\n if (isInitializationRequest) {\n if (this.initialized && this.sessionId !== undefined) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32600,\n message: \"Invalid Request: Server already initialized\"\n },\n id: null\n }),\n {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n if (messages.length > 1) {\n return new Response(\n 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 {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n // Capture protocol version from initialization request\n const initRequest = messages.find(isInitializeRequest) as\n | InitializeRequest\n | undefined;\n if (initRequest?.params) {\n const version = initRequest.params.protocolVersion;\n if (\n version &&\n SUPPORTED_PROTOCOL_VERSIONS.includes(version as ProtocolVersion)\n ) {\n this.protocolVersion = version as ProtocolVersion;\n } else {\n // Default to 2025-03-26 if not specified or unsupported\n this.protocolVersion = DEFAULT_PROTOCOL_VERSION;\n }\n }\n\n this.sessionId = this.sessionIdGenerator?.();\n this.initialized = true;\n\n if (this.sessionId && this.onsessioninitialized) {\n this.onsessioninitialized(this.sessionId);\n }\n }\n\n if (!isInitializationRequest) {\n const sessionError = this.validateSession(request);\n if (sessionError) {\n return sessionError;\n }\n\n // Validate protocol version on subsequent requests\n const versionError = this.validateProtocolVersion(request);\n if (versionError) {\n return versionError;\n }\n }\n\n const hasRequests = messages.some(isJSONRPCRequest);\n\n if (!hasRequests) {\n for (const message of messages) {\n this.onmessage?.(message, { requestInfo });\n }\n return new Response(null, {\n status: 202,\n headers: { ...this.getHeaders() }\n });\n }\n\n const streamId = crypto.randomUUID();\n\n if (this.enableJsonResponse) {\n return new Promise<Response>((resolve) => {\n this.streamMapping.set(streamId, {\n resolveJson: resolve,\n cleanup: () => {\n this.streamMapping.delete(streamId);\n }\n });\n\n for (const message of messages) {\n if (isJSONRPCRequest(message)) {\n this.requestToStreamMapping.set(message.id, streamId);\n }\n }\n\n for (const message of messages) {\n this.onmessage?.(message, { requestInfo });\n }\n });\n }\n\n const { readable, writable } = new TransformStream<Uint8Array>();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n const headers = new Headers({\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n ...this.getHeaders()\n });\n\n if (this.sessionId !== undefined) {\n headers.set(\"mcp-session-id\", this.sessionId);\n }\n\n this.streamMapping.set(streamId, {\n writer,\n encoder,\n cleanup: () => {\n this.streamMapping.delete(streamId);\n writer.close().catch(() => {});\n }\n });\n\n for (const message of messages) {\n if (isJSONRPCRequest(message)) {\n this.requestToStreamMapping.set(message.id, streamId);\n }\n }\n\n for (const message of messages) {\n this.onmessage?.(message, { requestInfo });\n }\n\n return new Response(readable, { headers });\n }\n\n private async handleDeleteRequest(request: Request): Promise<Response> {\n const sessionError = this.validateSession(request);\n if (sessionError) {\n return sessionError;\n }\n\n // Validate protocol version on subsequent requests\n const versionError = this.validateProtocolVersion(request);\n if (versionError) {\n return versionError;\n }\n\n await this.close();\n return new Response(null, {\n status: 200,\n headers: { ...this.getHeaders() }\n });\n }\n\n private handleOptionsRequest(_request: Request): Response {\n return new Response(null, {\n status: 200,\n headers: { ...this.getHeaders({ forPreflight: true }) }\n });\n }\n\n private handleUnsupportedRequest(): Response {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Method not allowed.\"\n },\n id: null\n }),\n {\n status: 405,\n headers: {\n Allow: \"GET, POST, DELETE, OPTIONS\",\n \"Content-Type\": \"application/json\"\n }\n }\n );\n }\n\n private validateSession(request: Request): Response | undefined {\n if (this.sessionIdGenerator === undefined) {\n return undefined;\n }\n\n if (!this.initialized) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Bad Request: Server not initialized\"\n },\n id: null\n }),\n {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n const sessionId = request.headers.get(\"mcp-session-id\");\n\n if (!sessionId) {\n return new Response(\n 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 {\n status: 400,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n if (sessionId !== this.sessionId) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32001,\n message: \"Session not found\"\n },\n id: null\n }),\n {\n status: 404,\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n }\n }\n );\n }\n\n return undefined;\n }\n\n async close(): Promise<void> {\n for (const { cleanup } of this.streamMapping.values()) {\n cleanup();\n }\n\n this.streamMapping.clear();\n this.requestResponseMap.clear();\n this.onclose?.();\n }\n\n async send(message: JSONRPCMessage): Promise<void> {\n let requestId: RequestId | undefined;\n\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n requestId = message.id;\n }\n\n if (requestId === undefined) {\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n throw new Error(\n \"Cannot send a response on a standalone SSE stream unless resuming a previous client request\"\n );\n }\n\n const standaloneSse = this.streamMapping.get(this.standaloneSseStreamId);\n if (standaloneSse === undefined) {\n return;\n }\n\n if (standaloneSse.writer && standaloneSse.encoder) {\n const data = `event: message\\ndata: ${JSON.stringify(message)}\\n\\n`;\n await standaloneSse.writer.write(standaloneSse.encoder.encode(data));\n }\n return;\n }\n\n const streamId = this.requestToStreamMapping.get(requestId);\n if (!streamId) {\n throw new Error(\n `No connection established for request ID: ${String(requestId)}`\n );\n }\n\n const response = this.streamMapping.get(streamId);\n if (!response) {\n throw new Error(\n `No connection established for request ID: ${String(requestId)}`\n );\n }\n\n if (!this.enableJsonResponse) {\n if (response.writer && response.encoder) {\n const data = `event: message\\ndata: ${JSON.stringify(message)}\\n\\n`;\n await response.writer.write(response.encoder.encode(data));\n }\n }\n\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n this.requestResponseMap.set(requestId, message);\n\n const relatedIds = Array.from(this.requestToStreamMapping.entries())\n .filter(([, sid]) => sid === streamId)\n .map(([id]) => id);\n\n const allResponsesReady = relatedIds.every((id) =>\n this.requestResponseMap.has(id)\n );\n\n if (allResponsesReady) {\n if (this.enableJsonResponse && response.resolveJson) {\n const responses = relatedIds.map(\n (id) => this.requestResponseMap.get(id)!\n );\n\n const headers = new Headers({\n \"Content-Type\": \"application/json\",\n ...this.getHeaders()\n });\n\n if (this.sessionId !== undefined) {\n headers.set(\"mcp-session-id\", this.sessionId);\n }\n\n const body = responses.length === 1 ? responses[0] : responses;\n response.resolveJson(new Response(JSON.stringify(body), { headers }));\n } else {\n response.cleanup();\n }\n\n for (const id of relatedIds) {\n this.requestResponseMap.delete(id);\n this.requestToStreamMapping.delete(id);\n }\n }\n }\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport interface McpAuthContext {\n props: Record<string, unknown>;\n}\n\nconst authContextStorage = new AsyncLocalStorage<McpAuthContext>();\n\nexport function getMcpAuthContext(): McpAuthContext | undefined {\n return authContextStorage.getStore();\n}\n\nexport function runWithAuthContext<T>(context: McpAuthContext, fn: () => T): T {\n return authContextStorage.run(context, fn);\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport {\n WorkerTransport,\n type WorkerTransportOptions\n} from \"./worker-transport\";\nimport { runWithAuthContext, type McpAuthContext } from \"./auth-context\";\nimport type { CORSOptions } from \"./types\";\n\nexport interface CreateMcpHandlerOptions extends WorkerTransportOptions {\n /**\n * The route path that this MCP handler should respond to.\n * If specified, the handler will only process requests that match this route.\n * @default \"/mcp\"\n */\n route?: string;\n /**\n * CORS configuration options for handling cross-origin requests.\n * These options are passed to the WorkerTransport which handles adding\n * CORS headers to all responses.\n *\n * Default values are:\n * - origin: \"*\"\n * - headers: \"Content-Type, Accept, Authorization, mcp-session-id, MCP-Protocol-Version\"\n * - methods: \"GET, POST, DELETE, OPTIONS\"\n * - exposeHeaders: \"mcp-session-id\"\n * - maxAge: 86400\n *\n * Provided options will overwrite the defaults.\n */\n corsOptions?: CORSOptions;\n}\n\nexport type OAuthExecutionContext = ExecutionContext & {\n props?: Record<string, unknown>;\n};\n\nexport function createMcpHandler(\n server: McpServer | Server,\n options: CreateMcpHandlerOptions = {}\n): (\n request: Request,\n env: unknown,\n ctx: ExecutionContext\n) => Promise<Response> {\n const route = options.route ?? \"/mcp\";\n\n return async (\n request: Request,\n _env: unknown,\n ctx: ExecutionContext\n ): Promise<Response> => {\n // Check if the request path matches the configured route\n const url = new URL(request.url);\n if (route && url.pathname !== route) {\n return new Response(\"Not Found\", { status: 404 });\n }\n\n const oauthCtx = ctx as OAuthExecutionContext;\n const authContext: McpAuthContext | undefined = oauthCtx.props\n ? { props: oauthCtx.props }\n : undefined;\n\n const transport = new WorkerTransport(options);\n await server.connect(transport);\n\n const handleRequest = async () => {\n return await transport.handleRequest(request);\n };\n\n try {\n if (authContext) {\n return await runWithAuthContext(authContext, handleRequest);\n } else {\n return await handleRequest();\n }\n } catch (error) {\n console.error(\"MCP handler error:\", error);\n\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32603,\n message:\n error instanceof Error ? error.message : \"Internal server error\"\n },\n id: null\n }),\n { status: 500, headers: { \"Content-Type\": \"application/json\" } }\n );\n }\n };\n}\n\nlet didWarnAboutExperimentalCreateMcpHandler = false;\n\n/**\n * @deprecated This has been renamed to createMcpHandler, and experimental_createMcpHandler will be removed in the next major version\n */\nexport function experimental_createMcpHandler(\n server: McpServer | Server,\n options: CreateMcpHandlerOptions = {}\n): (\n request: Request,\n env: unknown,\n ctx: ExecutionContext\n) => Promise<Response> {\n if (!didWarnAboutExperimentalCreateMcpHandler) {\n didWarnAboutExperimentalCreateMcpHandler = true;\n console.warn(\n \"experimental_createMcpHandler is deprecated, use createMcpHandler instead. experimental_createMcpHandler will be removed in the next major version.\"\n );\n }\n return createMcpHandler(server, options);\n}\n","import 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 JSONRPCMessageSchema,\n isJSONRPCError,\n isJSONRPCResponse,\n type ElicitResult\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { Connection, ConnectionContext } from \"../\";\nimport { Agent } from \"../index\";\nimport type { BaseTransportType, MaybePromise, ServeOptions } from \"./types\";\nimport {\n createLegacySseHandler,\n createStreamingHttpHandler,\n handleCORS,\n isDurableObjectNamespace,\n MCP_HTTP_METHOD_HEADER,\n MCP_MESSAGE_HEADER\n} from \"./utils\";\nimport { McpSSETransport, StreamableHTTPServerTransport } from \"./transport\";\n\nexport abstract class McpAgent<\n Env = unknown,\n State = unknown,\n Props extends Record<string, unknown> = Record<string, unknown>\n> extends Agent<Env, State, Props> {\n private _transport?: Transport;\n props?: Props;\n\n abstract server: MaybePromise<McpServer | Server>;\n abstract init(): Promise<void>;\n\n /*\n * Helpers\n */\n\n async setInitializeRequest(initializeRequest: JSONRPCMessage) {\n await this.ctx.storage.put(\"initializeRequest\", initializeRequest);\n }\n\n async getInitializeRequest() {\n return this.ctx.storage.get<JSONRPCMessage>(\"initializeRequest\");\n }\n\n /** Read the transport type for this agent.\n * This relies on the naming scheme being `sse:${sessionId}`\n * or `streamable-http:${sessionId}`.\n */\n getTransportType(): BaseTransportType {\n const [t, ..._] = this.name.split(\":\");\n switch (t) {\n case \"sse\":\n return \"sse\";\n case \"streamable-http\":\n return \"streamable-http\";\n default:\n throw new Error(\n \"Invalid transport type. McpAgent must be addressed with a valid protocol.\"\n );\n }\n }\n\n /** Read the sessionId for this agent.\n * This relies on the naming scheme being `sse:${sessionId}`\n * or `streamable-http:${sessionId}`.\n */\n getSessionId(): string {\n const [_, sessionId] = this.name.split(\":\");\n if (!sessionId) {\n throw new Error(\n \"Invalid session id. McpAgent must be addressed with a valid session id.\"\n );\n }\n return sessionId;\n }\n\n /** Get the unique WebSocket. SSE transport only. */\n private getWebSocket() {\n const websockets = Array.from(this.getConnections());\n if (websockets.length === 0) {\n return null;\n }\n return websockets[0];\n }\n\n /** Returns a new transport matching the type of the Agent. */\n private initTransport() {\n switch (this.getTransportType()) {\n case \"sse\": {\n return new McpSSETransport(() => this.getWebSocket());\n }\n case \"streamable-http\": {\n return new StreamableHTTPServerTransport({});\n }\n }\n }\n\n /** Update and store the props */\n async updateProps(props?: Props) {\n await this.ctx.storage.put(\"props\", props ?? {});\n this.props = props;\n }\n\n async reinitializeServer() {\n // If the agent was previously initialized, we have to populate\n // the server again by sending the initialize request to make\n // client information available to the server.\n const initializeRequest = await this.getInitializeRequest();\n if (initializeRequest) {\n this._transport?.onmessage?.(initializeRequest);\n }\n }\n\n /*\n * Base Agent / Parykit Server overrides\n */\n\n /** Sets up the MCP transport and server every time the Agent is started.*/\n async onStart(props?: Props) {\n // If onStart was passed props, save them in storage\n if (props) await this.updateProps(props);\n this.props = await this.ctx.storage.get(\"props\");\n\n await this.init();\n const server = await this.server;\n // Connect to the MCP server\n this._transport = this.initTransport();\n await server.connect(this._transport);\n await this.reinitializeServer();\n }\n\n /** Validates new WebSocket connections. */\n async onConnect(\n conn: Connection,\n { request: req }: ConnectionContext\n ): Promise<void> {\n switch (this.getTransportType()) {\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 = Array.from(this.getConnections());\n if (websockets.length > 1) {\n conn.close(1008, \"Websocket already connected\");\n return;\n }\n break;\n }\n case \"streamable-http\":\n if (this._transport instanceof StreamableHTTPServerTransport) {\n switch (req.headers.get(MCP_HTTP_METHOD_HEADER)) {\n case \"POST\": {\n // This returns the response directly to the client\n const payloadHeader = req.headers.get(MCP_MESSAGE_HEADER);\n let rawPayload: string;\n\n if (!payloadHeader) {\n rawPayload = \"{}\";\n } else {\n try {\n rawPayload = Buffer.from(payloadHeader, \"base64\").toString(\n \"utf-8\"\n );\n } catch (_error) {\n throw new Error(\n \"Internal Server Error: Failed to decode MCP message header\"\n );\n }\n }\n\n const parsedBody = JSON.parse(rawPayload);\n this._transport?.handlePostRequest(req, parsedBody);\n break;\n }\n case \"GET\":\n this._transport?.handleGetRequest(req);\n break;\n }\n }\n }\n }\n\n /*\n * Transport ingress and routing\n */\n\n /** Handles MCP Messages for the legacy SSE transport. */\n async onSSEMcpMessage(\n _sessionId: string,\n messageBody: unknown\n ): Promise<Error | null> {\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.getTransportType() !== \"sse\") {\n return new Error(\"Internal Server Error: Expected SSE transport\");\n }\n\n try {\n let parsedMessage: JSONRPCMessage;\n try {\n parsedMessage = JSONRPCMessageSchema.parse(messageBody);\n } catch (error) {\n this._transport?.onerror?.(error as Error);\n throw error;\n }\n\n // Check if this is an elicitation response before passing to transport\n if (await this._handleElicitationResponse(parsedMessage)) {\n return null; // Message was handled by elicitation system\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 /** Elicit user input with a message and schema */\n async elicitInput(params: {\n message: string;\n requestedSchema: unknown;\n }): Promise<ElicitResult> {\n const requestId = `elicit_${Math.random().toString(36).substring(2, 11)}`;\n\n // Store pending request in durable storage\n await this.ctx.storage.put(`elicitation:${requestId}`, {\n message: params.message,\n requestedSchema: params.requestedSchema,\n timestamp: Date.now()\n });\n\n const elicitRequest = {\n jsonrpc: \"2.0\" as const,\n id: requestId,\n method: \"elicitation/create\",\n params: {\n message: params.message,\n requestedSchema: params.requestedSchema\n }\n };\n\n // Send through MCP transport\n if (this._transport) {\n await this._transport.send(elicitRequest);\n } else {\n const connections = this.getConnections();\n if (!connections || Array.from(connections).length === 0) {\n await this.ctx.storage.delete(`elicitation:${requestId}`);\n throw new Error(\"No active connections available for elicitation\");\n }\n\n const connectionList = Array.from(connections);\n for (const connection of connectionList) {\n try {\n connection.send(JSON.stringify(elicitRequest));\n } catch (error) {\n console.error(\"Failed to send elicitation request:\", error);\n }\n }\n }\n\n // Wait for response through MCP\n return this._waitForElicitationResponse(requestId);\n }\n\n /** Wait for elicitation response through storage polling */\n private async _waitForElicitationResponse(\n requestId: string\n ): Promise<ElicitResult> {\n const startTime = Date.now();\n const timeout = 60000; // 60 second timeout\n\n try {\n while (Date.now() - startTime < timeout) {\n // Check if response has been stored\n const response = await this.ctx.storage.get<ElicitResult>(\n `elicitation:response:${requestId}`\n );\n if (response) {\n // Immediately clean up both request and response\n await this.ctx.storage.delete(`elicitation:${requestId}`);\n await this.ctx.storage.delete(`elicitation:response:${requestId}`);\n return response;\n }\n\n // Sleep briefly before checking again\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n throw new Error(\"Elicitation request timed out\");\n } finally {\n // Always clean up on timeout or error\n await this.ctx.storage.delete(`elicitation:${requestId}`);\n await this.ctx.storage.delete(`elicitation:response:${requestId}`);\n }\n }\n\n /** Handle elicitation responses */\n private async _handleElicitationResponse(\n message: JSONRPCMessage\n ): Promise<boolean> {\n // Check if this is a response to an elicitation request\n if (isJSONRPCResponse(message) && message.result) {\n const requestId = message.id?.toString();\n if (!requestId || !requestId.startsWith(\"elicit_\")) return false;\n\n // Check if we have a pending request for this ID\n const pendingRequest = await this.ctx.storage.get(\n `elicitation:${requestId}`\n );\n if (!pendingRequest) return false;\n\n // Store the response in durable storage\n await this.ctx.storage.put(\n `elicitation:response:${requestId}`,\n message.result as ElicitResult\n );\n return true;\n }\n\n // Check if this is an error response to an elicitation request\n if (isJSONRPCError(message)) {\n const requestId = message.id?.toString();\n if (!requestId || !requestId.startsWith(\"elicit_\")) return false;\n\n // Check if we have a pending request for this ID\n const pendingRequest = await this.ctx.storage.get(\n `elicitation:${requestId}`\n );\n if (!pendingRequest) return false;\n\n // Store error response\n const errorResult: ElicitResult = {\n action: \"cancel\",\n content: {\n error: message.error.message || \"Elicitation request failed\"\n }\n };\n await this.ctx.storage.put(\n `elicitation:response:${requestId}`,\n errorResult\n );\n return true;\n }\n\n return false;\n }\n\n /** Return a handler for the given path for this MCP.\n * Defaults to Streamable HTTP transport.\n */\n static serve(\n path: string,\n {\n binding = \"MCP_OBJECT\",\n corsOptions,\n transport = \"streamable-http\",\n jurisdiction\n }: ServeOptions = {}\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 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 throw new Error(\n `Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`\n );\n }\n\n // Ensure that the binding is to a DurableObject\n if (!isDurableObjectNamespace(bindingValue)) {\n throw new Error(\n `Invalid McpAgent binding for ${binding}. Make sure it's a Durable Object binding.`\n );\n }\n\n const namespace =\n bindingValue satisfies DurableObjectNamespace<McpAgent>;\n\n switch (transport) {\n case \"streamable-http\": {\n // Streamable HTTP transport handling\n const handleStreamableHttp = createStreamingHttpHandler(\n path,\n namespace,\n { corsOptions, jurisdiction }\n );\n return handleStreamableHttp(request, ctx);\n }\n case \"sse\": {\n // Legacy SSE transport handling\n const handleLegacySse = createLegacySseHandler(path, namespace, {\n corsOptions,\n jurisdiction\n });\n return handleLegacySse(request, ctx);\n }\n default:\n return new Response(\n \"Invalid MCP transport mode. Only `streamable-http` or `sse` are allowed.\",\n { status: 500 }\n );\n }\n }\n };\n }\n /**\n * Legacy api\n **/\n static mount(path: string, opts: Omit<ServeOptions, \"transport\"> = {}) {\n return McpAgent.serveSSE(path, opts);\n }\n\n static serveSSE(path: string, opts: Omit<ServeOptions, \"transport\"> = {}) {\n return McpAgent.serve(path, { ...opts, transport: \"sse\" });\n }\n}\n\nexport { SSEEdgeClientTransport } from \"./sse-edge\";\nexport { StreamableHTTPEdgeClientTransport } from \"./streamable-http-edge\";\n\nexport {\n ElicitRequestSchema,\n type ElicitRequest,\n type ElicitResult\n} from \"@modelcontextprotocol/sdk/types.js\";\n\nexport type {\n MCPClientOAuthResult,\n MCPClientOAuthCallbackConfig\n} from \"./client\";\n\nexport {\n createMcpHandler,\n experimental_createMcpHandler,\n type CreateMcpHandlerOptions,\n type OAuthExecutionContext\n} from \"./handler\";\n\nexport { getMcpAuthContext, type McpAuthContext } from \"./auth-context\";\n\nexport {\n WorkerTransport,\n type WorkerTransportOptions\n} from \"./worker-transport\";\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { m as MCPServersState, t as Agent } from "./index-
|
|
1
|
+
import { m as MCPServersState, t as Agent } from "./index-DFqsR7mb.js";
|
|
2
2
|
import { n as RPCMethod, t as Method } from "./serializable-CymX8ovI.js";
|
|
3
3
|
import { i as StreamOptions } from "./client-CbWe9FBd.js";
|
|
4
4
|
import { PartySocket } from "partysocket";
|
|
@@ -112,4 +112,4 @@ declare function useAgent<
|
|
|
112
112
|
};
|
|
113
113
|
//#endregion
|
|
114
114
|
export { useAgent as n, UseAgentOptions as t };
|
|
115
|
-
//# sourceMappingURL=react-
|
|
115
|
+
//# sourceMappingURL=react-NCPvtyCY.d.ts.map
|
package/dist/react.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import "./client-
|
|
1
|
+
import "./client-Csp_m13H.js";
|
|
2
2
|
import "./mcp-Dw5vDrY8.js";
|
|
3
3
|
import "./do-oauth-client-provider-DGc5pP0l.js";
|
|
4
4
|
import "./index-DhJCaDWd.js";
|
|
5
5
|
import "./ai-types-D5YoPrBZ.js";
|
|
6
|
-
import "./index-
|
|
6
|
+
import "./index-DFqsR7mb.js";
|
|
7
7
|
import "./serializable-CymX8ovI.js";
|
|
8
8
|
import "./client-CbWe9FBd.js";
|
|
9
|
-
import { n as useAgent, t as UseAgentOptions } from "./react-
|
|
9
|
+
import { n as useAgent, t as UseAgentOptions } from "./react-NCPvtyCY.js";
|
|
10
10
|
export { UseAgentOptions, useAgent };
|
package/package.json
CHANGED