agents 0.19.0 → 0.20.1
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 +24 -19
- package/dist/{agent-tool-types-BNUGGBzQ.d.ts → agent-tool-types-BC-WFlsz.d.ts} +1026 -400
- package/dist/agent-tool-types.d.ts +1 -1
- package/dist/{agent-tools-BFbzVLFc.d.ts → agent-tools-DeHe9Xov.d.ts} +2 -2
- package/dist/agent-tools.d.ts +1 -1
- package/dist/browser/ai.js +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/chat/index.d.ts +2 -2
- package/dist/chat-sdk/index.d.ts +1 -1
- package/dist/client-invoker-BNSZxAkv.d.ts +20 -0
- package/dist/client-invoker-VNZ7X0nn.js +57 -0
- package/dist/client-invoker-VNZ7X0nn.js.map +1 -0
- package/dist/{client-CcjiFpTf.js → client-zqKcsyFa.js} +434 -168
- package/dist/client-zqKcsyFa.js.map +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/cloudflare-BduZwmYK.js +204 -0
- package/dist/cloudflare-BduZwmYK.js.map +1 -0
- package/dist/{connector-CdldGF3h.js → connector-KEJnl6e5.js} +2 -2
- package/dist/connector-KEJnl6e5.js.map +1 -0
- package/dist/{do-oauth-client-provider-D4ZwyBDu.d.ts → do-oauth-client-provider-VTZj2VtM.d.ts} +23 -11
- package/dist/experimental/webmcp.js +1 -1
- package/dist/handler-stateless-CIkKPETH.js +318 -0
- package/dist/handler-stateless-CIkKPETH.js.map +1 -0
- package/dist/handler-stateless-C_bo-Ytq.d.ts +107 -0
- package/dist/index.d.ts +14 -12
- package/dist/index.js +30 -20
- package/dist/index.js.map +1 -1
- package/dist/mcp/client.d.ts +22 -18
- package/dist/mcp/client.js +1 -1
- package/dist/mcp/do-oauth-client-provider.d.ts +1 -1
- package/dist/mcp/do-oauth-client-provider.js +25 -12
- package/dist/mcp/do-oauth-client-provider.js.map +1 -1
- package/dist/mcp/index.d.ts +48 -34
- package/dist/mcp/index.js +95 -156
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/server.d.ts +17 -0
- package/dist/mcp/server.js +2 -0
- package/dist/mcp/x402.d.ts +21 -9
- package/dist/mcp/x402.js +8 -7
- package/dist/mcp/x402.js.map +1 -1
- package/dist/observability/ai/index.d.ts +9 -1
- package/dist/observability/ai/index.js +188 -63
- package/dist/observability/ai/index.js.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/sub-routing.d.ts +6 -6
- package/dist/workflows.d.ts +1 -1
- package/docs/human-in-the-loop.md +63 -82
- package/docs/mcp-client.md +31 -7
- package/docs/mcp-servers.md +125 -88
- package/docs/observability.md +2 -1
- package/docs/securing-mcp-servers.md +9 -6
- package/package.json +28 -7
- package/dist/client-CcjiFpTf.js.map +0 -1
- package/dist/cloudflare-BldFV0Pa.js +0 -117
- package/dist/cloudflare-BldFV0Pa.js.map +0 -1
- package/dist/connector-CdldGF3h.js.map +0 -1
package/dist/mcp/index.js
CHANGED
|
@@ -1,30 +1,24 @@
|
|
|
1
1
|
import "../types.js";
|
|
2
|
-
import { c as RPC_DO_PREFIX, i as normalizeServerId, n as MCP_SERVER_ID_MAX_LENGTH, o as RPCClientTransport, s as RPCServerTransport } from "../client-
|
|
2
|
+
import { c as RPC_DO_PREFIX, i as normalizeServerId, n as MCP_SERVER_ID_MAX_LENGTH, o as RPCClientTransport, s as RPCServerTransport } from "../client-zqKcsyFa.js";
|
|
3
3
|
import { Agent, getAgentByName, getCurrentAgent } from "../index.js";
|
|
4
|
-
import {
|
|
5
|
-
import { SSEClientTransport } from "@modelcontextprotocol/
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
|
-
import {
|
|
4
|
+
import { n as getMcpAuthContext, r as runWithAuthContext, t as createStatelessMcpHandler } from "../handler-stateless-CIkKPETH.js";
|
|
5
|
+
import { SSEClientTransport, StreamableHTTPClientTransport } from "@modelcontextprotocol/client";
|
|
6
|
+
import { ElicitRequestSchema, InitializeRequestSchema, JSONRPCMessageSchema, SUPPORTED_PROTOCOL_VERSIONS, isInitializeRequest, isJSONRPCErrorResponse, isJSONRPCNotification, isJSONRPCRequest, isJSONRPCResultResponse } from "@modelcontextprotocol/sdk/types.js";
|
|
7
|
+
import { McpServer, Server } from "@modelcontextprotocol/server";
|
|
8
|
+
import { McpServer as McpServer$1 } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
|
+
import { Server as Server$1 } from "@modelcontextprotocol/sdk/server/index.js";
|
|
10
|
+
import { WebStandardStreamableHTTPServerTransport as WebStandardStreamableHTTPServerTransport$1 } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
10
11
|
//#region src/mcp/sse-keepalive.ts
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
+
* SSE keepalive for the retained McpAgent WebSocket-to-SSE bridge.
|
|
13
14
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* watchdog.
|
|
15
|
+
* SDK-backed HTTP transports own their keepalive timers. This helper remains
|
|
16
|
+
* only for the custom bridge, where long-running POST tool calls can otherwise
|
|
17
|
+
* sit silent until Cloudflare's edge closes the idle stream.
|
|
18
18
|
*
|
|
19
19
|
* See cloudflare/agents#1583.
|
|
20
20
|
*/
|
|
21
|
-
/** Interval between SSE keepalive comment frames, in ms.
|
|
22
|
-
*
|
|
23
|
-
* The WHATWG SSE spec recommends a comment line every "15 seconds or so"
|
|
24
|
-
* (html.spec.whatwg.org §9.2.7). 25s gives comfortable headroom below
|
|
25
|
-
* both the ~30s post-handler background-work cancellation window on
|
|
26
|
-
* Workers and the ~5min Cloudflare edge idle-stream watchdog.
|
|
27
|
-
*/
|
|
21
|
+
/** Interval between bridge SSE keepalive comment frames, in ms. */
|
|
28
22
|
const KEEPALIVE_INTERVAL_MS = 25e3;
|
|
29
23
|
/** SSE comment frame the parser drops before any event dispatch. */
|
|
30
24
|
const KEEPALIVE_FRAME = ": keepalive\n\n";
|
|
@@ -54,6 +48,18 @@ const MCP_HTTP_METHOD_HEADER = "cf-mcp-method";
|
|
|
54
48
|
*/
|
|
55
49
|
const MCP_MESSAGE_HEADER = "cf-mcp-message";
|
|
56
50
|
const MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
|
|
51
|
+
function unsupportedProtocolVersionResponse(request) {
|
|
52
|
+
const protocolVersion = request.headers.get("mcp-protocol-version");
|
|
53
|
+
if (protocolVersion === null || SUPPORTED_PROTOCOL_VERSIONS.includes(protocolVersion)) return;
|
|
54
|
+
return Response.json({
|
|
55
|
+
error: {
|
|
56
|
+
code: -32e3,
|
|
57
|
+
message: `Bad Request: Unsupported protocol version: ${protocolVersion} (supported versions: ${SUPPORTED_PROTOCOL_VERSIONS.join(", ")})`
|
|
58
|
+
},
|
|
59
|
+
id: null,
|
|
60
|
+
jsonrpc: "2.0"
|
|
61
|
+
}, { status: 400 });
|
|
62
|
+
}
|
|
57
63
|
const createStreamingHttpHandler = (basePath, namespace, options = {}) => {
|
|
58
64
|
let pathname = basePath;
|
|
59
65
|
if (basePath === "/") pathname = "/*";
|
|
@@ -151,6 +157,10 @@ const createStreamingHttpHandler = (basePath, namespace, options = {}) => {
|
|
|
151
157
|
});
|
|
152
158
|
return new Response(body, { status: 400 });
|
|
153
159
|
}
|
|
160
|
+
if (!maybeInitializeRequest) {
|
|
161
|
+
const unsupportedVersion = unsupportedProtocolVersionResponse(request);
|
|
162
|
+
if (unsupportedVersion) return unsupportedVersion;
|
|
163
|
+
}
|
|
154
164
|
if (!maybeInitializeRequest && !sessionId) {
|
|
155
165
|
const body = JSON.stringify({
|
|
156
166
|
error: {
|
|
@@ -279,6 +289,8 @@ const createStreamingHttpHandler = (basePath, namespace, options = {}) => {
|
|
|
279
289
|
id: null,
|
|
280
290
|
jsonrpc: "2.0"
|
|
281
291
|
}), { status: 400 });
|
|
292
|
+
const unsupportedVersion = unsupportedProtocolVersionResponse(request);
|
|
293
|
+
if (unsupportedVersion) return unsupportedVersion;
|
|
282
294
|
const { readable, writable } = new TransformStream();
|
|
283
295
|
const writer = writable.getWriter();
|
|
284
296
|
const encoder = new TextEncoder();
|
|
@@ -338,6 +350,8 @@ const createStreamingHttpHandler = (basePath, namespace, options = {}) => {
|
|
|
338
350
|
status: 200
|
|
339
351
|
});
|
|
340
352
|
} else if (request.method === "DELETE") {
|
|
353
|
+
const unsupportedVersion = unsupportedProtocolVersionResponse(request);
|
|
354
|
+
if (unsupportedVersion) return unsupportedVersion;
|
|
341
355
|
const sessionId = request.headers.get("mcp-session-id");
|
|
342
356
|
if (!sessionId) return new Response(JSON.stringify({
|
|
343
357
|
jsonrpc: "2.0",
|
|
@@ -980,36 +994,36 @@ DurableObjectEventStore.REPLAY_LIMIT = 1e3;
|
|
|
980
994
|
*/
|
|
981
995
|
let didWarnAboutSSEEdgeClientTransport = false;
|
|
982
996
|
/**
|
|
983
|
-
* @deprecated Use SSEClientTransport from @modelcontextprotocol/
|
|
997
|
+
* @deprecated Use SSEClientTransport from @modelcontextprotocol/client instead. This alias will be removed in the next major version.
|
|
984
998
|
*/
|
|
985
999
|
var SSEEdgeClientTransport = class extends SSEClientTransport {
|
|
986
1000
|
constructor(url, options) {
|
|
987
1001
|
super(url, options);
|
|
988
1002
|
if (!didWarnAboutSSEEdgeClientTransport) {
|
|
989
1003
|
didWarnAboutSSEEdgeClientTransport = true;
|
|
990
|
-
console.warn("SSEEdgeClientTransport is deprecated. Use SSEClientTransport from @modelcontextprotocol/
|
|
1004
|
+
console.warn("SSEEdgeClientTransport is deprecated. Use SSEClientTransport from @modelcontextprotocol/client instead. SSEEdgeClientTransport will be removed in the next major version.");
|
|
991
1005
|
}
|
|
992
1006
|
}
|
|
993
1007
|
};
|
|
994
1008
|
let didWarnAboutStreamableHTTPEdgeClientTransport = false;
|
|
995
1009
|
/**
|
|
996
|
-
* @deprecated Use StreamableHTTPClientTransport from @modelcontextprotocol/
|
|
1010
|
+
* @deprecated Use StreamableHTTPClientTransport from @modelcontextprotocol/client instead. This alias will be removed in the next major version.
|
|
997
1011
|
*/
|
|
998
1012
|
var StreamableHTTPEdgeClientTransport = class extends StreamableHTTPClientTransport {
|
|
999
1013
|
constructor(url, options) {
|
|
1000
1014
|
super(url, options);
|
|
1001
1015
|
if (!didWarnAboutStreamableHTTPEdgeClientTransport) {
|
|
1002
1016
|
didWarnAboutStreamableHTTPEdgeClientTransport = true;
|
|
1003
|
-
console.warn("StreamableHTTPEdgeClientTransport is deprecated. Use StreamableHTTPClientTransport from @modelcontextprotocol/
|
|
1017
|
+
console.warn("StreamableHTTPEdgeClientTransport is deprecated. Use StreamableHTTPClientTransport from @modelcontextprotocol/client instead. StreamableHTTPEdgeClientTransport will be removed in the next major version.");
|
|
1004
1018
|
}
|
|
1005
1019
|
}
|
|
1006
1020
|
};
|
|
1007
1021
|
//#endregion
|
|
1008
1022
|
//#region src/mcp/worker-transport.ts
|
|
1009
1023
|
/**
|
|
1010
|
-
* WorkerTransport
|
|
1024
|
+
* WorkerTransport — retained sessionful Legacy transport
|
|
1011
1025
|
*
|
|
1012
|
-
* Thin Cloudflare-Workers wrapper around the official MCP SDK
|
|
1026
|
+
* Thin Cloudflare-Workers wrapper around the official MCP SDK v1
|
|
1013
1027
|
* `WebStandardStreamableHTTPServerTransport`. The wrapper layers a couple of
|
|
1014
1028
|
* Workers-specific concerns on top of the SDK transport without forking it:
|
|
1015
1029
|
*
|
|
@@ -1021,15 +1035,12 @@ var StreamableHTTPEdgeClientTransport = class extends StreamableHTTPClientTransp
|
|
|
1021
1035
|
* survive DO hibernation / eviction. On the first request after a cold
|
|
1022
1036
|
* start, the saved initialize params are replayed through the `Server`
|
|
1023
1037
|
* so client capabilities are re-established.
|
|
1024
|
-
* 3. **SSE keepalive** —
|
|
1025
|
-
*
|
|
1026
|
-
*
|
|
1027
|
-
* Disabled on the standalone GET stream when an `eventStore` is
|
|
1028
|
-
* configured — clients recover idle drops via `Last-Event-ID` instead.
|
|
1029
|
-
* POST response streams always keepalive (no resumption path during a
|
|
1030
|
-
* mid-flight tool call). See cloudflare/agents#1583.
|
|
1038
|
+
* 3. **SSE keepalive** — delegated to the SDK transport, which writes SSE
|
|
1039
|
+
* comment frames and owns timer cleanup. Configure the cadence with the
|
|
1040
|
+
* inherited `keepAliveMs` option.
|
|
1031
1041
|
*
|
|
1032
|
-
* Everything else (session
|
|
1042
|
+
* Stateless handlers do not import this module. Everything else (session
|
|
1043
|
+
* validation, SSE streaming, protocol-version
|
|
1033
1044
|
* negotiation, event-store resumability, etc.) is delegated to the SDK
|
|
1034
1045
|
* transport.
|
|
1035
1046
|
*/
|
|
@@ -1042,7 +1053,7 @@ const DEFAULT_CORS_OPTIONS = {
|
|
|
1042
1053
|
exposeHeaders: "mcp-session-id",
|
|
1043
1054
|
maxAge: 86400
|
|
1044
1055
|
};
|
|
1045
|
-
var WorkerTransport = class extends WebStandardStreamableHTTPServerTransport {
|
|
1056
|
+
var WorkerTransport = class extends WebStandardStreamableHTTPServerTransport$1 {
|
|
1046
1057
|
constructor(options = {}) {
|
|
1047
1058
|
const { corsOptions, storage, onsessioninitialized, ...sdkOptions } = options;
|
|
1048
1059
|
super({
|
|
@@ -1051,7 +1062,6 @@ var WorkerTransport = class extends WebStandardStreamableHTTPServerTransport {
|
|
|
1051
1062
|
});
|
|
1052
1063
|
this._stateRestored = false;
|
|
1053
1064
|
this._bridgeInstalled = false;
|
|
1054
|
-
this._keepaliveCleanups = /* @__PURE__ */ new Map();
|
|
1055
1065
|
this._closedRequestIds = /* @__PURE__ */ new Set();
|
|
1056
1066
|
this._corsOptions = corsOptions;
|
|
1057
1067
|
this._storage = storage;
|
|
@@ -1067,17 +1077,15 @@ var WorkerTransport = class extends WebStandardStreamableHTTPServerTransport {
|
|
|
1067
1077
|
/**
|
|
1068
1078
|
* Top-level request entry point. Handles CORS preflight, restores any
|
|
1069
1079
|
* persisted state on first invocation, then delegates to the SDK transport
|
|
1070
|
-
* and finally appends CORS headers
|
|
1071
|
-
* back.
|
|
1080
|
+
* and finally appends CORS headers to whatever response comes back.
|
|
1072
1081
|
*/
|
|
1073
1082
|
async handleRequest(request, options) {
|
|
1074
1083
|
if (request.method === "OPTIONS") return new Response(null, { headers: this.getCorsHeaders({ forPreflight: true }) });
|
|
1075
1084
|
await this.restoreState();
|
|
1076
1085
|
this.installOnSessionInitializedBridge();
|
|
1077
1086
|
await this.captureInitializeParams(request, options);
|
|
1078
|
-
const requestIdForKeepalive = request.method === "GET" ? "_standalone" : this._pendingRequestId;
|
|
1079
1087
|
const response = await super.handleRequest(request, options);
|
|
1080
|
-
return this.withCorsHeaders(this.
|
|
1088
|
+
return this.withCorsHeaders(this.normalizeAllowHeader(response));
|
|
1081
1089
|
}
|
|
1082
1090
|
/**
|
|
1083
1091
|
* The SDK's 405 responses advertise `Allow: GET, POST, DELETE` because
|
|
@@ -1097,19 +1105,10 @@ var WorkerTransport = class extends WebStandardStreamableHTTPServerTransport {
|
|
|
1097
1105
|
});
|
|
1098
1106
|
}
|
|
1099
1107
|
closeSSEStream(requestId) {
|
|
1100
|
-
this._keepaliveCleanups.get(requestId)?.();
|
|
1101
|
-
this._keepaliveCleanups.delete(requestId);
|
|
1102
1108
|
this._closedRequestIds.add(requestId);
|
|
1103
1109
|
super.closeSSEStream(requestId);
|
|
1104
1110
|
}
|
|
1105
|
-
closeStandaloneSSEStream() {
|
|
1106
|
-
this._keepaliveCleanups.get("_standalone")?.();
|
|
1107
|
-
this._keepaliveCleanups.delete("_standalone");
|
|
1108
|
-
super.closeStandaloneSSEStream();
|
|
1109
|
-
}
|
|
1110
1111
|
async close() {
|
|
1111
|
-
for (const cleanup of Array.from(this._keepaliveCleanups.values())) cleanup();
|
|
1112
|
-
this._keepaliveCleanups.clear();
|
|
1113
1112
|
this._closedRequestIds.clear();
|
|
1114
1113
|
await super.close();
|
|
1115
1114
|
}
|
|
@@ -1139,77 +1138,6 @@ var WorkerTransport = class extends WebStandardStreamableHTTPServerTransport {
|
|
|
1139
1138
|
if (requestId !== void 0 && this._closedRequestIds.has(requestId)) return;
|
|
1140
1139
|
await super.send(message, options);
|
|
1141
1140
|
}
|
|
1142
|
-
/**
|
|
1143
|
-
* If the response is an SSE stream, tee the body through a TransformStream
|
|
1144
|
-
* that injects a `: keepalive\n\n` comment frame every 25s. The interval
|
|
1145
|
-
* is cleared when the wrapped stream closes — which happens both when the
|
|
1146
|
-
* SDK ends the underlying stream naturally and when `closeSSEStream` is
|
|
1147
|
-
* called.
|
|
1148
|
-
*
|
|
1149
|
-
* Keepalive policy:
|
|
1150
|
-
* - POST response streams (`key` is a request id): always keepalive.
|
|
1151
|
-
* In-progress tool calls have no recovery path — if the stream drops
|
|
1152
|
-
* mid-execution the result is lost — so we keep it under the
|
|
1153
|
-
* Cloudflare edge ~5min idle watchdog.
|
|
1154
|
-
* - Standalone GET stream (`key === "_standalone"`): keepalive only
|
|
1155
|
-
* when no `eventStore` is configured. When resumability is enabled,
|
|
1156
|
-
* clients reconnect with `Last-Event-ID` after an idle drop, so we
|
|
1157
|
-
* skip the keepalive and let the DO hibernate.
|
|
1158
|
-
*
|
|
1159
|
-
* Uses the shared `sse-keepalive` constants so both this wrapper and
|
|
1160
|
-
* `McpAgent.serve()` write identical frames at the same cadence.
|
|
1161
|
-
* See cloudflare/agents#1583.
|
|
1162
|
-
*/
|
|
1163
|
-
withKeepalive(response, key) {
|
|
1164
|
-
if (!(response.headers.get("Content-Type") ?? "").includes("text/event-stream") || !response.body) return response;
|
|
1165
|
-
if (key === "_standalone" && this.eventStoreConfigured()) return response;
|
|
1166
|
-
const encoder = new TextEncoder();
|
|
1167
|
-
let intervalId;
|
|
1168
|
-
let controllerRef;
|
|
1169
|
-
const clear = () => {
|
|
1170
|
-
if (intervalId !== void 0) {
|
|
1171
|
-
clearInterval(intervalId);
|
|
1172
|
-
intervalId = void 0;
|
|
1173
|
-
}
|
|
1174
|
-
if (key !== void 0) this._keepaliveCleanups.delete(key);
|
|
1175
|
-
};
|
|
1176
|
-
const transform = new TransformStream({
|
|
1177
|
-
start: (controller) => {
|
|
1178
|
-
controllerRef = controller;
|
|
1179
|
-
intervalId = setInterval(() => {
|
|
1180
|
-
try {
|
|
1181
|
-
controllerRef?.enqueue(encoder.encode(KEEPALIVE_FRAME));
|
|
1182
|
-
} catch {
|
|
1183
|
-
clear();
|
|
1184
|
-
}
|
|
1185
|
-
}, KEEPALIVE_INTERVAL_MS);
|
|
1186
|
-
if (key !== void 0) this._keepaliveCleanups.set(key, clear);
|
|
1187
|
-
},
|
|
1188
|
-
transform(chunk, controller) {
|
|
1189
|
-
controller.enqueue(chunk);
|
|
1190
|
-
},
|
|
1191
|
-
flush() {
|
|
1192
|
-
clear();
|
|
1193
|
-
},
|
|
1194
|
-
cancel() {
|
|
1195
|
-
clear();
|
|
1196
|
-
}
|
|
1197
|
-
});
|
|
1198
|
-
const piped = response.body.pipeThrough(transform);
|
|
1199
|
-
return new Response(piped, {
|
|
1200
|
-
status: response.status,
|
|
1201
|
-
statusText: response.statusText,
|
|
1202
|
-
headers: response.headers
|
|
1203
|
-
});
|
|
1204
|
-
}
|
|
1205
|
-
/**
|
|
1206
|
-
* Does the SDK transport have an `eventStore`? Reaches into the SDK's
|
|
1207
|
-
* private field because the option isn't surfaced on the public API —
|
|
1208
|
-
* we only need a yes/no for keepalive policy.
|
|
1209
|
-
*/
|
|
1210
|
-
eventStoreConfigured() {
|
|
1211
|
-
return this._eventStore !== void 0;
|
|
1212
|
-
}
|
|
1213
1141
|
getCorsHeaders({ forPreflight } = {}) {
|
|
1214
1142
|
const merged = {
|
|
1215
1143
|
...DEFAULT_CORS_OPTIONS,
|
|
@@ -1245,19 +1173,15 @@ var WorkerTransport = class extends WebStandardStreamableHTTPServerTransport {
|
|
|
1245
1173
|
this._bridgeInstalled = true;
|
|
1246
1174
|
}
|
|
1247
1175
|
async captureInitializeParams(request, handleOptions) {
|
|
1248
|
-
this._pendingRequestId = void 0;
|
|
1249
1176
|
if (request.method !== "POST") return;
|
|
1250
1177
|
try {
|
|
1251
1178
|
const parsed = handleOptions?.parsedBody ?? await request.clone().json();
|
|
1252
|
-
const
|
|
1253
|
-
const init = messages.find((m) => typeof m === "object" && m !== null && isInitializeRequest(m));
|
|
1179
|
+
const init = (Array.isArray(parsed) ? parsed : [parsed]).find((m) => typeof m === "object" && m !== null && isInitializeRequest(m));
|
|
1254
1180
|
if (init && isInitializeRequest(init)) this._capturedInitializeParams = {
|
|
1255
1181
|
capabilities: init.params.capabilities,
|
|
1256
1182
|
clientInfo: init.params.clientInfo,
|
|
1257
1183
|
protocolVersion: init.params.protocolVersion
|
|
1258
1184
|
};
|
|
1259
|
-
const firstRequest = messages.find((m) => typeof m === "object" && m !== null && "id" in m && "method" in m);
|
|
1260
|
-
if (firstRequest) this._pendingRequestId = firstRequest.id;
|
|
1261
1185
|
} catch {}
|
|
1262
1186
|
}
|
|
1263
1187
|
async restoreState() {
|
|
@@ -1294,67 +1218,81 @@ var WorkerTransport = class extends WebStandardStreamableHTTPServerTransport {
|
|
|
1294
1218
|
}
|
|
1295
1219
|
};
|
|
1296
1220
|
//#endregion
|
|
1297
|
-
//#region src/mcp/
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
}
|
|
1305
|
-
//#endregion
|
|
1306
|
-
//#region src/mcp/handler.ts
|
|
1307
|
-
function createMcpHandler(server, options = {}) {
|
|
1221
|
+
//#region src/mcp/handler-legacy.ts
|
|
1222
|
+
/**
|
|
1223
|
+
* Create a sessionful Legacy MCP handler backed by SDK v1.
|
|
1224
|
+
*
|
|
1225
|
+
* New Stateless servers should use `createMcpHandler` from
|
|
1226
|
+
* `agents/mcp/server` instead.
|
|
1227
|
+
*/
|
|
1228
|
+
function createLegacyMcpHandler(server, options = {}) {
|
|
1308
1229
|
const route = options.route ?? "/mcp";
|
|
1309
1230
|
const { route: _route, authContext, transport: providedTransport, ...transportOptions } = options;
|
|
1310
1231
|
return async (request, _env, ctx) => {
|
|
1311
1232
|
const url = new URL(request.url);
|
|
1312
1233
|
if (route && url.pathname !== route) return new Response("Not Found", { status: 404 });
|
|
1313
1234
|
const transport = providedTransport ?? new WorkerTransport(transportOptions);
|
|
1314
|
-
const
|
|
1315
|
-
if (authContext) return authContext;
|
|
1316
|
-
if (ctx.props && Object.keys(ctx.props).length > 0) return { props: ctx.props };
|
|
1317
|
-
};
|
|
1318
|
-
const handleRequest = async () => {
|
|
1319
|
-
return await transport.handleRequest(request);
|
|
1320
|
-
};
|
|
1321
|
-
const resolvedAuthContext = buildAuthContext();
|
|
1235
|
+
const resolvedAuthContext = authContext ?? (ctx.props && Object.keys(ctx.props).length > 0 ? { props: ctx.props } : void 0);
|
|
1322
1236
|
if (!transport.started) {
|
|
1323
|
-
if (server instanceof McpServer ? server.isConnected() : server.transport !== void 0) throw new Error("Server is already connected to a transport. Create a new McpServer instance per request for stateless handlers.");
|
|
1237
|
+
if (server instanceof McpServer$1 ? server.isConnected() : server.transport !== void 0) throw new Error("Server is already connected to a transport. Create a new McpServer instance per request for stateless handlers.");
|
|
1324
1238
|
await server.connect(transport);
|
|
1325
1239
|
}
|
|
1240
|
+
const handleRequest = () => transport.handleRequest(request);
|
|
1326
1241
|
try {
|
|
1327
|
-
|
|
1328
|
-
else return await handleRequest();
|
|
1242
|
+
return resolvedAuthContext ? await runWithAuthContext(resolvedAuthContext, handleRequest) : await handleRequest();
|
|
1329
1243
|
} catch (error) {
|
|
1330
1244
|
console.error("MCP handler error:", error);
|
|
1331
|
-
return
|
|
1245
|
+
return Response.json({
|
|
1332
1246
|
jsonrpc: "2.0",
|
|
1333
1247
|
error: {
|
|
1334
1248
|
code: -32603,
|
|
1335
1249
|
message: error instanceof Error ? error.message : "Internal server error"
|
|
1336
1250
|
},
|
|
1337
1251
|
id: null
|
|
1338
|
-
}
|
|
1339
|
-
status: 500,
|
|
1340
|
-
headers: { "Content-Type": "application/json" }
|
|
1341
|
-
});
|
|
1252
|
+
}, { status: 500 });
|
|
1342
1253
|
}
|
|
1343
1254
|
};
|
|
1344
1255
|
}
|
|
1256
|
+
//#endregion
|
|
1257
|
+
//#region src/mcp/handler-warning.ts
|
|
1258
|
+
let didWarnAboutLegacyCreateMcpHandlerOverload = false;
|
|
1259
|
+
function warnLegacyCreateMcpHandlerOverload() {
|
|
1260
|
+
if (didWarnAboutLegacyCreateMcpHandlerOverload) return;
|
|
1261
|
+
didWarnAboutLegacyCreateMcpHandlerOverload = true;
|
|
1262
|
+
console.warn("[agents/mcp] Passing an MCP SDK v1 server to createMcpHandler is deprecated and will be removed in the next major version. Pass an @modelcontextprotocol/server factory to createMcpHandler. To temporarily retain sessionful SDK v1 behavior while migrating, use createLegacyMcpHandler.");
|
|
1263
|
+
}
|
|
1264
|
+
//#endregion
|
|
1265
|
+
//#region src/mcp/handler-compat.ts
|
|
1266
|
+
function createMcpHandler(serverOrFactory, options = {}) {
|
|
1267
|
+
if (typeof serverOrFactory === "function") return createStatelessMcpHandler(serverOrFactory, options);
|
|
1268
|
+
if (serverOrFactory instanceof McpServer$1 || serverOrFactory instanceof Server$1) {
|
|
1269
|
+
warnLegacyCreateMcpHandlerOverload();
|
|
1270
|
+
return createLegacyMcpHandler(serverOrFactory, options);
|
|
1271
|
+
}
|
|
1272
|
+
throw new TypeError("createMcpHandler received an unsupported server. Pass a factory returning McpServer or Server from \"@modelcontextprotocol/server\", or use createLegacyMcpHandler with an MCP SDK v1 server.");
|
|
1273
|
+
}
|
|
1345
1274
|
let didWarnAboutExperimentalCreateMcpHandler = false;
|
|
1346
1275
|
/**
|
|
1347
|
-
* @deprecated
|
|
1276
|
+
* @deprecated Pass an SDK v2 factory to createMcpHandler.
|
|
1277
|
+
* experimental_createMcpHandler will be removed in the next major version.
|
|
1278
|
+
* Use createLegacyMcpHandler only to temporarily retain sessionful SDK v1
|
|
1279
|
+
* behavior while migrating.
|
|
1348
1280
|
*/
|
|
1349
1281
|
function experimental_createMcpHandler(server, options = {}) {
|
|
1350
1282
|
if (!didWarnAboutExperimentalCreateMcpHandler) {
|
|
1351
1283
|
didWarnAboutExperimentalCreateMcpHandler = true;
|
|
1352
|
-
console.warn("experimental_createMcpHandler is deprecated
|
|
1284
|
+
console.warn("experimental_createMcpHandler is deprecated and will be removed in the next major version. Pass an @modelcontextprotocol/server factory to createMcpHandler. To temporarily retain sessionful SDK v1 behavior while migrating, use createLegacyMcpHandler.");
|
|
1353
1285
|
}
|
|
1354
|
-
return
|
|
1286
|
+
return createLegacyMcpHandler(server, options);
|
|
1355
1287
|
}
|
|
1356
1288
|
//#endregion
|
|
1357
|
-
//#region src/mcp/
|
|
1289
|
+
//#region src/mcp/legacy-agent.ts
|
|
1290
|
+
/**
|
|
1291
|
+
* @deprecated McpAgent is feature-frozen. Migrate to an SDK v2 factory with
|
|
1292
|
+
* createMcpHandler from agents/mcp/server. When sessionful features prevent an
|
|
1293
|
+
* immediate migration, run the stateless route beside the existing McpAgent
|
|
1294
|
+
* route until clients transition and sessions drain.
|
|
1295
|
+
*/
|
|
1358
1296
|
var McpAgent = class McpAgent extends Agent {
|
|
1359
1297
|
constructor(..._args) {
|
|
1360
1298
|
super(..._args);
|
|
@@ -1502,6 +1440,7 @@ var McpAgent = class McpAgent extends Agent {
|
|
|
1502
1440
|
else this.props = await this.ctx.storage.get("props");
|
|
1503
1441
|
await this.init();
|
|
1504
1442
|
const server = await this.server;
|
|
1443
|
+
if (server instanceof McpServer || server instanceof Server) throw new TypeError("McpAgent uses MCP SDK v1 and cannot serve McpServer from \"@modelcontextprotocol/server\". For MCP SDK v2, use createMcpHandler. Existing McpAgent applications should continue importing McpServer from \"@modelcontextprotocol/sdk/server/mcp.js\".");
|
|
1505
1444
|
this._transport = this.initTransport();
|
|
1506
1445
|
if (!this._transport) throw new Error("Failed to initialize transport");
|
|
1507
1446
|
await server.connect(this._transport);
|
|
@@ -1698,6 +1637,6 @@ var McpAgent = class McpAgent extends Agent {
|
|
|
1698
1637
|
};
|
|
1699
1638
|
McpAgent.STREAM_REQS_KEY_PREFIX = "__mcp_stream_reqs__:";
|
|
1700
1639
|
//#endregion
|
|
1701
|
-
export { DurableObjectEventStore, ElicitRequestSchema, MCP_SERVER_ID_MAX_LENGTH, McpAgent, RPCClientTransport, RPCServerTransport, RPC_DO_PREFIX, SSEEdgeClientTransport, StreamableHTTPEdgeClientTransport, WorkerTransport, createMcpHandler, experimental_createMcpHandler, getMcpAuthContext, normalizeServerId };
|
|
1640
|
+
export { DurableObjectEventStore, ElicitRequestSchema, MCP_SERVER_ID_MAX_LENGTH, McpAgent, RPCClientTransport, RPCServerTransport, RPC_DO_PREFIX, SSEEdgeClientTransport, StreamableHTTPEdgeClientTransport, WorkerTransport, createLegacyMcpHandler, createMcpHandler, experimental_createMcpHandler, getMcpAuthContext, normalizeServerId };
|
|
1702
1641
|
|
|
1703
1642
|
//# sourceMappingURL=index.js.map
|