agents 0.19.0 → 0.20.0
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-Btk9ETS-.d.ts} +997 -356
- package/dist/agent-tool-types.d.ts +1 -1
- package/dist/{agent-tools-BFbzVLFc.d.ts → agent-tools-UuScsJg3.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/{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-8hQN_kC3.js +367 -0
- package/dist/handler-stateless-8hQN_kC3.js.map +1 -0
- package/dist/handler-stateless-C_bo-Ytq.d.ts +107 -0
- package/dist/index.d.ts +12 -12
- package/dist/index.js +3 -2
- 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 +84 -79
- 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/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/securing-mcp-servers.md +9 -6
- package/package.json +28 -7
- package/dist/client-CcjiFpTf.js.map +0 -1
- package/dist/connector-CdldGF3h.js.map +0 -1
package/dist/mcp/client.d.ts
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
|
-
At as
|
|
3
|
-
Ct as
|
|
4
|
-
Dt as
|
|
5
|
-
Et as
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
2
|
+
At as MCPServerFilter,
|
|
3
|
+
Ct as MCPClientManager,
|
|
4
|
+
Dt as MCPConnectionResult,
|
|
5
|
+
Et as MCPClientOAuthResult,
|
|
6
|
+
Ft as normalizeServerId,
|
|
7
|
+
Mt as MCP_SERVER_ID_MAX_LENGTH,
|
|
8
|
+
Nt as RegisterServerOptions,
|
|
9
|
+
Ot as MCPDiscoverResult,
|
|
10
|
+
Pt as getNamespacedData,
|
|
11
|
+
St as MCPClientElicitationHandlers,
|
|
12
|
+
Tt as MCPClientOAuthCallbackConfig,
|
|
13
|
+
_t as ElicitRequest,
|
|
14
|
+
bt as MCPAIToolSet,
|
|
15
|
+
jt as MCPServerOptions,
|
|
16
|
+
kt as MCPOAuthCallbackResult,
|
|
17
|
+
vt as ElicitResult,
|
|
18
|
+
wt as MCPClientManagerOptions,
|
|
19
|
+
xt as MCPClientElicitationHandler,
|
|
20
|
+
yt as MCPAITool
|
|
21
|
+
} from "../agent-tool-types-Btk9ETS-.js";
|
|
20
22
|
export {
|
|
23
|
+
type ElicitRequest,
|
|
24
|
+
type ElicitResult,
|
|
21
25
|
MCPAITool,
|
|
22
26
|
MCPAIToolSet,
|
|
23
27
|
MCPClientElicitationHandler,
|
package/dist/mcp/client.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as normalizeServerId, n as MCP_SERVER_ID_MAX_LENGTH, r as getNamespacedData, t as MCPClientManager } from "../client-
|
|
1
|
+
import { i as normalizeServerId, n as MCP_SERVER_ID_MAX_LENGTH, r as getNamespacedData, t as MCPClientManager } from "../client-zqKcsyFa.js";
|
|
2
2
|
export { MCPClientManager, MCP_SERVER_ID_MAX_LENGTH, getNamespacedData, normalizeServerId };
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
n as AgentsOAuthProvider,
|
|
3
3
|
r as DurableObjectOAuthClientProvider,
|
|
4
4
|
t as AgentMcpOAuthProvider
|
|
5
|
-
} from "../do-oauth-client-provider-
|
|
5
|
+
} from "../do-oauth-client-provider-VTZj2VtM.js";
|
|
6
6
|
export {
|
|
7
7
|
AgentMcpOAuthProvider,
|
|
8
8
|
AgentsOAuthProvider,
|
|
@@ -68,23 +68,33 @@ var DurableObjectOAuthClientProvider = class {
|
|
|
68
68
|
clientInfoKey(clientId) {
|
|
69
69
|
return `${this.keyPrefix(clientId)}/client_info/`;
|
|
70
70
|
}
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
discoveryStateKey() {
|
|
72
|
+
return `/${this.clientName}/${this.serverId}/oauth_discovery`;
|
|
73
|
+
}
|
|
74
|
+
async saveDiscoveryState(state) {
|
|
75
|
+
await this.storage.put(this.discoveryStateKey(), state);
|
|
76
|
+
}
|
|
77
|
+
async discoveryState() {
|
|
78
|
+
return await this.storage.get(this.discoveryStateKey()) ?? void 0;
|
|
79
|
+
}
|
|
80
|
+
async clientInformation(_context) {
|
|
81
|
+
if (!this._clientId_) return void 0;
|
|
73
82
|
return await this.storage.get(this.clientInfoKey(this.clientId)) ?? void 0;
|
|
74
83
|
}
|
|
75
|
-
async saveClientInformation(clientInformation) {
|
|
76
|
-
await this.storage.put(this.clientInfoKey(clientInformation.client_id), clientInformation);
|
|
84
|
+
async saveClientInformation(clientInformation, _context) {
|
|
77
85
|
this.clientId = clientInformation.client_id;
|
|
86
|
+
await this.storage.put(this.clientInfoKey(clientInformation.client_id), clientInformation);
|
|
78
87
|
}
|
|
79
88
|
tokenKey(clientId) {
|
|
80
89
|
return `${this.keyPrefix(clientId)}/token`;
|
|
81
90
|
}
|
|
82
|
-
async tokens() {
|
|
83
|
-
if (!this._clientId_) return;
|
|
91
|
+
async tokens(_context) {
|
|
92
|
+
if (!this._clientId_) return void 0;
|
|
84
93
|
return await this.storage.get(this.tokenKey(this.clientId)) ?? void 0;
|
|
85
94
|
}
|
|
86
|
-
async saveTokens(tokens) {
|
|
95
|
+
async saveTokens(tokens, _context) {
|
|
87
96
|
await this.storage.put(this.tokenKey(this.clientId), tokens);
|
|
97
|
+
await this.storage.delete(this.discoveryStateKey());
|
|
88
98
|
}
|
|
89
99
|
get authUrl() {
|
|
90
100
|
return this._authUrl_;
|
|
@@ -166,12 +176,15 @@ var DurableObjectOAuthClientProvider = class {
|
|
|
166
176
|
await this.storage.delete(challengeKey);
|
|
167
177
|
}
|
|
168
178
|
async invalidateCredentials(scope) {
|
|
169
|
-
if (!this._clientId_) return;
|
|
170
179
|
const deleteKeys = [];
|
|
171
|
-
if (scope === "all" || scope === "
|
|
172
|
-
if (
|
|
173
|
-
|
|
174
|
-
|
|
180
|
+
if (scope === "all" || scope === "discovery") deleteKeys.push(this.discoveryStateKey());
|
|
181
|
+
if (this._clientId_) {
|
|
182
|
+
const clientId = this.clientId;
|
|
183
|
+
if (scope === "all" || scope === "client") deleteKeys.push(this.clientInfoKey(clientId));
|
|
184
|
+
if (scope === "all" || scope === "tokens") deleteKeys.push(this.tokenKey(clientId));
|
|
185
|
+
if (scope === "all" || scope === "verifier") deleteKeys.push(...await this.codeVerifierKeys(clientId, { includeChallengeKeys: true }));
|
|
186
|
+
}
|
|
187
|
+
if (deleteKeys.length > 0) await this.storage.delete([...new Set(deleteKeys)]);
|
|
175
188
|
}
|
|
176
189
|
codeVerifierKey(clientId) {
|
|
177
190
|
return `${this.keyPrefix(clientId)}/code_verifier`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"do-oauth-client-provider.js","names":[],"sources":["../../src/mcp/do-oauth-client-provider.ts"],"sourcesContent":["import type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport type {\n OAuthClientInformation,\n OAuthClientInformationFull,\n OAuthClientMetadata,\n OAuthTokens\n} from \"@modelcontextprotocol/sdk/shared/auth.js\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { nanoid } from \"nanoid\";\n\nconst STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes\n\nconst codeVerifierStateStorage = new AsyncLocalStorage<{\n state: string;\n servedKey?: string;\n}>();\n\ninterface StoredState {\n nonce: string;\n serverId: string;\n createdAt: number;\n}\n\ninterface StoredCodeVerifier {\n verifier: string;\n createdAt: number;\n}\n\n// A slight extension to the standard OAuthClientProvider interface because `redirectToAuthorization` doesn't give us the interface we need\n// This allows us to track authentication for a specific server and associated dynamic client registration\nexport interface AgentMcpOAuthProvider extends OAuthClientProvider {\n authUrl: string | undefined;\n clientId: string | undefined;\n serverId: string | undefined;\n checkState(\n state: string\n ): Promise<{ valid: boolean; serverId?: string; error?: string }>;\n consumeState(state: string): Promise<void>;\n runWithCodeVerifierState?<T>(\n state: string,\n callback: () => Promise<T>\n ): Promise<T>;\n deleteCodeVerifier(): Promise<void>;\n}\n\nfunction parseOAuthState(\n state: string\n): { nonce: string; serverId: string } | undefined {\n const parts = state.split(\".\");\n if (parts.length !== 2) {\n return undefined;\n }\n\n const [nonce, serverId] = parts;\n if (!nonce || !serverId) {\n return undefined;\n }\n\n return { nonce, serverId };\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nasync function createCodeChallenge(verifier: string): Promise<string> {\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(verifier)\n );\n return base64UrlEncode(new Uint8Array(digest));\n}\n\nfunction isExpired(createdAt: number): boolean {\n return Date.now() - createdAt > STATE_EXPIRATION_MS;\n}\n\n/**\n * @deprecated Use {@link AgentMcpOAuthProvider} instead.\n */\nexport type AgentsOAuthProvider = AgentMcpOAuthProvider;\n\nexport class DurableObjectOAuthClientProvider implements AgentMcpOAuthProvider {\n private _authUrl_: string | undefined;\n private _serverId_: string | undefined;\n private _clientId_: string | undefined;\n\n constructor(\n public storage: DurableObjectStorage,\n public clientName: string,\n public baseRedirectUrl: string\n ) {\n if (!storage) {\n throw new Error(\n \"DurableObjectOAuthClientProvider requires a valid DurableObjectStorage instance\"\n );\n }\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return {\n client_name: this.clientName,\n client_uri: this.clientUri,\n grant_types: [\"authorization_code\", \"refresh_token\"],\n redirect_uris: [this.redirectUrl],\n response_types: [\"code\"],\n token_endpoint_auth_method: \"none\"\n };\n }\n\n get clientUri() {\n return new URL(this.redirectUrl).origin;\n }\n\n get redirectUrl() {\n return this.baseRedirectUrl;\n }\n\n get clientId() {\n if (!this._clientId_) {\n throw new Error(\"Trying to access clientId before it was set\");\n }\n return this._clientId_;\n }\n\n set clientId(clientId_: string) {\n this._clientId_ = clientId_;\n }\n\n get serverId() {\n if (!this._serverId_) {\n throw new Error(\"Trying to access serverId before it was set\");\n }\n return this._serverId_;\n }\n\n set serverId(serverId_: string) {\n this._serverId_ = serverId_;\n }\n\n keyPrefix(clientId: string) {\n return `/${this.clientName}/${this.serverId}/${clientId}`;\n }\n\n clientInfoKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/client_info/`;\n }\n\n async clientInformation(): Promise<OAuthClientInformation | undefined> {\n if (!this._clientId_) {\n return undefined;\n }\n return (\n (await this.storage.get<OAuthClientInformation>(\n this.clientInfoKey(this.clientId)\n )) ?? undefined\n );\n }\n\n async saveClientInformation(\n clientInformation: OAuthClientInformationFull\n ): Promise<void> {\n await this.storage.put(\n this.clientInfoKey(clientInformation.client_id),\n clientInformation\n );\n this.clientId = clientInformation.client_id;\n }\n\n tokenKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/token`;\n }\n\n async tokens(): Promise<OAuthTokens | undefined> {\n if (!this._clientId_) {\n return undefined;\n }\n return (\n (await this.storage.get<OAuthTokens>(this.tokenKey(this.clientId))) ??\n undefined\n );\n }\n\n async saveTokens(tokens: OAuthTokens): Promise<void> {\n await this.storage.put(this.tokenKey(this.clientId), tokens);\n }\n\n get authUrl() {\n return this._authUrl_;\n }\n\n stateKey(nonce: string) {\n return `/${this.clientName}/${this.serverId}/state/${nonce}`;\n }\n\n async state(): Promise<string> {\n const nonce = nanoid();\n const state = `${nonce}.${this.serverId}`;\n const storedState: StoredState = {\n nonce,\n serverId: this.serverId,\n createdAt: Date.now()\n };\n await this.storage.put(this.stateKey(nonce), storedState);\n return state;\n }\n\n async checkState(\n state: string\n ): Promise<{ valid: boolean; serverId?: string; error?: string }> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n return { valid: false, error: \"Invalid state format\" };\n }\n\n const { nonce, serverId } = parsed;\n const key = this.stateKey(nonce);\n const storedState = await this.storage.get<StoredState>(key);\n\n if (!storedState) {\n return { valid: false, error: \"State not found or already used\" };\n }\n\n if (storedState.serverId !== serverId) {\n await this.storage.delete(key);\n return { valid: false, error: \"State serverId mismatch\" };\n }\n\n if (isExpired(storedState.createdAt)) {\n const deleteKeys = [key];\n if (this._clientId_) {\n deleteKeys.push(this.stateCodeVerifierKey(this.clientId, nonce));\n }\n await this.storage.delete(deleteKeys);\n return { valid: false, error: \"State expired\" };\n }\n\n return { valid: true, serverId };\n }\n\n async consumeState(state: string): Promise<void> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n // This should never happen since checkState validates format first.\n // Log for debugging but don't throw - state consumption is best-effort.\n console.warn(`[OAuth] consumeState called with invalid state format`);\n return;\n }\n await this.storage.delete(this.stateKey(parsed.nonce));\n }\n\n async redirectToAuthorization(authUrl: URL): Promise<void> {\n this._authUrl_ = authUrl.toString();\n\n const clientId = this._clientId_;\n const serverId = this._serverId_;\n if (!clientId || !serverId) {\n return;\n }\n\n const state = authUrl.searchParams.get(\"state\");\n const codeChallenge = authUrl.searchParams.get(\"code_challenge\");\n if (!state || !codeChallenge) {\n return;\n }\n\n const parsed = parseOAuthState(state);\n if (!parsed || parsed.serverId !== serverId) {\n return;\n }\n\n const challengeKey = this.challengeCodeVerifierKey(clientId, codeChallenge);\n const pendingVerifier =\n await this.storage.get<StoredCodeVerifier>(challengeKey);\n if (!pendingVerifier) {\n return;\n }\n\n if (isExpired(pendingVerifier.createdAt)) {\n await this.storage.delete(challengeKey);\n return;\n }\n\n await this.storage.put(\n this.stateCodeVerifierKey(clientId, parsed.nonce),\n pendingVerifier\n );\n await this.storage.delete(challengeKey);\n }\n\n async invalidateCredentials(\n scope: \"all\" | \"client\" | \"tokens\" | \"verifier\"\n ): Promise<void> {\n if (!this._clientId_) return;\n\n const deleteKeys: string[] = [];\n\n if (scope === \"all\" || scope === \"client\") {\n deleteKeys.push(this.clientInfoKey(this.clientId));\n }\n if (scope === \"all\" || scope === \"tokens\") {\n deleteKeys.push(this.tokenKey(this.clientId));\n }\n if (scope === \"all\" || scope === \"verifier\") {\n deleteKeys.push(\n ...(await this.codeVerifierKeys(this.clientId, {\n includeChallengeKeys: true\n }))\n );\n }\n\n if (deleteKeys.length > 0) {\n await this.storage.delete(deleteKeys);\n }\n }\n\n codeVerifierKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier`;\n }\n\n stateCodeVerifierPrefix(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier/`;\n }\n\n stateCodeVerifierKey(clientId: string, nonce: string) {\n return `${this.stateCodeVerifierPrefix(clientId)}${nonce}`;\n }\n\n challengeCodeVerifierPrefix(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier_challenge/`;\n }\n\n challengeCodeVerifierKey(clientId: string, codeChallenge: string) {\n return `${this.challengeCodeVerifierPrefix(clientId)}${codeChallenge}`;\n }\n\n async codeVerifierKeys(\n clientId: string,\n options: { includeChallengeKeys?: boolean } = {}\n ): Promise<string[]> {\n const legacyKey = this.codeVerifierKey(clientId);\n const keys: string[] = [];\n\n if (await this.storage.get(legacyKey)) {\n keys.push(legacyKey);\n }\n\n const stateKeys = await this.storage.list({\n prefix: this.stateCodeVerifierPrefix(clientId)\n });\n keys.push(...stateKeys.keys());\n\n if (options.includeChallengeKeys) {\n const challengeKeys = await this.storage.list({\n prefix: this.challengeCodeVerifierPrefix(clientId)\n });\n keys.push(...challengeKeys.keys());\n }\n\n return keys;\n }\n\n async saveCodeVerifier(verifier: string): Promise<void> {\n await this.deleteExpiredChallengeCodeVerifiers(this.clientId);\n\n const codeChallenge = await createCodeChallenge(verifier);\n const storedVerifier: StoredCodeVerifier = {\n verifier,\n createdAt: Date.now()\n };\n\n await this.storage.put(\n this.challengeCodeVerifierKey(this.clientId, codeChallenge),\n storedVerifier\n );\n }\n\n private async deleteExpiredChallengeCodeVerifiers(\n clientId: string\n ): Promise<void> {\n const challengeVerifiers = await this.storage.list<StoredCodeVerifier>({\n prefix: this.challengeCodeVerifierPrefix(clientId)\n });\n const expiredKeys = [...challengeVerifiers.entries()]\n .filter(([, storedVerifier]) => isExpired(storedVerifier.createdAt))\n .map(([key]) => key);\n if (expiredKeys.length > 0) {\n await this.storage.delete(expiredKeys);\n }\n }\n\n async codeVerifier(): Promise<string> {\n const context = codeVerifierStateStorage.getStore();\n if (context) {\n const stateVerifier = await this.codeVerifierForState(context.state);\n if (stateVerifier) {\n context.servedKey = stateVerifier.key;\n return stateVerifier.verifier;\n }\n }\n\n const legacyVerifier = await this.storage.get<string>(\n this.codeVerifierKey(this.clientId)\n );\n if (legacyVerifier) {\n if (context) {\n context.servedKey = this.codeVerifierKey(this.clientId);\n }\n return legacyVerifier;\n }\n\n if (context) {\n throw new Error(\"No code verifier found for OAuth state\");\n }\n\n const pendingVerifiers = await this.storage.list<StoredCodeVerifier>({\n prefix: this.stateCodeVerifierPrefix(this.clientId)\n });\n const unexpiredPendingVerifiers = [...pendingVerifiers.entries()].filter(\n ([, storedVerifier]) => !isExpired(storedVerifier.createdAt)\n );\n const expiredKeys = [...pendingVerifiers.entries()]\n .filter(([, storedVerifier]) => isExpired(storedVerifier.createdAt))\n .map(([key]) => key);\n if (expiredKeys.length > 0) {\n await this.storage.delete(expiredKeys);\n }\n\n if (unexpiredPendingVerifiers.length === 1) {\n const [[, storedVerifier]] = unexpiredPendingVerifiers;\n return storedVerifier.verifier;\n }\n\n if (unexpiredPendingVerifiers.length > 1) {\n throw new Error(\n \"Multiple OAuth code verifiers are pending; complete authorization with the callback state\"\n );\n }\n\n throw new Error(\"No code verifier found\");\n }\n\n private async codeVerifierForState(\n state: string\n ): Promise<{ key: string; verifier: string } | undefined> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n throw new Error(\"Invalid state format\");\n }\n\n const key = this.stateCodeVerifierKey(this.clientId, parsed.nonce);\n const storedVerifier = await this.storage.get<StoredCodeVerifier>(key);\n if (!storedVerifier) {\n return undefined;\n }\n\n if (isExpired(storedVerifier.createdAt)) {\n await this.storage.delete(key);\n throw new Error(\"Code verifier expired\");\n }\n\n return { key, verifier: storedVerifier.verifier };\n }\n\n async runWithCodeVerifierState<T>(\n state: string,\n callback: () => Promise<T>\n ): Promise<T> {\n return codeVerifierStateStorage.run({ state }, callback);\n }\n\n async deleteCodeVerifier(): Promise<void> {\n const context = codeVerifierStateStorage.getStore();\n if (context?.servedKey) {\n await this.storage.delete(context.servedKey);\n return;\n }\n\n if (context) {\n const parsed = parseOAuthState(context.state);\n if (parsed) {\n await this.storage.delete(\n this.stateCodeVerifierKey(this.clientId, parsed.nonce)\n );\n return;\n }\n }\n\n const keys = await this.codeVerifierKeys(this.clientId);\n if (keys.length > 0) {\n await this.storage.delete(keys);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"do-oauth-client-provider.js","names":[],"sources":["../../src/mcp/do-oauth-client-provider.ts"],"sourcesContent":["import type {\n OAuthClientInformationContext,\n OAuthClientMetadata,\n OAuthClientProvider,\n OAuthDiscoveryState,\n StoredOAuthClientInformation,\n StoredOAuthTokens\n} from \"@modelcontextprotocol/client\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { nanoid } from \"nanoid\";\n\nconst STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes\n\nconst codeVerifierStateStorage = new AsyncLocalStorage<{\n state: string;\n servedKey?: string;\n}>();\n\ninterface StoredState {\n nonce: string;\n serverId: string;\n createdAt: number;\n}\n\ninterface StoredCodeVerifier {\n verifier: string;\n createdAt: number;\n}\n\n// A slight extension to the standard OAuthClientProvider interface because `redirectToAuthorization` doesn't give us the interface we need\n// This allows us to track authentication for a specific server and associated dynamic client registration\nexport interface AgentMcpOAuthProvider extends OAuthClientProvider {\n authUrl: string | undefined;\n clientId: string | undefined;\n serverId: string | undefined;\n checkState(\n state: string\n ): Promise<{ valid: boolean; serverId?: string; error?: string }>;\n consumeState(state: string): Promise<void>;\n runWithCodeVerifierState?<T>(\n state: string,\n callback: () => Promise<T>\n ): Promise<T>;\n deleteCodeVerifier(): Promise<void>;\n}\n\nfunction parseOAuthState(\n state: string\n): { nonce: string; serverId: string } | undefined {\n const parts = state.split(\".\");\n if (parts.length !== 2) {\n return undefined;\n }\n\n const [nonce, serverId] = parts;\n if (!nonce || !serverId) {\n return undefined;\n }\n\n return { nonce, serverId };\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nasync function createCodeChallenge(verifier: string): Promise<string> {\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(verifier)\n );\n return base64UrlEncode(new Uint8Array(digest));\n}\n\nfunction isExpired(createdAt: number): boolean {\n return Date.now() - createdAt > STATE_EXPIRATION_MS;\n}\n\n/**\n * @deprecated Use {@link AgentMcpOAuthProvider} instead.\n */\nexport type AgentsOAuthProvider = AgentMcpOAuthProvider;\n\nexport class DurableObjectOAuthClientProvider implements AgentMcpOAuthProvider {\n private _authUrl_: string | undefined;\n private _serverId_: string | undefined;\n private _clientId_: string | undefined;\n\n constructor(\n public storage: DurableObjectStorage,\n public clientName: string,\n public baseRedirectUrl: string\n ) {\n if (!storage) {\n throw new Error(\n \"DurableObjectOAuthClientProvider requires a valid DurableObjectStorage instance\"\n );\n }\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return {\n client_name: this.clientName,\n client_uri: this.clientUri,\n grant_types: [\"authorization_code\", \"refresh_token\"],\n redirect_uris: [this.redirectUrl],\n response_types: [\"code\"],\n token_endpoint_auth_method: \"none\"\n };\n }\n\n get clientUri() {\n return new URL(this.redirectUrl).origin;\n }\n\n get redirectUrl() {\n return this.baseRedirectUrl;\n }\n\n get clientId() {\n if (!this._clientId_) {\n throw new Error(\"Trying to access clientId before it was set\");\n }\n return this._clientId_;\n }\n\n set clientId(clientId_: string) {\n this._clientId_ = clientId_;\n }\n\n get serverId() {\n if (!this._serverId_) {\n throw new Error(\"Trying to access serverId before it was set\");\n }\n return this._serverId_;\n }\n\n set serverId(serverId_: string) {\n this._serverId_ = serverId_;\n }\n\n keyPrefix(clientId: string) {\n return `/${this.clientName}/${this.serverId}/${clientId}`;\n }\n\n clientInfoKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/client_info/`;\n }\n\n discoveryStateKey() {\n return `/${this.clientName}/${this.serverId}/oauth_discovery`;\n }\n\n async saveDiscoveryState(state: OAuthDiscoveryState): Promise<void> {\n await this.storage.put(this.discoveryStateKey(), state);\n }\n\n async discoveryState(): Promise<OAuthDiscoveryState | undefined> {\n return (\n (await this.storage.get<OAuthDiscoveryState>(this.discoveryStateKey())) ??\n undefined\n );\n }\n\n async clientInformation(\n _context?: OAuthClientInformationContext\n ): Promise<StoredOAuthClientInformation | undefined> {\n if (!this._clientId_) return undefined;\n return (\n (await this.storage.get<StoredOAuthClientInformation>(\n this.clientInfoKey(this.clientId)\n )) ?? undefined\n );\n }\n\n async saveClientInformation(\n clientInformation: StoredOAuthClientInformation,\n _context?: OAuthClientInformationContext\n ): Promise<void> {\n this.clientId = clientInformation.client_id;\n // Round-trip the SDK's issuer stamp verbatim. The SDK treats a credential\n // stamped for another issuer as absent, so one durable slot per MCP server\n // is both sufficient and safer than maintaining our own issuer index.\n await this.storage.put(\n this.clientInfoKey(clientInformation.client_id),\n clientInformation\n );\n }\n\n tokenKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/token`;\n }\n\n async tokens(\n _context?: OAuthClientInformationContext\n ): Promise<StoredOAuthTokens | undefined> {\n if (!this._clientId_) return undefined;\n return (\n (await this.storage.get<StoredOAuthTokens>(\n this.tokenKey(this.clientId)\n )) ?? undefined\n );\n }\n\n async saveTokens(\n tokens: StoredOAuthTokens,\n _context?: OAuthClientInformationContext\n ): Promise<void> {\n // Keep the SDK-owned issuer stamp intact for SEP-2352 validation. Discovery\n // is needed across the browser redirect, but once token issuance succeeds\n // it must not pin later re-authorization to this AS: a subsequent 401 must\n // re-read PRM so an authorization-server migration can be observed.\n await this.storage.put(this.tokenKey(this.clientId), tokens);\n await this.storage.delete(this.discoveryStateKey());\n }\n\n get authUrl() {\n return this._authUrl_;\n }\n\n stateKey(nonce: string) {\n return `/${this.clientName}/${this.serverId}/state/${nonce}`;\n }\n\n async state(): Promise<string> {\n const nonce = nanoid();\n const state = `${nonce}.${this.serverId}`;\n const storedState: StoredState = {\n nonce,\n serverId: this.serverId,\n createdAt: Date.now()\n };\n await this.storage.put(this.stateKey(nonce), storedState);\n return state;\n }\n\n async checkState(\n state: string\n ): Promise<{ valid: boolean; serverId?: string; error?: string }> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n return { valid: false, error: \"Invalid state format\" };\n }\n\n const { nonce, serverId } = parsed;\n const key = this.stateKey(nonce);\n const storedState = await this.storage.get<StoredState>(key);\n\n if (!storedState) {\n return { valid: false, error: \"State not found or already used\" };\n }\n\n if (storedState.serverId !== serverId) {\n await this.storage.delete(key);\n return { valid: false, error: \"State serverId mismatch\" };\n }\n\n if (isExpired(storedState.createdAt)) {\n const deleteKeys = [key];\n if (this._clientId_) {\n deleteKeys.push(this.stateCodeVerifierKey(this.clientId, nonce));\n }\n await this.storage.delete(deleteKeys);\n return { valid: false, error: \"State expired\" };\n }\n\n return { valid: true, serverId };\n }\n\n async consumeState(state: string): Promise<void> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n // This should never happen since checkState validates format first.\n // Log for debugging but don't throw - state consumption is best-effort.\n console.warn(`[OAuth] consumeState called with invalid state format`);\n return;\n }\n await this.storage.delete(this.stateKey(parsed.nonce));\n }\n\n async redirectToAuthorization(authUrl: URL): Promise<void> {\n this._authUrl_ = authUrl.toString();\n\n const clientId = this._clientId_;\n const serverId = this._serverId_;\n if (!clientId || !serverId) {\n return;\n }\n\n const state = authUrl.searchParams.get(\"state\");\n const codeChallenge = authUrl.searchParams.get(\"code_challenge\");\n if (!state || !codeChallenge) {\n return;\n }\n\n const parsed = parseOAuthState(state);\n if (!parsed || parsed.serverId !== serverId) {\n return;\n }\n\n const challengeKey = this.challengeCodeVerifierKey(clientId, codeChallenge);\n const pendingVerifier =\n await this.storage.get<StoredCodeVerifier>(challengeKey);\n if (!pendingVerifier) {\n return;\n }\n\n if (isExpired(pendingVerifier.createdAt)) {\n await this.storage.delete(challengeKey);\n return;\n }\n\n await this.storage.put(\n this.stateCodeVerifierKey(clientId, parsed.nonce),\n pendingVerifier\n );\n await this.storage.delete(challengeKey);\n }\n\n async invalidateCredentials(\n scope: \"all\" | \"client\" | \"tokens\" | \"verifier\" | \"discovery\"\n ): Promise<void> {\n const deleteKeys: string[] = [];\n\n if (scope === \"all\" || scope === \"discovery\") {\n deleteKeys.push(this.discoveryStateKey());\n }\n\n if (this._clientId_) {\n const clientId = this.clientId;\n if (scope === \"all\" || scope === \"client\") {\n deleteKeys.push(this.clientInfoKey(clientId));\n }\n if (scope === \"all\" || scope === \"tokens\") {\n deleteKeys.push(this.tokenKey(clientId));\n }\n if (scope === \"all\" || scope === \"verifier\") {\n deleteKeys.push(\n ...(await this.codeVerifierKeys(clientId, {\n includeChallengeKeys: true\n }))\n );\n }\n }\n\n if (deleteKeys.length > 0) {\n await this.storage.delete([...new Set(deleteKeys)]);\n }\n }\n\n codeVerifierKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier`;\n }\n\n stateCodeVerifierPrefix(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier/`;\n }\n\n stateCodeVerifierKey(clientId: string, nonce: string) {\n return `${this.stateCodeVerifierPrefix(clientId)}${nonce}`;\n }\n\n challengeCodeVerifierPrefix(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier_challenge/`;\n }\n\n challengeCodeVerifierKey(clientId: string, codeChallenge: string) {\n return `${this.challengeCodeVerifierPrefix(clientId)}${codeChallenge}`;\n }\n\n async codeVerifierKeys(\n clientId: string,\n options: { includeChallengeKeys?: boolean } = {}\n ): Promise<string[]> {\n const legacyKey = this.codeVerifierKey(clientId);\n const keys: string[] = [];\n\n if (await this.storage.get(legacyKey)) {\n keys.push(legacyKey);\n }\n\n const stateKeys = await this.storage.list({\n prefix: this.stateCodeVerifierPrefix(clientId)\n });\n keys.push(...stateKeys.keys());\n\n if (options.includeChallengeKeys) {\n const challengeKeys = await this.storage.list({\n prefix: this.challengeCodeVerifierPrefix(clientId)\n });\n keys.push(...challengeKeys.keys());\n }\n\n return keys;\n }\n\n async saveCodeVerifier(verifier: string): Promise<void> {\n await this.deleteExpiredChallengeCodeVerifiers(this.clientId);\n\n const codeChallenge = await createCodeChallenge(verifier);\n const storedVerifier: StoredCodeVerifier = {\n verifier,\n createdAt: Date.now()\n };\n\n await this.storage.put(\n this.challengeCodeVerifierKey(this.clientId, codeChallenge),\n storedVerifier\n );\n }\n\n private async deleteExpiredChallengeCodeVerifiers(\n clientId: string\n ): Promise<void> {\n const challengeVerifiers = await this.storage.list<StoredCodeVerifier>({\n prefix: this.challengeCodeVerifierPrefix(clientId)\n });\n const expiredKeys = [...challengeVerifiers.entries()]\n .filter(([, storedVerifier]) => isExpired(storedVerifier.createdAt))\n .map(([key]) => key);\n if (expiredKeys.length > 0) {\n await this.storage.delete(expiredKeys);\n }\n }\n\n async codeVerifier(): Promise<string> {\n const context = codeVerifierStateStorage.getStore();\n if (context) {\n const stateVerifier = await this.codeVerifierForState(context.state);\n if (stateVerifier) {\n context.servedKey = stateVerifier.key;\n return stateVerifier.verifier;\n }\n }\n\n const legacyVerifier = await this.storage.get<string>(\n this.codeVerifierKey(this.clientId)\n );\n if (legacyVerifier) {\n if (context) {\n context.servedKey = this.codeVerifierKey(this.clientId);\n }\n return legacyVerifier;\n }\n\n if (context) {\n throw new Error(\"No code verifier found for OAuth state\");\n }\n\n const pendingVerifiers = await this.storage.list<StoredCodeVerifier>({\n prefix: this.stateCodeVerifierPrefix(this.clientId)\n });\n const unexpiredPendingVerifiers = [...pendingVerifiers.entries()].filter(\n ([, storedVerifier]) => !isExpired(storedVerifier.createdAt)\n );\n const expiredKeys = [...pendingVerifiers.entries()]\n .filter(([, storedVerifier]) => isExpired(storedVerifier.createdAt))\n .map(([key]) => key);\n if (expiredKeys.length > 0) {\n await this.storage.delete(expiredKeys);\n }\n\n if (unexpiredPendingVerifiers.length === 1) {\n const [[, storedVerifier]] = unexpiredPendingVerifiers;\n return storedVerifier.verifier;\n }\n\n if (unexpiredPendingVerifiers.length > 1) {\n throw new Error(\n \"Multiple OAuth code verifiers are pending; complete authorization with the callback state\"\n );\n }\n\n throw new Error(\"No code verifier found\");\n }\n\n private async codeVerifierForState(\n state: string\n ): Promise<{ key: string; verifier: string } | undefined> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n throw new Error(\"Invalid state format\");\n }\n\n const key = this.stateCodeVerifierKey(this.clientId, parsed.nonce);\n const storedVerifier = await this.storage.get<StoredCodeVerifier>(key);\n if (!storedVerifier) {\n return undefined;\n }\n\n if (isExpired(storedVerifier.createdAt)) {\n await this.storage.delete(key);\n throw new Error(\"Code verifier expired\");\n }\n\n return { key, verifier: storedVerifier.verifier };\n }\n\n async runWithCodeVerifierState<T>(\n state: string,\n callback: () => Promise<T>\n ): Promise<T> {\n return codeVerifierStateStorage.run({ state }, callback);\n }\n\n async deleteCodeVerifier(): Promise<void> {\n const context = codeVerifierStateStorage.getStore();\n if (context?.servedKey) {\n await this.storage.delete(context.servedKey);\n return;\n }\n\n if (context) {\n const parsed = parseOAuthState(context.state);\n if (parsed) {\n await this.storage.delete(\n this.stateCodeVerifierKey(this.clientId, parsed.nonce)\n );\n return;\n }\n }\n\n const keys = await this.codeVerifierKeys(this.clientId);\n if (keys.length > 0) {\n await this.storage.delete(keys);\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -1,45 +1,56 @@
|
|
|
1
1
|
import {
|
|
2
|
-
$t as
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
Tt as
|
|
19
|
-
Ut as
|
|
20
|
-
Vt as
|
|
21
|
-
Wt as
|
|
22
|
-
Xt as
|
|
23
|
-
Yt as
|
|
24
|
-
Zt as
|
|
25
|
-
|
|
26
|
-
en as
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
2
|
+
$t as LegacyMcpHandler,
|
|
3
|
+
Bt as RPCServerTransport,
|
|
4
|
+
Dt as MCPConnectionResult,
|
|
5
|
+
Et as MCPClientOAuthResult,
|
|
6
|
+
Ft as normalizeServerId,
|
|
7
|
+
Gt as ElicitResult,
|
|
8
|
+
Ht as RPC_DO_PREFIX,
|
|
9
|
+
It as MCPElicitationHandler,
|
|
10
|
+
Jt as DurableObjectEventStore,
|
|
11
|
+
Kt as McpAgent,
|
|
12
|
+
Lt as MCPElicitationHandlers,
|
|
13
|
+
Mt as MCP_SERVER_ID_MAX_LENGTH,
|
|
14
|
+
Ot as MCPDiscoverResult,
|
|
15
|
+
Qt as CreateMcpHandlerOptions,
|
|
16
|
+
Rt as RPCClientTransport,
|
|
17
|
+
St as MCPClientElicitationHandlers,
|
|
18
|
+
Tt as MCPClientOAuthCallbackConfig,
|
|
19
|
+
Ut as ElicitRequest,
|
|
20
|
+
Vt as RPCServerTransportOptions,
|
|
21
|
+
Wt as ElicitRequestSchema,
|
|
22
|
+
Xt as experimental_createMcpHandler,
|
|
23
|
+
Yt as createMcpHandler,
|
|
24
|
+
Zt as CreateLegacyMcpHandlerOptions,
|
|
25
|
+
an as SSEEdgeClientTransport,
|
|
26
|
+
en as createLegacyMcpHandler,
|
|
27
|
+
in as WorkerTransportOptions,
|
|
28
|
+
jt as MCPServerOptions,
|
|
29
|
+
nn as TransportState,
|
|
30
|
+
on as StreamableHTTPEdgeClientTransport,
|
|
31
|
+
qt as ClearableEventStore,
|
|
32
|
+
rn as WorkerTransport,
|
|
33
|
+
tn as MCPStorageApi,
|
|
34
|
+
xt as MCPClientElicitationHandler,
|
|
35
|
+
zt as RPCClientTransportOptions
|
|
36
|
+
} from "../agent-tool-types-Btk9ETS-.js";
|
|
37
|
+
import {
|
|
38
|
+
a as McpAuthContext,
|
|
39
|
+
n as StatelessMcpHandler,
|
|
40
|
+
o as getMcpAuthContext,
|
|
41
|
+
t as CreateStatelessMcpHandlerOptions,
|
|
42
|
+
u as McpClientOptions
|
|
43
|
+
} from "../handler-stateless-C_bo-Ytq.js";
|
|
36
44
|
export {
|
|
37
45
|
type ClearableEventStore,
|
|
46
|
+
type CreateLegacyMcpHandlerOptions,
|
|
38
47
|
type CreateMcpHandlerOptions,
|
|
48
|
+
type CreateStatelessMcpHandlerOptions,
|
|
39
49
|
DurableObjectEventStore,
|
|
40
50
|
type ElicitRequest,
|
|
41
51
|
ElicitRequestSchema,
|
|
42
52
|
type ElicitResult,
|
|
53
|
+
type LegacyMcpHandler,
|
|
43
54
|
type MCPClientElicitationHandler,
|
|
44
55
|
type MCPClientElicitationHandlers,
|
|
45
56
|
type MCPClientOAuthCallbackConfig,
|
|
@@ -49,6 +60,7 @@ export {
|
|
|
49
60
|
type MCPElicitationHandler,
|
|
50
61
|
type MCPElicitationHandlers,
|
|
51
62
|
type MCPServerOptions,
|
|
63
|
+
type MCPStorageApi,
|
|
52
64
|
MCP_SERVER_ID_MAX_LENGTH,
|
|
53
65
|
McpAgent,
|
|
54
66
|
type McpAuthContext,
|
|
@@ -59,10 +71,12 @@ export {
|
|
|
59
71
|
type RPCServerTransportOptions,
|
|
60
72
|
RPC_DO_PREFIX,
|
|
61
73
|
SSEEdgeClientTransport,
|
|
74
|
+
type StatelessMcpHandler,
|
|
62
75
|
StreamableHTTPEdgeClientTransport,
|
|
63
76
|
type TransportState,
|
|
64
77
|
WorkerTransport,
|
|
65
78
|
type WorkerTransportOptions,
|
|
79
|
+
createLegacyMcpHandler,
|
|
66
80
|
createMcpHandler,
|
|
67
81
|
experimental_createMcpHandler,
|
|
68
82
|
getMcpAuthContext,
|
package/dist/mcp/index.js
CHANGED
|
@@ -1,44 +1,13 @@
|
|
|
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 {
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Shared SSE keepalive utility for MCP transports.
|
|
13
|
-
*
|
|
14
|
-
* Cloudflare's edge closes idle SSE responses after ~5 minutes. Writers
|
|
15
|
-
* that may sit silent for that long (long-running tool calls, idle
|
|
16
|
-
* standalone GET streams) arm a keepalive to keep the response under the
|
|
17
|
-
* watchdog.
|
|
18
|
-
*
|
|
19
|
-
* See cloudflare/agents#1583.
|
|
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
|
-
*/
|
|
28
|
-
const KEEPALIVE_INTERVAL_MS = 25e3;
|
|
29
|
-
/** SSE comment frame the parser drops before any event dispatch. */
|
|
30
|
-
const KEEPALIVE_FRAME = ": keepalive\n\n";
|
|
31
|
-
/**
|
|
32
|
-
* Start an SSE keepalive on `writer`. Returns a `clearInterval` handle
|
|
33
|
-
* that the stream cleanup must invoke when the stream closes.
|
|
34
|
-
*/
|
|
35
|
-
function startKeepalive(writer, encoder) {
|
|
36
|
-
const handle = setInterval(() => {
|
|
37
|
-
writer.write(encoder.encode(KEEPALIVE_FRAME)).catch(() => clearInterval(handle));
|
|
38
|
-
}, KEEPALIVE_INTERVAL_MS);
|
|
39
|
-
return handle;
|
|
40
|
-
}
|
|
41
|
-
//#endregion
|
|
4
|
+
import { a as KEEPALIVE_INTERVAL_MS, i as KEEPALIVE_FRAME, n as getMcpAuthContext, o as startKeepalive, r as runWithAuthContext, t as createStatelessMcpHandler } from "../handler-stateless-8hQN_kC3.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";
|
|
42
11
|
//#region src/mcp/utils.ts
|
|
43
12
|
/**
|
|
44
13
|
* Since we use WebSockets to bridge the client to the
|
|
@@ -54,6 +23,18 @@ const MCP_HTTP_METHOD_HEADER = "cf-mcp-method";
|
|
|
54
23
|
*/
|
|
55
24
|
const MCP_MESSAGE_HEADER = "cf-mcp-message";
|
|
56
25
|
const MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024;
|
|
26
|
+
function unsupportedProtocolVersionResponse(request) {
|
|
27
|
+
const protocolVersion = request.headers.get("mcp-protocol-version");
|
|
28
|
+
if (protocolVersion === null || SUPPORTED_PROTOCOL_VERSIONS.includes(protocolVersion)) return;
|
|
29
|
+
return Response.json({
|
|
30
|
+
error: {
|
|
31
|
+
code: -32e3,
|
|
32
|
+
message: `Bad Request: Unsupported protocol version: ${protocolVersion} (supported versions: ${SUPPORTED_PROTOCOL_VERSIONS.join(", ")})`
|
|
33
|
+
},
|
|
34
|
+
id: null,
|
|
35
|
+
jsonrpc: "2.0"
|
|
36
|
+
}, { status: 400 });
|
|
37
|
+
}
|
|
57
38
|
const createStreamingHttpHandler = (basePath, namespace, options = {}) => {
|
|
58
39
|
let pathname = basePath;
|
|
59
40
|
if (basePath === "/") pathname = "/*";
|
|
@@ -151,6 +132,10 @@ const createStreamingHttpHandler = (basePath, namespace, options = {}) => {
|
|
|
151
132
|
});
|
|
152
133
|
return new Response(body, { status: 400 });
|
|
153
134
|
}
|
|
135
|
+
if (!maybeInitializeRequest) {
|
|
136
|
+
const unsupportedVersion = unsupportedProtocolVersionResponse(request);
|
|
137
|
+
if (unsupportedVersion) return unsupportedVersion;
|
|
138
|
+
}
|
|
154
139
|
if (!maybeInitializeRequest && !sessionId) {
|
|
155
140
|
const body = JSON.stringify({
|
|
156
141
|
error: {
|
|
@@ -279,6 +264,8 @@ const createStreamingHttpHandler = (basePath, namespace, options = {}) => {
|
|
|
279
264
|
id: null,
|
|
280
265
|
jsonrpc: "2.0"
|
|
281
266
|
}), { status: 400 });
|
|
267
|
+
const unsupportedVersion = unsupportedProtocolVersionResponse(request);
|
|
268
|
+
if (unsupportedVersion) return unsupportedVersion;
|
|
282
269
|
const { readable, writable } = new TransformStream();
|
|
283
270
|
const writer = writable.getWriter();
|
|
284
271
|
const encoder = new TextEncoder();
|
|
@@ -338,6 +325,8 @@ const createStreamingHttpHandler = (basePath, namespace, options = {}) => {
|
|
|
338
325
|
status: 200
|
|
339
326
|
});
|
|
340
327
|
} else if (request.method === "DELETE") {
|
|
328
|
+
const unsupportedVersion = unsupportedProtocolVersionResponse(request);
|
|
329
|
+
if (unsupportedVersion) return unsupportedVersion;
|
|
341
330
|
const sessionId = request.headers.get("mcp-session-id");
|
|
342
331
|
if (!sessionId) return new Response(JSON.stringify({
|
|
343
332
|
jsonrpc: "2.0",
|
|
@@ -980,36 +969,36 @@ DurableObjectEventStore.REPLAY_LIMIT = 1e3;
|
|
|
980
969
|
*/
|
|
981
970
|
let didWarnAboutSSEEdgeClientTransport = false;
|
|
982
971
|
/**
|
|
983
|
-
* @deprecated Use SSEClientTransport from @modelcontextprotocol/
|
|
972
|
+
* @deprecated Use SSEClientTransport from @modelcontextprotocol/client instead. This alias will be removed in the next major version.
|
|
984
973
|
*/
|
|
985
974
|
var SSEEdgeClientTransport = class extends SSEClientTransport {
|
|
986
975
|
constructor(url, options) {
|
|
987
976
|
super(url, options);
|
|
988
977
|
if (!didWarnAboutSSEEdgeClientTransport) {
|
|
989
978
|
didWarnAboutSSEEdgeClientTransport = true;
|
|
990
|
-
console.warn("SSEEdgeClientTransport is deprecated. Use SSEClientTransport from @modelcontextprotocol/
|
|
979
|
+
console.warn("SSEEdgeClientTransport is deprecated. Use SSEClientTransport from @modelcontextprotocol/client instead. SSEEdgeClientTransport will be removed in the next major version.");
|
|
991
980
|
}
|
|
992
981
|
}
|
|
993
982
|
};
|
|
994
983
|
let didWarnAboutStreamableHTTPEdgeClientTransport = false;
|
|
995
984
|
/**
|
|
996
|
-
* @deprecated Use StreamableHTTPClientTransport from @modelcontextprotocol/
|
|
985
|
+
* @deprecated Use StreamableHTTPClientTransport from @modelcontextprotocol/client instead. This alias will be removed in the next major version.
|
|
997
986
|
*/
|
|
998
987
|
var StreamableHTTPEdgeClientTransport = class extends StreamableHTTPClientTransport {
|
|
999
988
|
constructor(url, options) {
|
|
1000
989
|
super(url, options);
|
|
1001
990
|
if (!didWarnAboutStreamableHTTPEdgeClientTransport) {
|
|
1002
991
|
didWarnAboutStreamableHTTPEdgeClientTransport = true;
|
|
1003
|
-
console.warn("StreamableHTTPEdgeClientTransport is deprecated. Use StreamableHTTPClientTransport from @modelcontextprotocol/
|
|
992
|
+
console.warn("StreamableHTTPEdgeClientTransport is deprecated. Use StreamableHTTPClientTransport from @modelcontextprotocol/client instead. StreamableHTTPEdgeClientTransport will be removed in the next major version.");
|
|
1004
993
|
}
|
|
1005
994
|
}
|
|
1006
995
|
};
|
|
1007
996
|
//#endregion
|
|
1008
997
|
//#region src/mcp/worker-transport.ts
|
|
1009
998
|
/**
|
|
1010
|
-
* WorkerTransport
|
|
999
|
+
* WorkerTransport — retained sessionful Legacy transport
|
|
1011
1000
|
*
|
|
1012
|
-
* Thin Cloudflare-Workers wrapper around the official MCP SDK
|
|
1001
|
+
* Thin Cloudflare-Workers wrapper around the official MCP SDK v1
|
|
1013
1002
|
* `WebStandardStreamableHTTPServerTransport`. The wrapper layers a couple of
|
|
1014
1003
|
* Workers-specific concerns on top of the SDK transport without forking it:
|
|
1015
1004
|
*
|
|
@@ -1029,7 +1018,8 @@ var StreamableHTTPEdgeClientTransport = class extends StreamableHTTPClientTransp
|
|
|
1029
1018
|
* POST response streams always keepalive (no resumption path during a
|
|
1030
1019
|
* mid-flight tool call). See cloudflare/agents#1583.
|
|
1031
1020
|
*
|
|
1032
|
-
* Everything else (session
|
|
1021
|
+
* Stateless handlers do not import this module. Everything else (session
|
|
1022
|
+
* validation, SSE streaming, protocol-version
|
|
1033
1023
|
* negotiation, event-store resumability, etc.) is delegated to the SDK
|
|
1034
1024
|
* transport.
|
|
1035
1025
|
*/
|
|
@@ -1042,7 +1032,7 @@ const DEFAULT_CORS_OPTIONS = {
|
|
|
1042
1032
|
exposeHeaders: "mcp-session-id",
|
|
1043
1033
|
maxAge: 86400
|
|
1044
1034
|
};
|
|
1045
|
-
var WorkerTransport = class extends WebStandardStreamableHTTPServerTransport {
|
|
1035
|
+
var WorkerTransport = class extends WebStandardStreamableHTTPServerTransport$1 {
|
|
1046
1036
|
constructor(options = {}) {
|
|
1047
1037
|
const { corsOptions, storage, onsessioninitialized, ...sdkOptions } = options;
|
|
1048
1038
|
super({
|
|
@@ -1294,67 +1284,81 @@ var WorkerTransport = class extends WebStandardStreamableHTTPServerTransport {
|
|
|
1294
1284
|
}
|
|
1295
1285
|
};
|
|
1296
1286
|
//#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 = {}) {
|
|
1287
|
+
//#region src/mcp/handler-legacy.ts
|
|
1288
|
+
/**
|
|
1289
|
+
* Create a sessionful Legacy MCP handler backed by SDK v1.
|
|
1290
|
+
*
|
|
1291
|
+
* New Stateless servers should use `createMcpHandler` from
|
|
1292
|
+
* `agents/mcp/server` instead.
|
|
1293
|
+
*/
|
|
1294
|
+
function createLegacyMcpHandler(server, options = {}) {
|
|
1308
1295
|
const route = options.route ?? "/mcp";
|
|
1309
1296
|
const { route: _route, authContext, transport: providedTransport, ...transportOptions } = options;
|
|
1310
1297
|
return async (request, _env, ctx) => {
|
|
1311
1298
|
const url = new URL(request.url);
|
|
1312
1299
|
if (route && url.pathname !== route) return new Response("Not Found", { status: 404 });
|
|
1313
1300
|
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();
|
|
1301
|
+
const resolvedAuthContext = authContext ?? (ctx.props && Object.keys(ctx.props).length > 0 ? { props: ctx.props } : void 0);
|
|
1322
1302
|
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.");
|
|
1303
|
+
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
1304
|
await server.connect(transport);
|
|
1325
1305
|
}
|
|
1306
|
+
const handleRequest = () => transport.handleRequest(request);
|
|
1326
1307
|
try {
|
|
1327
|
-
|
|
1328
|
-
else return await handleRequest();
|
|
1308
|
+
return resolvedAuthContext ? await runWithAuthContext(resolvedAuthContext, handleRequest) : await handleRequest();
|
|
1329
1309
|
} catch (error) {
|
|
1330
1310
|
console.error("MCP handler error:", error);
|
|
1331
|
-
return
|
|
1311
|
+
return Response.json({
|
|
1332
1312
|
jsonrpc: "2.0",
|
|
1333
1313
|
error: {
|
|
1334
1314
|
code: -32603,
|
|
1335
1315
|
message: error instanceof Error ? error.message : "Internal server error"
|
|
1336
1316
|
},
|
|
1337
1317
|
id: null
|
|
1338
|
-
}
|
|
1339
|
-
status: 500,
|
|
1340
|
-
headers: { "Content-Type": "application/json" }
|
|
1341
|
-
});
|
|
1318
|
+
}, { status: 500 });
|
|
1342
1319
|
}
|
|
1343
1320
|
};
|
|
1344
1321
|
}
|
|
1322
|
+
//#endregion
|
|
1323
|
+
//#region src/mcp/handler-warning.ts
|
|
1324
|
+
let didWarnAboutLegacyCreateMcpHandlerOverload = false;
|
|
1325
|
+
function warnLegacyCreateMcpHandlerOverload() {
|
|
1326
|
+
if (didWarnAboutLegacyCreateMcpHandlerOverload) return;
|
|
1327
|
+
didWarnAboutLegacyCreateMcpHandlerOverload = true;
|
|
1328
|
+
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.");
|
|
1329
|
+
}
|
|
1330
|
+
//#endregion
|
|
1331
|
+
//#region src/mcp/handler-compat.ts
|
|
1332
|
+
function createMcpHandler(serverOrFactory, options = {}) {
|
|
1333
|
+
if (typeof serverOrFactory === "function") return createStatelessMcpHandler(serverOrFactory, options);
|
|
1334
|
+
if (serverOrFactory instanceof McpServer$1 || serverOrFactory instanceof Server$1) {
|
|
1335
|
+
warnLegacyCreateMcpHandlerOverload();
|
|
1336
|
+
return createLegacyMcpHandler(serverOrFactory, options);
|
|
1337
|
+
}
|
|
1338
|
+
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.");
|
|
1339
|
+
}
|
|
1345
1340
|
let didWarnAboutExperimentalCreateMcpHandler = false;
|
|
1346
1341
|
/**
|
|
1347
|
-
* @deprecated
|
|
1342
|
+
* @deprecated Pass an SDK v2 factory to createMcpHandler.
|
|
1343
|
+
* experimental_createMcpHandler will be removed in the next major version.
|
|
1344
|
+
* Use createLegacyMcpHandler only to temporarily retain sessionful SDK v1
|
|
1345
|
+
* behavior while migrating.
|
|
1348
1346
|
*/
|
|
1349
1347
|
function experimental_createMcpHandler(server, options = {}) {
|
|
1350
1348
|
if (!didWarnAboutExperimentalCreateMcpHandler) {
|
|
1351
1349
|
didWarnAboutExperimentalCreateMcpHandler = true;
|
|
1352
|
-
console.warn("experimental_createMcpHandler is deprecated
|
|
1350
|
+
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
1351
|
}
|
|
1354
|
-
return
|
|
1352
|
+
return createLegacyMcpHandler(server, options);
|
|
1355
1353
|
}
|
|
1356
1354
|
//#endregion
|
|
1357
|
-
//#region src/mcp/
|
|
1355
|
+
//#region src/mcp/legacy-agent.ts
|
|
1356
|
+
/**
|
|
1357
|
+
* @deprecated McpAgent is feature-frozen. Migrate to an SDK v2 factory with
|
|
1358
|
+
* createMcpHandler from agents/mcp/server. When sessionful features prevent an
|
|
1359
|
+
* immediate migration, run the stateless route beside the existing McpAgent
|
|
1360
|
+
* route until clients transition and sessions drain.
|
|
1361
|
+
*/
|
|
1358
1362
|
var McpAgent = class McpAgent extends Agent {
|
|
1359
1363
|
constructor(..._args) {
|
|
1360
1364
|
super(..._args);
|
|
@@ -1502,6 +1506,7 @@ var McpAgent = class McpAgent extends Agent {
|
|
|
1502
1506
|
else this.props = await this.ctx.storage.get("props");
|
|
1503
1507
|
await this.init();
|
|
1504
1508
|
const server = await this.server;
|
|
1509
|
+
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
1510
|
this._transport = this.initTransport();
|
|
1506
1511
|
if (!this._transport) throw new Error("Failed to initialize transport");
|
|
1507
1512
|
await server.connect(this._transport);
|
|
@@ -1698,6 +1703,6 @@ var McpAgent = class McpAgent extends Agent {
|
|
|
1698
1703
|
};
|
|
1699
1704
|
McpAgent.STREAM_REQS_KEY_PREFIX = "__mcp_stream_reqs__:";
|
|
1700
1705
|
//#endregion
|
|
1701
|
-
export { DurableObjectEventStore, ElicitRequestSchema, MCP_SERVER_ID_MAX_LENGTH, McpAgent, RPCClientTransport, RPCServerTransport, RPC_DO_PREFIX, SSEEdgeClientTransport, StreamableHTTPEdgeClientTransport, WorkerTransport, createMcpHandler, experimental_createMcpHandler, getMcpAuthContext, normalizeServerId };
|
|
1706
|
+
export { DurableObjectEventStore, ElicitRequestSchema, MCP_SERVER_ID_MAX_LENGTH, McpAgent, RPCClientTransport, RPCServerTransport, RPC_DO_PREFIX, SSEEdgeClientTransport, StreamableHTTPEdgeClientTransport, WorkerTransport, createLegacyMcpHandler, createMcpHandler, experimental_createMcpHandler, getMcpAuthContext, normalizeServerId };
|
|
1702
1707
|
|
|
1703
1708
|
//# sourceMappingURL=index.js.map
|