agents 0.0.0-ccbea72 → 0.0.0-cccbd0f
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/README.md +5 -3
- package/dist/ai-chat-agent.d.ts +86 -13
- package/dist/ai-chat-agent.js +340 -74
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/{ai-chat-v5-migration-DBHGW4Hv.js → ai-chat-v5-migration-BSiGZmYU.js} +1 -1
- package/dist/{ai-chat-v5-migration-DBHGW4Hv.js.map → ai-chat-v5-migration-BSiGZmYU.js.map} +1 -1
- package/dist/ai-chat-v5-migration.js +1 -1
- package/dist/ai-react.d.ts +14 -9
- package/dist/ai-react.js +164 -29
- package/dist/ai-react.js.map +1 -1
- package/dist/{ai-types-D5YoPrBZ.d.ts → ai-types-81H_-Uxh.d.ts} +15 -7
- package/dist/{ai-types-B3aQaFv3.js → ai-types-CrMqkwc_.js} +5 -1
- package/dist/ai-types-CrMqkwc_.js.map +1 -0
- package/dist/ai-types.d.ts +1 -1
- package/dist/ai-types.js +1 -1
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +27 -0
- package/dist/cli.js.map +1 -0
- package/dist/{client-BfiZ3HQd.js → client-B3SR12TQ.js} +2 -2
- package/dist/{client-BfiZ3HQd.js.map → client-B3SR12TQ.js.map} +1 -1
- package/dist/{client-CbWe9FBd.d.ts → client-BAQA84dr.d.ts} +2 -2
- package/dist/{client-9Ld2_lnt.js → client-BZ-xTxF5.js} +239 -124
- package/dist/client-BZ-xTxF5.js.map +1 -0
- package/dist/client-ctTw3KHG.d.ts +1440 -0
- package/dist/client.d.ts +2 -2
- package/dist/client.js +2 -2
- package/dist/codemode/ai.js +5 -5
- package/dist/{do-oauth-client-provider-CswoD5Lu.js → do-oauth-client-provider-Cs9QpXYp.js} +2 -2
- package/dist/do-oauth-client-provider-Cs9QpXYp.js.map +1 -0
- package/dist/do-oauth-client-provider-UhQDpDb8.d.ts +134 -0
- package/dist/{index-DhJCaDWd.d.ts → index-BUle9RiP.d.ts} +2 -2
- package/dist/{index-D6iosdF4.d.ts → index-D2dnUH0r.d.ts} +40 -22
- package/dist/index.d.ts +6 -6
- package/dist/index.js +5 -5
- package/dist/mcp/client.d.ts +4 -4
- package/dist/mcp/client.js +2 -1
- package/dist/mcp/do-oauth-client-provider.d.ts +1 -1
- package/dist/mcp/do-oauth-client-provider.js +1 -1
- package/dist/mcp/index.d.ts +88 -24
- package/dist/mcp/index.js +293 -81
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/x402.js +10 -6
- package/dist/mcp/x402.js.map +1 -1
- package/dist/{mcp-Dw5vDrY8.d.ts → mcp-BwPscEiF.d.ts} +1 -1
- package/dist/observability/index.d.ts +2 -2
- package/dist/observability/index.js +5 -5
- package/dist/{react-YzfC33jB.d.ts → react-B_ENAdCe.d.ts} +33 -35
- package/dist/react.d.ts +9 -9
- package/dist/react.js +2 -2
- package/dist/react.js.map +1 -1
- package/dist/{serializable-CymX8ovI.d.ts → serializable-faDkMCai.d.ts} +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/{src-Dz0H9hSU.js → src-C6rC6ZpH.js} +188 -140
- package/dist/src-C6rC6ZpH.js.map +1 -0
- package/package.json +53 -38
- package/dist/ai-types-B3aQaFv3.js.map +0 -1
- package/dist/client-9Ld2_lnt.js.map +0 -1
- package/dist/client-BmMRlvlM.d.ts +0 -5313
- package/dist/do-oauth-client-provider-CswoD5Lu.js.map +0 -1
- package/dist/do-oauth-client-provider-DGc5pP0l.d.ts +0 -55
- package/dist/src-Dz0H9hSU.js.map +0 -1
package/dist/mcp/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { t as MessageType } from "../ai-types-
|
|
2
|
-
import "../client-
|
|
3
|
-
import
|
|
4
|
-
import "../do-oauth-client-provider-
|
|
5
|
-
import { c as getCurrentAgent, s as getAgentByName, t as Agent } from "../src-
|
|
1
|
+
import { t as MessageType } from "../ai-types-CrMqkwc_.js";
|
|
2
|
+
import "../client-B3SR12TQ.js";
|
|
3
|
+
import "../client-BZ-xTxF5.js";
|
|
4
|
+
import "../do-oauth-client-provider-Cs9QpXYp.js";
|
|
5
|
+
import { c as getCurrentAgent, s as getAgentByName, t as Agent } from "../src-C6rC6ZpH.js";
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
|
+
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
8
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
7
9
|
import { ElicitRequestSchema, InitializeRequestSchema, JSONRPCMessageSchema, isInitializeRequest, isJSONRPCError, isJSONRPCNotification, isJSONRPCRequest, isJSONRPCResponse } from "@modelcontextprotocol/sdk/types.js";
|
|
8
10
|
|
|
9
11
|
//#region src/mcp/utils.ts
|
|
@@ -21,7 +23,7 @@ const MCP_HTTP_METHOD_HEADER = "cf-mcp-method";
|
|
|
21
23
|
*/
|
|
22
24
|
const MCP_MESSAGE_HEADER = "cf-mcp-message";
|
|
23
25
|
const MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
|
|
24
|
-
const createStreamingHttpHandler = (basePath, namespace,
|
|
26
|
+
const createStreamingHttpHandler = (basePath, namespace, options = {}) => {
|
|
25
27
|
let pathname = basePath;
|
|
26
28
|
if (basePath === "/") pathname = "/*";
|
|
27
29
|
const basePattern = new URLPattern({ pathname });
|
|
@@ -130,7 +132,10 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
130
132
|
return new Response(body$1, { status: 400 });
|
|
131
133
|
}
|
|
132
134
|
sessionId = sessionId ?? namespace.newUniqueId().toString();
|
|
133
|
-
const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, {
|
|
135
|
+
const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, {
|
|
136
|
+
props: ctx.props,
|
|
137
|
+
jurisdiction: options.jurisdiction
|
|
138
|
+
});
|
|
134
139
|
const isInitialized = await agent.getInitializeRequest();
|
|
135
140
|
if (maybeInitializeRequest) await agent.setInitializeRequest(maybeInitializeRequest);
|
|
136
141
|
else if (!isInitialized) {
|
|
@@ -205,7 +210,7 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
205
210
|
if (messages.every((msg) => isJSONRPCNotification(msg) || isJSONRPCResponse(msg))) {
|
|
206
211
|
ws.close();
|
|
207
212
|
return new Response(null, {
|
|
208
|
-
headers: corsHeaders(request, corsOptions),
|
|
213
|
+
headers: corsHeaders(request, options.corsOptions),
|
|
209
214
|
status: 202
|
|
210
215
|
});
|
|
211
216
|
}
|
|
@@ -215,7 +220,7 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
215
220
|
Connection: "keep-alive",
|
|
216
221
|
"Content-Type": "text/event-stream",
|
|
217
222
|
"mcp-session-id": sessionId,
|
|
218
|
-
...corsHeaders(request, corsOptions)
|
|
223
|
+
...corsHeaders(request, options.corsOptions)
|
|
219
224
|
},
|
|
220
225
|
status: 200
|
|
221
226
|
});
|
|
@@ -243,7 +248,10 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
243
248
|
const { readable, writable } = new TransformStream();
|
|
244
249
|
const writer = writable.getWriter();
|
|
245
250
|
const encoder = new TextEncoder();
|
|
246
|
-
const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, {
|
|
251
|
+
const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, {
|
|
252
|
+
props: ctx.props,
|
|
253
|
+
jurisdiction: options.jurisdiction
|
|
254
|
+
});
|
|
247
255
|
if (!await agent.getInitializeRequest()) return new Response(JSON.stringify({
|
|
248
256
|
jsonrpc: "2.0",
|
|
249
257
|
error: {
|
|
@@ -292,7 +300,7 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
292
300
|
Connection: "keep-alive",
|
|
293
301
|
"Content-Type": "text/event-stream",
|
|
294
302
|
"mcp-session-id": sessionId,
|
|
295
|
-
...corsHeaders(request, corsOptions)
|
|
303
|
+
...corsHeaders(request, options.corsOptions)
|
|
296
304
|
},
|
|
297
305
|
status: 200
|
|
298
306
|
});
|
|
@@ -307,9 +315,9 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
307
315
|
id: null
|
|
308
316
|
}), {
|
|
309
317
|
status: 400,
|
|
310
|
-
headers: corsHeaders(request, corsOptions)
|
|
318
|
+
headers: corsHeaders(request, options.corsOptions)
|
|
311
319
|
});
|
|
312
|
-
const agent = await getAgentByName(namespace, `streamable-http:${sessionId}
|
|
320
|
+
const agent = await getAgentByName(namespace, `streamable-http:${sessionId}`, { jurisdiction: options.jurisdiction });
|
|
313
321
|
if (!await agent.getInitializeRequest()) return new Response(JSON.stringify({
|
|
314
322
|
jsonrpc: "2.0",
|
|
315
323
|
error: {
|
|
@@ -319,12 +327,12 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
319
327
|
id: null
|
|
320
328
|
}), {
|
|
321
329
|
status: 404,
|
|
322
|
-
headers: corsHeaders(request, corsOptions)
|
|
330
|
+
headers: corsHeaders(request, options.corsOptions)
|
|
323
331
|
});
|
|
324
332
|
ctx.waitUntil(agent.destroy().catch(() => {}));
|
|
325
333
|
return new Response(null, {
|
|
326
334
|
status: 204,
|
|
327
|
-
headers: corsHeaders(request, corsOptions)
|
|
335
|
+
headers: corsHeaders(request, options.corsOptions)
|
|
328
336
|
});
|
|
329
337
|
}
|
|
330
338
|
}
|
|
@@ -339,7 +347,7 @@ const createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
|
|
|
339
347
|
return new Response(body, { status: 404 });
|
|
340
348
|
};
|
|
341
349
|
};
|
|
342
|
-
const createLegacySseHandler = (basePath, namespace,
|
|
350
|
+
const createLegacySseHandler = (basePath, namespace, options = {}) => {
|
|
343
351
|
let pathname = basePath;
|
|
344
352
|
if (basePath === "/") pathname = "/*";
|
|
345
353
|
const basePattern = new URLPattern({ pathname });
|
|
@@ -356,7 +364,10 @@ const createLegacySseHandler = (basePath, namespace, corsOptions) => {
|
|
|
356
364
|
endpointUrl.searchParams.set("sessionId", sessionId);
|
|
357
365
|
const endpointMessage = `event: endpoint\ndata: ${endpointUrl.pathname + endpointUrl.search + endpointUrl.hash}\n\n`;
|
|
358
366
|
writer.write(encoder.encode(endpointMessage));
|
|
359
|
-
const agent = await getAgentByName(namespace, `sse:${sessionId}`, {
|
|
367
|
+
const agent = await getAgentByName(namespace, `sse:${sessionId}`, {
|
|
368
|
+
props: ctx.props,
|
|
369
|
+
jurisdiction: options.jurisdiction
|
|
370
|
+
});
|
|
360
371
|
const existingHeaders = {};
|
|
361
372
|
request.headers.forEach((value, key) => {
|
|
362
373
|
existingHeaders[key] = value;
|
|
@@ -408,7 +419,7 @@ const createLegacySseHandler = (basePath, namespace, corsOptions) => {
|
|
|
408
419
|
"Cache-Control": "no-cache",
|
|
409
420
|
Connection: "keep-alive",
|
|
410
421
|
"Content-Type": "text/event-stream",
|
|
411
|
-
...corsHeaders(request, corsOptions)
|
|
422
|
+
...corsHeaders(request, options.corsOptions)
|
|
412
423
|
} });
|
|
413
424
|
}
|
|
414
425
|
if (request.method === "POST" && messagePattern.test(url)) {
|
|
@@ -418,15 +429,19 @@ const createLegacySseHandler = (basePath, namespace, corsOptions) => {
|
|
|
418
429
|
if (!contentType.includes("application/json")) return new Response(`Unsupported content-type: ${contentType}`, { status: 400 });
|
|
419
430
|
const contentLength = Number.parseInt(request.headers.get("content-length") || "0", 10);
|
|
420
431
|
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}`, {
|
|
432
|
+
const agent = await getAgentByName(namespace, `sse:${sessionId}`, {
|
|
433
|
+
props: ctx.props,
|
|
434
|
+
jurisdiction: options.jurisdiction
|
|
435
|
+
});
|
|
422
436
|
const messageBody = await request.json();
|
|
423
|
-
const
|
|
437
|
+
const extraInfo = { requestInfo: { headers: Object.fromEntries(request.headers.entries()) } };
|
|
438
|
+
const error = await agent.onSSEMcpMessage(sessionId, messageBody, extraInfo);
|
|
424
439
|
if (error) return new Response(error.message, {
|
|
425
440
|
headers: {
|
|
426
441
|
"Cache-Control": "no-cache",
|
|
427
442
|
Connection: "keep-alive",
|
|
428
443
|
"Content-Type": "text/event-stream",
|
|
429
|
-
...corsHeaders(request, corsOptions)
|
|
444
|
+
...corsHeaders(request, options.corsOptions)
|
|
430
445
|
},
|
|
431
446
|
status: 400
|
|
432
447
|
});
|
|
@@ -435,7 +450,7 @@ const createLegacySseHandler = (basePath, namespace, corsOptions) => {
|
|
|
435
450
|
"Cache-Control": "no-cache",
|
|
436
451
|
Connection: "keep-alive",
|
|
437
452
|
"Content-Type": "text/event-stream",
|
|
438
|
-
...corsHeaders(request, corsOptions)
|
|
453
|
+
...corsHeaders(request, options.corsOptions)
|
|
439
454
|
},
|
|
440
455
|
status: 202
|
|
441
456
|
});
|
|
@@ -464,9 +479,12 @@ function isDurableObjectNamespace(namespace) {
|
|
|
464
479
|
//#endregion
|
|
465
480
|
//#region src/mcp/transport.ts
|
|
466
481
|
var McpSSETransport = class {
|
|
467
|
-
constructor(
|
|
482
|
+
constructor() {
|
|
468
483
|
this._started = false;
|
|
469
|
-
|
|
484
|
+
const { agent } = getCurrentAgent();
|
|
485
|
+
if (!agent) throw new Error("McpAgent was not found in Transport constructor");
|
|
486
|
+
this.sessionId = agent.getSessionId();
|
|
487
|
+
this._getWebSocket = () => agent.getWebSocket();
|
|
470
488
|
}
|
|
471
489
|
async start() {
|
|
472
490
|
if (this._started) throw new Error("Transport already started");
|
|
@@ -625,8 +643,43 @@ var StreamableHTTPServerTransport = class {
|
|
|
625
643
|
}
|
|
626
644
|
};
|
|
627
645
|
|
|
646
|
+
//#endregion
|
|
647
|
+
//#region src/mcp/client-transports.ts
|
|
648
|
+
/**
|
|
649
|
+
* Deprecated transport wrappers
|
|
650
|
+
*/
|
|
651
|
+
let didWarnAboutSSEEdgeClientTransport = false;
|
|
652
|
+
/**
|
|
653
|
+
* @deprecated Use SSEClientTransport from @modelcontextprotocol/sdk/client/sse.js instead. This alias will be removed in the next major version.
|
|
654
|
+
*/
|
|
655
|
+
var SSEEdgeClientTransport = class extends SSEClientTransport {
|
|
656
|
+
constructor(url, options) {
|
|
657
|
+
super(url, options);
|
|
658
|
+
if (!didWarnAboutSSEEdgeClientTransport) {
|
|
659
|
+
didWarnAboutSSEEdgeClientTransport = true;
|
|
660
|
+
console.warn("SSEEdgeClientTransport is deprecated. Use SSEClientTransport from @modelcontextprotocol/sdk/client/sse.js instead. SSEEdgeClientTransport will be removed in the next major version.");
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
let didWarnAboutStreamableHTTPEdgeClientTransport = false;
|
|
665
|
+
/**
|
|
666
|
+
* @deprecated Use StreamableHTTPClientTransport from @modelcontextprotocol/sdk/client/streamableHttp.js instead. This alias will be removed in the next major version.
|
|
667
|
+
*/
|
|
668
|
+
var StreamableHTTPEdgeClientTransport = class extends StreamableHTTPClientTransport {
|
|
669
|
+
constructor(url, options) {
|
|
670
|
+
super(url, options);
|
|
671
|
+
if (!didWarnAboutStreamableHTTPEdgeClientTransport) {
|
|
672
|
+
didWarnAboutStreamableHTTPEdgeClientTransport = true;
|
|
673
|
+
console.warn("StreamableHTTPEdgeClientTransport is deprecated. Use StreamableHTTPClientTransport from @modelcontextprotocol/sdk/client/streamableHttp.js instead. StreamableHTTPEdgeClientTransport will be removed in the next major version.");
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
};
|
|
677
|
+
|
|
628
678
|
//#endregion
|
|
629
679
|
//#region src/mcp/worker-transport.ts
|
|
680
|
+
const SUPPORTED_PROTOCOL_VERSIONS = ["2025-03-26", "2025-06-18"];
|
|
681
|
+
const DEFAULT_PROTOCOL_VERSION = "2025-03-26";
|
|
682
|
+
const MCP_PROTOCOL_VERSION_HEADER = "MCP-Protocol-Version";
|
|
630
683
|
var WorkerTransport = class {
|
|
631
684
|
constructor(options) {
|
|
632
685
|
this.started = false;
|
|
@@ -636,15 +689,113 @@ var WorkerTransport = class {
|
|
|
636
689
|
this.streamMapping = /* @__PURE__ */ new Map();
|
|
637
690
|
this.requestToStreamMapping = /* @__PURE__ */ new Map();
|
|
638
691
|
this.requestResponseMap = /* @__PURE__ */ new Map();
|
|
692
|
+
this.stateRestored = false;
|
|
639
693
|
this.sessionIdGenerator = options?.sessionIdGenerator;
|
|
640
694
|
this.enableJsonResponse = options?.enableJsonResponse ?? false;
|
|
641
695
|
this.onsessioninitialized = options?.onsessioninitialized;
|
|
696
|
+
this.corsOptions = options?.corsOptions;
|
|
697
|
+
this.storage = options?.storage;
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Restore transport state from persistent storage.
|
|
701
|
+
* This is automatically called on start.
|
|
702
|
+
*/
|
|
703
|
+
async restoreState() {
|
|
704
|
+
if (!this.storage || this.stateRestored) return;
|
|
705
|
+
const state = await Promise.resolve(this.storage.get());
|
|
706
|
+
if (state) {
|
|
707
|
+
this.sessionId = state.sessionId;
|
|
708
|
+
this.initialized = state.initialized;
|
|
709
|
+
this.protocolVersion = state.protocolVersion;
|
|
710
|
+
}
|
|
711
|
+
this.stateRestored = true;
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Persist current transport state to storage.
|
|
715
|
+
*/
|
|
716
|
+
async saveState() {
|
|
717
|
+
if (!this.storage) return;
|
|
718
|
+
const state = {
|
|
719
|
+
sessionId: this.sessionId,
|
|
720
|
+
initialized: this.initialized,
|
|
721
|
+
protocolVersion: this.protocolVersion
|
|
722
|
+
};
|
|
723
|
+
await Promise.resolve(this.storage.set(state));
|
|
642
724
|
}
|
|
643
725
|
async start() {
|
|
644
726
|
if (this.started) throw new Error("Transport already started");
|
|
645
727
|
this.started = true;
|
|
646
728
|
}
|
|
729
|
+
validateProtocolVersion(request) {
|
|
730
|
+
const versionHeader = request.headers.get(MCP_PROTOCOL_VERSION_HEADER);
|
|
731
|
+
if (!versionHeader) {
|
|
732
|
+
if (!this.protocolVersion || this.protocolVersion === DEFAULT_PROTOCOL_VERSION) return;
|
|
733
|
+
return new Response(JSON.stringify({
|
|
734
|
+
jsonrpc: "2.0",
|
|
735
|
+
error: {
|
|
736
|
+
code: -32e3,
|
|
737
|
+
message: `Bad Request: ${MCP_PROTOCOL_VERSION_HEADER} header is required`
|
|
738
|
+
},
|
|
739
|
+
id: null
|
|
740
|
+
}), {
|
|
741
|
+
status: 400,
|
|
742
|
+
headers: {
|
|
743
|
+
"Content-Type": "application/json",
|
|
744
|
+
...this.getHeaders()
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
if (!SUPPORTED_PROTOCOL_VERSIONS.includes(versionHeader)) return new Response(JSON.stringify({
|
|
749
|
+
jsonrpc: "2.0",
|
|
750
|
+
error: {
|
|
751
|
+
code: -32e3,
|
|
752
|
+
message: `Bad Request: Unsupported ${MCP_PROTOCOL_VERSION_HEADER}: ${versionHeader}. Supported versions: ${SUPPORTED_PROTOCOL_VERSIONS.join(", ")}`
|
|
753
|
+
},
|
|
754
|
+
id: null
|
|
755
|
+
}), {
|
|
756
|
+
status: 400,
|
|
757
|
+
headers: {
|
|
758
|
+
"Content-Type": "application/json",
|
|
759
|
+
...this.getHeaders()
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
if (this.protocolVersion && versionHeader !== this.protocolVersion) return new Response(JSON.stringify({
|
|
763
|
+
jsonrpc: "2.0",
|
|
764
|
+
error: {
|
|
765
|
+
code: -32e3,
|
|
766
|
+
message: `Bad Request: ${MCP_PROTOCOL_VERSION_HEADER} mismatch. Expected: ${this.protocolVersion}, Got: ${versionHeader}`
|
|
767
|
+
},
|
|
768
|
+
id: null
|
|
769
|
+
}), {
|
|
770
|
+
status: 400,
|
|
771
|
+
headers: {
|
|
772
|
+
"Content-Type": "application/json",
|
|
773
|
+
...this.getHeaders()
|
|
774
|
+
}
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
getHeaders({ forPreflight } = {}) {
|
|
778
|
+
const options = {
|
|
779
|
+
origin: "*",
|
|
780
|
+
headers: "Content-Type, Accept, Authorization, mcp-session-id, MCP-Protocol-Version",
|
|
781
|
+
methods: "GET, POST, DELETE, OPTIONS",
|
|
782
|
+
exposeHeaders: "mcp-session-id",
|
|
783
|
+
maxAge: 86400,
|
|
784
|
+
...this.corsOptions
|
|
785
|
+
};
|
|
786
|
+
if (forPreflight) return {
|
|
787
|
+
"Access-Control-Allow-Origin": options.origin,
|
|
788
|
+
"Access-Control-Allow-Headers": options.headers,
|
|
789
|
+
"Access-Control-Allow-Methods": options.methods,
|
|
790
|
+
"Access-Control-Max-Age": options.maxAge.toString()
|
|
791
|
+
};
|
|
792
|
+
return {
|
|
793
|
+
"Access-Control-Allow-Origin": options.origin,
|
|
794
|
+
"Access-Control-Expose-Headers": options.exposeHeaders
|
|
795
|
+
};
|
|
796
|
+
}
|
|
647
797
|
async handleRequest(request, parsedBody) {
|
|
798
|
+
await this.restoreState();
|
|
648
799
|
switch (request.method) {
|
|
649
800
|
case "OPTIONS": return this.handleOptionsRequest(request);
|
|
650
801
|
case "GET": return this.handleGetRequest(request);
|
|
@@ -663,10 +814,15 @@ var WorkerTransport = class {
|
|
|
663
814
|
id: null
|
|
664
815
|
}), {
|
|
665
816
|
status: 406,
|
|
666
|
-
headers: {
|
|
817
|
+
headers: {
|
|
818
|
+
"Content-Type": "application/json",
|
|
819
|
+
...this.getHeaders()
|
|
820
|
+
}
|
|
667
821
|
});
|
|
668
|
-
const
|
|
669
|
-
if (
|
|
822
|
+
const sessionError = this.validateSession(request);
|
|
823
|
+
if (sessionError) return sessionError;
|
|
824
|
+
const versionError = this.validateProtocolVersion(request);
|
|
825
|
+
if (versionError) return versionError;
|
|
670
826
|
const streamId = this.standaloneSseStreamId;
|
|
671
827
|
if (this.streamMapping.get(streamId) !== void 0) return new Response(JSON.stringify({
|
|
672
828
|
jsonrpc: "2.0",
|
|
@@ -677,7 +833,10 @@ var WorkerTransport = class {
|
|
|
677
833
|
id: null
|
|
678
834
|
}), {
|
|
679
835
|
status: 409,
|
|
680
|
-
headers: {
|
|
836
|
+
headers: {
|
|
837
|
+
"Content-Type": "application/json",
|
|
838
|
+
...this.getHeaders()
|
|
839
|
+
}
|
|
681
840
|
});
|
|
682
841
|
const { readable, writable } = new TransformStream();
|
|
683
842
|
const writer = writable.getWriter();
|
|
@@ -686,8 +845,7 @@ var WorkerTransport = class {
|
|
|
686
845
|
"Content-Type": "text/event-stream",
|
|
687
846
|
"Cache-Control": "no-cache",
|
|
688
847
|
Connection: "keep-alive",
|
|
689
|
-
|
|
690
|
-
"Access-Control-Expose-Headers": "mcp-session-id"
|
|
848
|
+
...this.getHeaders()
|
|
691
849
|
});
|
|
692
850
|
if (this.sessionId !== void 0) headers.set("mcp-session-id", this.sessionId);
|
|
693
851
|
const keepAlive = setInterval(() => {
|
|
@@ -710,7 +868,7 @@ var WorkerTransport = class {
|
|
|
710
868
|
}
|
|
711
869
|
async handlePostRequest(request, parsedBody) {
|
|
712
870
|
const acceptHeader = request.headers.get("Accept");
|
|
713
|
-
if (!acceptHeader?.includes("application/json") || !acceptHeader
|
|
871
|
+
if (!acceptHeader?.includes("application/json") || !acceptHeader?.includes("text/event-stream")) return new Response(JSON.stringify({
|
|
714
872
|
jsonrpc: "2.0",
|
|
715
873
|
error: {
|
|
716
874
|
code: -32e3,
|
|
@@ -719,7 +877,10 @@ var WorkerTransport = class {
|
|
|
719
877
|
id: null
|
|
720
878
|
}), {
|
|
721
879
|
status: 406,
|
|
722
|
-
headers: {
|
|
880
|
+
headers: {
|
|
881
|
+
"Content-Type": "application/json",
|
|
882
|
+
...this.getHeaders()
|
|
883
|
+
}
|
|
723
884
|
});
|
|
724
885
|
if (!request.headers.get("Content-Type")?.includes("application/json")) return new Response(JSON.stringify({
|
|
725
886
|
jsonrpc: "2.0",
|
|
@@ -730,7 +891,10 @@ var WorkerTransport = class {
|
|
|
730
891
|
id: null
|
|
731
892
|
}), {
|
|
732
893
|
status: 415,
|
|
733
|
-
headers: {
|
|
894
|
+
headers: {
|
|
895
|
+
"Content-Type": "application/json",
|
|
896
|
+
...this.getHeaders()
|
|
897
|
+
}
|
|
734
898
|
});
|
|
735
899
|
let rawMessage = parsedBody;
|
|
736
900
|
if (rawMessage === void 0) try {
|
|
@@ -745,7 +909,10 @@ var WorkerTransport = class {
|
|
|
745
909
|
id: null
|
|
746
910
|
}), {
|
|
747
911
|
status: 400,
|
|
748
|
-
headers: {
|
|
912
|
+
headers: {
|
|
913
|
+
"Content-Type": "application/json",
|
|
914
|
+
...this.getHeaders()
|
|
915
|
+
}
|
|
749
916
|
});
|
|
750
917
|
}
|
|
751
918
|
let messages;
|
|
@@ -762,9 +929,13 @@ var WorkerTransport = class {
|
|
|
762
929
|
id: null
|
|
763
930
|
}), {
|
|
764
931
|
status: 400,
|
|
765
|
-
headers: {
|
|
932
|
+
headers: {
|
|
933
|
+
"Content-Type": "application/json",
|
|
934
|
+
...this.getHeaders()
|
|
935
|
+
}
|
|
766
936
|
});
|
|
767
937
|
}
|
|
938
|
+
const requestInfo = { headers: Object.fromEntries(request.headers.entries()) };
|
|
768
939
|
const isInitializationRequest = messages.some(isInitializeRequest);
|
|
769
940
|
if (isInitializationRequest) {
|
|
770
941
|
if (this.initialized && this.sessionId !== void 0) return new Response(JSON.stringify({
|
|
@@ -776,7 +947,10 @@ var WorkerTransport = class {
|
|
|
776
947
|
id: null
|
|
777
948
|
}), {
|
|
778
949
|
status: 400,
|
|
779
|
-
headers: {
|
|
950
|
+
headers: {
|
|
951
|
+
"Content-Type": "application/json",
|
|
952
|
+
...this.getHeaders()
|
|
953
|
+
}
|
|
780
954
|
});
|
|
781
955
|
if (messages.length > 1) return new Response(JSON.stringify({
|
|
782
956
|
jsonrpc: "2.0",
|
|
@@ -787,21 +961,33 @@ var WorkerTransport = class {
|
|
|
787
961
|
id: null
|
|
788
962
|
}), {
|
|
789
963
|
status: 400,
|
|
790
|
-
headers: {
|
|
964
|
+
headers: {
|
|
965
|
+
"Content-Type": "application/json",
|
|
966
|
+
...this.getHeaders()
|
|
967
|
+
}
|
|
791
968
|
});
|
|
969
|
+
const initRequest = messages.find(isInitializeRequest);
|
|
970
|
+
if (initRequest?.params) {
|
|
971
|
+
const version = initRequest.params.protocolVersion;
|
|
972
|
+
if (version && SUPPORTED_PROTOCOL_VERSIONS.includes(version)) this.protocolVersion = version;
|
|
973
|
+
else this.protocolVersion = DEFAULT_PROTOCOL_VERSION;
|
|
974
|
+
}
|
|
792
975
|
this.sessionId = this.sessionIdGenerator?.();
|
|
793
976
|
this.initialized = true;
|
|
977
|
+
await this.saveState();
|
|
794
978
|
if (this.sessionId && this.onsessioninitialized) this.onsessioninitialized(this.sessionId);
|
|
795
979
|
}
|
|
796
980
|
if (!isInitializationRequest) {
|
|
797
|
-
const
|
|
798
|
-
if (
|
|
981
|
+
const sessionError = this.validateSession(request);
|
|
982
|
+
if (sessionError) return sessionError;
|
|
983
|
+
const versionError = this.validateProtocolVersion(request);
|
|
984
|
+
if (versionError) return versionError;
|
|
799
985
|
}
|
|
800
986
|
if (!messages.some(isJSONRPCRequest)) {
|
|
801
|
-
for (const message of messages) this.onmessage?.(message);
|
|
987
|
+
for (const message of messages) this.onmessage?.(message, { requestInfo });
|
|
802
988
|
return new Response(null, {
|
|
803
989
|
status: 202,
|
|
804
|
-
headers: {
|
|
990
|
+
headers: { ...this.getHeaders() }
|
|
805
991
|
});
|
|
806
992
|
}
|
|
807
993
|
const streamId = crypto.randomUUID();
|
|
@@ -813,7 +999,7 @@ var WorkerTransport = class {
|
|
|
813
999
|
}
|
|
814
1000
|
});
|
|
815
1001
|
for (const message of messages) if (isJSONRPCRequest(message)) this.requestToStreamMapping.set(message.id, streamId);
|
|
816
|
-
for (const message of messages) this.onmessage?.(message);
|
|
1002
|
+
for (const message of messages) this.onmessage?.(message, { requestInfo });
|
|
817
1003
|
});
|
|
818
1004
|
const { readable, writable } = new TransformStream();
|
|
819
1005
|
const writer = writable.getWriter();
|
|
@@ -822,8 +1008,7 @@ var WorkerTransport = class {
|
|
|
822
1008
|
"Content-Type": "text/event-stream",
|
|
823
1009
|
"Cache-Control": "no-cache",
|
|
824
1010
|
Connection: "keep-alive",
|
|
825
|
-
|
|
826
|
-
"Access-Control-Expose-Headers": "mcp-session-id"
|
|
1011
|
+
...this.getHeaders()
|
|
827
1012
|
});
|
|
828
1013
|
if (this.sessionId !== void 0) headers.set("mcp-session-id", this.sessionId);
|
|
829
1014
|
this.streamMapping.set(streamId, {
|
|
@@ -835,28 +1020,24 @@ var WorkerTransport = class {
|
|
|
835
1020
|
}
|
|
836
1021
|
});
|
|
837
1022
|
for (const message of messages) if (isJSONRPCRequest(message)) this.requestToStreamMapping.set(message.id, streamId);
|
|
838
|
-
for (const message of messages) this.onmessage?.(message);
|
|
1023
|
+
for (const message of messages) this.onmessage?.(message, { requestInfo });
|
|
839
1024
|
return new Response(readable, { headers });
|
|
840
1025
|
}
|
|
841
1026
|
async handleDeleteRequest(request) {
|
|
842
|
-
const
|
|
843
|
-
if (
|
|
1027
|
+
const sessionError = this.validateSession(request);
|
|
1028
|
+
if (sessionError) return sessionError;
|
|
1029
|
+
const versionError = this.validateProtocolVersion(request);
|
|
1030
|
+
if (versionError) return versionError;
|
|
844
1031
|
await this.close();
|
|
845
1032
|
return new Response(null, {
|
|
846
1033
|
status: 200,
|
|
847
|
-
headers: {
|
|
1034
|
+
headers: { ...this.getHeaders() }
|
|
848
1035
|
});
|
|
849
1036
|
}
|
|
850
1037
|
handleOptionsRequest(_request) {
|
|
851
|
-
const headers = new Headers({
|
|
852
|
-
"Access-Control-Allow-Origin": "*",
|
|
853
|
-
"Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS",
|
|
854
|
-
"Access-Control-Allow-Headers": "Content-Type, Accept, Authorization, mcp-session-id",
|
|
855
|
-
"Access-Control-Max-Age": "86400"
|
|
856
|
-
});
|
|
857
1038
|
return new Response(null, {
|
|
858
|
-
status:
|
|
859
|
-
headers
|
|
1039
|
+
status: 200,
|
|
1040
|
+
headers: { ...this.getHeaders({ forPreflight: true }) }
|
|
860
1041
|
});
|
|
861
1042
|
}
|
|
862
1043
|
handleUnsupportedRequest() {
|
|
@@ -876,7 +1057,7 @@ var WorkerTransport = class {
|
|
|
876
1057
|
});
|
|
877
1058
|
}
|
|
878
1059
|
validateSession(request) {
|
|
879
|
-
if (this.sessionIdGenerator === void 0) return
|
|
1060
|
+
if (this.sessionIdGenerator === void 0) return;
|
|
880
1061
|
if (!this.initialized) return new Response(JSON.stringify({
|
|
881
1062
|
jsonrpc: "2.0",
|
|
882
1063
|
error: {
|
|
@@ -886,7 +1067,10 @@ var WorkerTransport = class {
|
|
|
886
1067
|
id: null
|
|
887
1068
|
}), {
|
|
888
1069
|
status: 400,
|
|
889
|
-
headers: {
|
|
1070
|
+
headers: {
|
|
1071
|
+
"Content-Type": "application/json",
|
|
1072
|
+
...this.getHeaders()
|
|
1073
|
+
}
|
|
890
1074
|
});
|
|
891
1075
|
const sessionId = request.headers.get("mcp-session-id");
|
|
892
1076
|
if (!sessionId) return new Response(JSON.stringify({
|
|
@@ -898,7 +1082,10 @@ var WorkerTransport = class {
|
|
|
898
1082
|
id: null
|
|
899
1083
|
}), {
|
|
900
1084
|
status: 400,
|
|
901
|
-
headers: {
|
|
1085
|
+
headers: {
|
|
1086
|
+
"Content-Type": "application/json",
|
|
1087
|
+
...this.getHeaders()
|
|
1088
|
+
}
|
|
902
1089
|
});
|
|
903
1090
|
if (sessionId !== this.sessionId) return new Response(JSON.stringify({
|
|
904
1091
|
jsonrpc: "2.0",
|
|
@@ -909,9 +1096,11 @@ var WorkerTransport = class {
|
|
|
909
1096
|
id: null
|
|
910
1097
|
}), {
|
|
911
1098
|
status: 404,
|
|
912
|
-
headers: {
|
|
1099
|
+
headers: {
|
|
1100
|
+
"Content-Type": "application/json",
|
|
1101
|
+
...this.getHeaders()
|
|
1102
|
+
}
|
|
913
1103
|
});
|
|
914
|
-
return true;
|
|
915
1104
|
}
|
|
916
1105
|
async close() {
|
|
917
1106
|
for (const { cleanup } of this.streamMapping.values()) cleanup();
|
|
@@ -919,8 +1108,8 @@ var WorkerTransport = class {
|
|
|
919
1108
|
this.requestResponseMap.clear();
|
|
920
1109
|
this.onclose?.();
|
|
921
1110
|
}
|
|
922
|
-
async send(message) {
|
|
923
|
-
let requestId;
|
|
1111
|
+
async send(message, options) {
|
|
1112
|
+
let requestId = options?.relatedRequestId;
|
|
924
1113
|
if (isJSONRPCResponse(message) || isJSONRPCError(message)) requestId = message.id;
|
|
925
1114
|
if (requestId === void 0) {
|
|
926
1115
|
if (isJSONRPCResponse(message) || isJSONRPCError(message)) throw new Error("Cannot send a response on a standalone SSE stream unless resuming a previous client request");
|
|
@@ -950,8 +1139,7 @@ var WorkerTransport = class {
|
|
|
950
1139
|
const responses = relatedIds.map((id) => this.requestResponseMap.get(id));
|
|
951
1140
|
const headers = new Headers({
|
|
952
1141
|
"Content-Type": "application/json",
|
|
953
|
-
|
|
954
|
-
"Access-Control-Expose-Headers": "mcp-session-id"
|
|
1142
|
+
...this.getHeaders()
|
|
955
1143
|
});
|
|
956
1144
|
if (this.sessionId !== void 0) headers.set("mcp-session-id", this.sessionId);
|
|
957
1145
|
const body = responses.length === 1 ? responses[0] : responses;
|
|
@@ -978,23 +1166,30 @@ function runWithAuthContext(context, fn) {
|
|
|
978
1166
|
|
|
979
1167
|
//#endregion
|
|
980
1168
|
//#region src/mcp/handler.ts
|
|
981
|
-
function
|
|
1169
|
+
function createMcpHandler(server, options = {}) {
|
|
982
1170
|
const route = options.route ?? "/mcp";
|
|
983
1171
|
return async (request, _env, ctx) => {
|
|
984
1172
|
const url = new URL(request.url);
|
|
985
1173
|
if (route && url.pathname !== route) return new Response("Not Found", { status: 404 });
|
|
986
|
-
const
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
1174
|
+
const transport = options.transport ?? new WorkerTransport({
|
|
1175
|
+
sessionIdGenerator: options.sessionIdGenerator,
|
|
1176
|
+
enableJsonResponse: options.enableJsonResponse,
|
|
1177
|
+
onsessioninitialized: options.onsessioninitialized,
|
|
1178
|
+
corsOptions: options.corsOptions,
|
|
1179
|
+
storage: options.storage
|
|
1180
|
+
});
|
|
1181
|
+
const buildAuthContext = () => {
|
|
1182
|
+
if (options.authContext) return options.authContext;
|
|
1183
|
+
if (ctx.props && Object.keys(ctx.props).length > 0) return { props: ctx.props };
|
|
1184
|
+
};
|
|
990
1185
|
const handleRequest = async () => {
|
|
991
1186
|
return await transport.handleRequest(request);
|
|
992
1187
|
};
|
|
1188
|
+
const authContext = buildAuthContext();
|
|
1189
|
+
if (!transport.started) await server.connect(transport);
|
|
993
1190
|
try {
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
else response = await handleRequest();
|
|
997
|
-
return response;
|
|
1191
|
+
if (authContext) return await runWithAuthContext(authContext, handleRequest);
|
|
1192
|
+
else return await handleRequest();
|
|
998
1193
|
} catch (error) {
|
|
999
1194
|
console.error("MCP handler error:", error);
|
|
1000
1195
|
return new Response(JSON.stringify({
|
|
@@ -1011,6 +1206,17 @@ function experimental_createMcpHandler(server, options = {}) {
|
|
|
1011
1206
|
}
|
|
1012
1207
|
};
|
|
1013
1208
|
}
|
|
1209
|
+
let didWarnAboutExperimentalCreateMcpHandler = false;
|
|
1210
|
+
/**
|
|
1211
|
+
* @deprecated This has been renamed to createMcpHandler, and experimental_createMcpHandler will be removed in the next major version
|
|
1212
|
+
*/
|
|
1213
|
+
function experimental_createMcpHandler(server, options = {}) {
|
|
1214
|
+
if (!didWarnAboutExperimentalCreateMcpHandler) {
|
|
1215
|
+
didWarnAboutExperimentalCreateMcpHandler = true;
|
|
1216
|
+
console.warn("experimental_createMcpHandler is deprecated, use createMcpHandler instead. experimental_createMcpHandler will be removed in the next major version.");
|
|
1217
|
+
}
|
|
1218
|
+
return createMcpHandler(server, options);
|
|
1219
|
+
}
|
|
1014
1220
|
|
|
1015
1221
|
//#endregion
|
|
1016
1222
|
//#region src/mcp/index.ts
|
|
@@ -1051,7 +1257,7 @@ var McpAgent = class McpAgent extends Agent {
|
|
|
1051
1257
|
/** Returns a new transport matching the type of the Agent. */
|
|
1052
1258
|
initTransport() {
|
|
1053
1259
|
switch (this.getTransportType()) {
|
|
1054
|
-
case "sse": return new McpSSETransport(
|
|
1260
|
+
case "sse": return new McpSSETransport();
|
|
1055
1261
|
case "streamable-http": return new StreamableHTTPServerTransport({});
|
|
1056
1262
|
}
|
|
1057
1263
|
}
|
|
@@ -1104,7 +1310,7 @@ var McpAgent = class McpAgent extends Agent {
|
|
|
1104
1310
|
}
|
|
1105
1311
|
}
|
|
1106
1312
|
/** Handles MCP Messages for the legacy SSE transport. */
|
|
1107
|
-
async onSSEMcpMessage(_sessionId, messageBody) {
|
|
1313
|
+
async onSSEMcpMessage(_sessionId, messageBody, extraInfo) {
|
|
1108
1314
|
if (this.getTransportType() !== "sse") return /* @__PURE__ */ new Error("Internal Server Error: Expected SSE transport");
|
|
1109
1315
|
try {
|
|
1110
1316
|
let parsedMessage;
|
|
@@ -1115,7 +1321,7 @@ var McpAgent = class McpAgent extends Agent {
|
|
|
1115
1321
|
throw error;
|
|
1116
1322
|
}
|
|
1117
1323
|
if (await this._handleElicitationResponse(parsedMessage)) return null;
|
|
1118
|
-
this._transport?.onmessage?.(parsedMessage);
|
|
1324
|
+
this._transport?.onmessage?.(parsedMessage, extraInfo);
|
|
1119
1325
|
return null;
|
|
1120
1326
|
} catch (error) {
|
|
1121
1327
|
console.error("Error forwarding message to SSE:", error);
|
|
@@ -1201,7 +1407,7 @@ var McpAgent = class McpAgent extends Agent {
|
|
|
1201
1407
|
/** Return a handler for the given path for this MCP.
|
|
1202
1408
|
* Defaults to Streamable HTTP transport.
|
|
1203
1409
|
*/
|
|
1204
|
-
static serve(path, { binding = "MCP_OBJECT", corsOptions, transport = "streamable-http" } = {}) {
|
|
1410
|
+
static serve(path, { binding = "MCP_OBJECT", corsOptions, transport = "streamable-http", jurisdiction } = {}) {
|
|
1205
1411
|
return { async fetch(request, env, ctx) {
|
|
1206
1412
|
const corsResponse = handleCORS(request, corsOptions);
|
|
1207
1413
|
if (corsResponse) return corsResponse;
|
|
@@ -1210,8 +1416,14 @@ var McpAgent = class McpAgent extends Agent {
|
|
|
1210
1416
|
if (!isDurableObjectNamespace(bindingValue)) throw new Error(`Invalid McpAgent binding for ${binding}. Make sure it's a Durable Object binding.`);
|
|
1211
1417
|
const namespace = bindingValue;
|
|
1212
1418
|
switch (transport) {
|
|
1213
|
-
case "streamable-http": return createStreamingHttpHandler(path, namespace,
|
|
1214
|
-
|
|
1419
|
+
case "streamable-http": return createStreamingHttpHandler(path, namespace, {
|
|
1420
|
+
corsOptions,
|
|
1421
|
+
jurisdiction
|
|
1422
|
+
})(request, ctx);
|
|
1423
|
+
case "sse": return createLegacySseHandler(path, namespace, {
|
|
1424
|
+
corsOptions,
|
|
1425
|
+
jurisdiction
|
|
1426
|
+
})(request, ctx);
|
|
1215
1427
|
default: return new Response("Invalid MCP transport mode. Only `streamable-http` or `sse` are allowed.", { status: 500 });
|
|
1216
1428
|
}
|
|
1217
1429
|
} };
|
|
@@ -1231,5 +1443,5 @@ var McpAgent = class McpAgent extends Agent {
|
|
|
1231
1443
|
};
|
|
1232
1444
|
|
|
1233
1445
|
//#endregion
|
|
1234
|
-
export { ElicitRequestSchema, McpAgent, SSEEdgeClientTransport, StreamableHTTPEdgeClientTransport, WorkerTransport, experimental_createMcpHandler, getMcpAuthContext };
|
|
1446
|
+
export { ElicitRequestSchema, McpAgent, SSEEdgeClientTransport, StreamableHTTPEdgeClientTransport, WorkerTransport, createMcpHandler, experimental_createMcpHandler, getMcpAuthContext };
|
|
1235
1447
|
//# sourceMappingURL=index.js.map
|