@adcp/sdk 12.0.2 → 12.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/advanced.d.mts +2 -1
- package/dist/lib/advanced.d.ts +2 -1
- package/dist/lib/advanced.d.ts.map +1 -1
- package/dist/lib/advanced.js +4 -0
- package/dist/lib/advanced.js.map +1 -1
- package/dist/lib/advanced.mjs +11 -1
- package/dist/lib/advanced.mjs.map +1 -1
- package/dist/lib/index.d.mts +2 -2
- package/dist/lib/index.d.ts +2 -2
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +2 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +3 -1
- package/dist/lib/index.mjs.map +1 -1
- package/dist/lib/protocols/mcp-modern.d.mts +1 -0
- package/dist/lib/protocols/mcp-modern.d.ts +1 -0
- package/dist/lib/protocols/mcp-modern.d.ts.map +1 -1
- package/dist/lib/protocols/mcp-modern.js +22 -5
- package/dist/lib/protocols/mcp-modern.js.map +1 -1
- package/dist/lib/protocols/mcp-modern.mjs +22 -5
- package/dist/lib/protocols/mcp-modern.mjs.map +1 -1
- package/dist/lib/protocols/mcp.d.mts +11 -0
- package/dist/lib/protocols/mcp.d.ts +11 -0
- package/dist/lib/protocols/mcp.d.ts.map +1 -1
- package/dist/lib/protocols/mcp.js +25 -8
- package/dist/lib/protocols/mcp.js.map +1 -1
- package/dist/lib/protocols/mcp.mjs +25 -8
- package/dist/lib/protocols/mcp.mjs.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/adcp-server.d.ts.map +1 -1
- package/dist/lib/server/adcp-server.js +18 -0
- package/dist/lib/server/adcp-server.js.map +1 -1
- package/dist/lib/server/adcp-server.mjs +15 -0
- package/dist/lib/server/adcp-server.mjs.map +1 -1
- package/dist/lib/server/create-adcp-server.d.mts +11 -0
- package/dist/lib/server/create-adcp-server.d.ts +11 -0
- package/dist/lib/server/create-adcp-server.d.ts.map +1 -1
- package/dist/lib/server/create-adcp-server.js +21 -0
- package/dist/lib/server/create-adcp-server.js.map +1 -1
- package/dist/lib/server/create-adcp-server.mjs +26 -0
- package/dist/lib/server/create-adcp-server.mjs.map +1 -1
- package/dist/lib/server/index.d.mts +2 -0
- package/dist/lib/server/index.d.ts +2 -0
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js +3 -0
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/server/index.mjs +2 -0
- package/dist/lib/server/index.mjs.map +1 -1
- package/dist/lib/server/mcp-app.d.mts +57 -0
- package/dist/lib/server/mcp-app.d.ts +58 -0
- package/dist/lib/server/mcp-app.d.ts.map +1 -0
- package/dist/lib/server/mcp-app.js +110 -0
- package/dist/lib/server/mcp-app.js.map +1 -0
- package/dist/lib/server/mcp-app.mjs +83 -0
- package/dist/lib/server/mcp-app.mjs.map +1 -0
- package/dist/lib/server/mcp-modern-server.d.ts.map +1 -1
- package/dist/lib/server/mcp-modern-server.js +23 -1
- package/dist/lib/server/mcp-modern-server.js.map +1 -1
- package/dist/lib/server/mcp-modern-server.mjs +24 -1
- package/dist/lib/server/mcp-modern-server.mjs.map +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.js.map +1 -1
- package/dist/lib/version.mjs +3 -3
- package/dist/lib/version.mjs.map +1 -1
- package/docs/guides/BUILD-AN-AGENT.md +70 -0
- package/package.json +1 -1
|
@@ -23,7 +23,9 @@ const knownLegacyConnections = /* @__PURE__ */ new Map();
|
|
|
23
23
|
const MAX_CACHED_CONNECTIONS = 20;
|
|
24
24
|
const LEGACY_CLASSIFICATION_TTL_MS = 5 * 60 * 1e3;
|
|
25
25
|
const modernOAuthProviderIds = /* @__PURE__ */ new WeakMap();
|
|
26
|
+
const modernFetchFnIds = /* @__PURE__ */ new WeakMap();
|
|
26
27
|
let nextModernOAuthProviderId = 0;
|
|
28
|
+
let nextModernFetchFnId = 0;
|
|
27
29
|
let connectionGeneration = 0;
|
|
28
30
|
function cacheDisambiguator(value) {
|
|
29
31
|
return createHmac("sha256", "").update(value).digest("hex");
|
|
@@ -49,12 +51,23 @@ function oauthProviderCacheKey(provider) {
|
|
|
49
51
|
}
|
|
50
52
|
return key;
|
|
51
53
|
}
|
|
52
|
-
function
|
|
54
|
+
function fetchFnCacheKey(fetchFn) {
|
|
55
|
+
if (!fetchFn) return void 0;
|
|
56
|
+
let key = modernFetchFnIds.get(fetchFn);
|
|
57
|
+
if (!key) {
|
|
58
|
+
key = `fetch:${++nextModernFetchFnId}`;
|
|
59
|
+
modernFetchFnIds.set(fetchFn, key);
|
|
60
|
+
}
|
|
61
|
+
return key;
|
|
62
|
+
}
|
|
63
|
+
function connectionCacheKey(agentUrl, headers, signingCacheKey, authProvider, fetchFn) {
|
|
53
64
|
const normalizedHeaders = Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value]).sort(([left], [right]) => left.localeCompare(right));
|
|
54
65
|
const parts = [agentUrl, `headers:${cacheDisambiguator(JSON.stringify(normalizedHeaders))}`];
|
|
55
66
|
if (signingCacheKey) parts.push(signingCacheKey);
|
|
56
67
|
const providerKey = oauthProviderCacheKey(authProvider);
|
|
57
68
|
if (providerKey) parts.push(providerKey);
|
|
69
|
+
const fetchKey = fetchFnCacheKey(fetchFn);
|
|
70
|
+
if (fetchKey) parts.push(fetchKey);
|
|
58
71
|
return parts.join("::");
|
|
59
72
|
}
|
|
60
73
|
function isKnownLegacy(cacheKey) {
|
|
@@ -122,7 +135,7 @@ function evictLeastRecentlyUsed() {
|
|
|
122
135
|
async function createNegotiatedClient(options, authHeaders) {
|
|
123
136
|
const requestTimeoutMs = resolveRequestTimeoutMs(options.requestTimeoutMs);
|
|
124
137
|
const clientRequestTimeoutMs = resolveClientRequestTimeoutMs(options.requestTimeoutMs);
|
|
125
|
-
const rawNetworkFetch = (input, init) => fetch(input, init);
|
|
138
|
+
const rawNetworkFetch = options.fetchFn ?? ((input, init) => fetch(input, init));
|
|
126
139
|
const networkFetch = (input, init) => withAbortSignal(
|
|
127
140
|
[options.signal, init?.signal],
|
|
128
141
|
requestTimeoutMs,
|
|
@@ -206,10 +219,11 @@ async function attemptModernCall(options, toolName, args) {
|
|
|
206
219
|
options.agentUrl,
|
|
207
220
|
authHeaders,
|
|
208
221
|
options.signingContext?.cacheKey,
|
|
209
|
-
options.authProvider
|
|
222
|
+
options.authProvider,
|
|
223
|
+
options.fetchFn
|
|
210
224
|
);
|
|
211
225
|
if (isKnownLegacy(cacheKey)) return { handled: false };
|
|
212
|
-
const guardedConnection = options.signal !== void 0 || options.requestTimeoutMs !== void 0;
|
|
226
|
+
const guardedConnection = options.signal !== void 0 || options.requestTimeoutMs !== void 0 || options.fetchFn !== void 0;
|
|
213
227
|
let client;
|
|
214
228
|
try {
|
|
215
229
|
client = guardedConnection ? await createNegotiatedClient(options, authHeaders) : await getOrCreateModernConnection(cacheKey, options, authHeaders);
|
|
@@ -288,6 +302,7 @@ async function tryCallModernMCPTool(agentUrl, toolName, args, authToken, debugLo
|
|
|
288
302
|
authProvider: options.authProvider,
|
|
289
303
|
signal: options.signal,
|
|
290
304
|
requestTimeoutMs: options.requestTimeoutMs,
|
|
305
|
+
fetchFn: options.fetchFn,
|
|
291
306
|
handleLegacy: options.handleLegacy
|
|
292
307
|
},
|
|
293
308
|
toolName,
|
|
@@ -306,6 +321,7 @@ async function probeModernMCPConnection(agentUrl, authToken, customHeaders, opti
|
|
|
306
321
|
authProvider: options.authProvider,
|
|
307
322
|
signal: options.signal,
|
|
308
323
|
requestTimeoutMs: options.requestTimeoutMs,
|
|
324
|
+
fetchFn: options.fetchFn,
|
|
309
325
|
handleLegacy: options.handleLegacy
|
|
310
326
|
};
|
|
311
327
|
const authHeaders = buildAuthHeaders(authToken, customHeaders, options.authProvider);
|
|
@@ -332,7 +348,8 @@ async function tryListModernMCPTools(agentUrl, authToken, customHeaders, options
|
|
|
332
348
|
signingContext: options.signingContext,
|
|
333
349
|
authProvider: options.authProvider,
|
|
334
350
|
signal: options.signal,
|
|
335
|
-
requestTimeoutMs: options.requestTimeoutMs
|
|
351
|
+
requestTimeoutMs: options.requestTimeoutMs,
|
|
352
|
+
fetchFn: options.fetchFn
|
|
336
353
|
};
|
|
337
354
|
const authHeaders = buildAuthHeaders(authToken, customHeaders, options.authProvider);
|
|
338
355
|
let client;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/protocols/mcp-modern.ts"],"sourcesContent":["/**\n * MCP 2026-07-28 client path.\n *\n * The v2 SDK removed the experimental 2025 Tasks interception API. During the\n * migration window we therefore negotiate with the v2 client first and use it\n * only when the peer selects the modern protocol era. Legacy peers fall back\n * to mcp-tasks.ts, which keeps the existing v1 Tasks behavior intact.\n */\n\nimport {\n Client,\n StreamableHTTPClientTransport,\n type OAuthClientProvider as ModernOAuthClientProvider,\n type Tool,\n} from '@modelcontextprotocol/client';\nimport { createHmac } from 'node:crypto';\nimport { createMCPAuthHeaders } from '../auth';\nimport { is401Error } from '../errors';\nimport { withSpan, injectTraceHeaders } from '../observability/tracing';\nimport { buildAgentSigningFetch, signingContextStorage, type AgentSigningContext } from '../signing/client';\nimport type { DebugLogEntry } from '../types/adcp';\nimport {\n isAbortOrTimeoutError,\n resolveClientRequestTimeoutMs,\n resolveRequestTimeoutMs,\n withAbortSignal,\n} from './abort';\nimport { wrapFetchWithCapture } from './rawResponseCapture';\nimport { wrapFetchWithSizeLimit } from './responseSizeLimit';\nimport { wrapFetchWithTransportDiagnostics } from './transportDiagnostics';\n\ntype CallToolResponse = {\n isError?: boolean;\n content?: Array<{ type: string; text?: string }>;\n [key: string]: unknown;\n};\n\nexport type ModernMCPAttempt = { handled: false } | { handled: true; response: CallToolResponse };\nexport type ModernMCPListAttempt = { handled: false } | { handled: true; tools: Tool[] };\n\nexport interface ModernMCPConnectionOptions {\n signingContext?: AgentSigningContext;\n authProvider?: object;\n signal?: AbortSignal;\n requestTimeoutMs?: number;\n /** Use the v2 SDK's negotiated legacy client instead of handing off to v1. */\n handleLegacy?: boolean;\n}\n\ninterface ModernConnectionOptions {\n agentUrl: string;\n authToken?: string;\n customHeaders?: Record<string, string>;\n debugLogs: DebugLogEntry[];\n signingContext?: AgentSigningContext;\n authProvider?: object;\n signal?: AbortSignal;\n requestTimeoutMs?: number;\n handleLegacy?: boolean;\n}\n\nconst modernConnections = new Map<string, Client>();\nconst legacyConnectionExpiresAt = new Map<string, number>();\nconst pendingModernConnections = new Map<string, Promise<Client>>();\nconst knownLegacyConnections = new Map<string, number>();\nconst MAX_CACHED_CONNECTIONS = 20;\nconst LEGACY_CLASSIFICATION_TTL_MS = 5 * 60 * 1000;\nconst modernOAuthProviderIds = new WeakMap<object, string>();\nlet nextModernOAuthProviderId = 0;\nlet connectionGeneration = 0;\n\nfunction cacheDisambiguator(value: string): string {\n return createHmac('sha256', '').update(value).digest('hex');\n}\n\nfunction buildAuthHeaders(\n authToken: string | undefined,\n customHeaders: Record<string, string> | undefined,\n authProvider?: object\n): Record<string, string> {\n const filteredHeaders =\n authProvider || authToken\n ? Object.fromEntries(\n Object.entries(customHeaders ?? {}).filter(keyValue => {\n const key = keyValue[0].toLowerCase();\n return key !== 'authorization' && key !== 'x-adcp-auth';\n })\n )\n : customHeaders;\n return {\n ...filteredHeaders,\n ...(!authProvider && authToken ? createMCPAuthHeaders(authToken) : {}),\n };\n}\n\nfunction oauthProviderCacheKey(provider: object | undefined): string | undefined {\n if (!provider) return undefined;\n let key = modernOAuthProviderIds.get(provider);\n if (!key) {\n key = `oauth-provider:${++nextModernOAuthProviderId}`;\n modernOAuthProviderIds.set(provider, key);\n }\n return key;\n}\n\nfunction connectionCacheKey(\n agentUrl: string,\n headers: Record<string, string>,\n signingCacheKey?: string,\n authProvider?: object\n): string {\n const normalizedHeaders = Object.entries(headers)\n .map(([key, value]) => [key.toLowerCase(), value] as const)\n .sort(([left], [right]) => left.localeCompare(right));\n const parts = [agentUrl, `headers:${cacheDisambiguator(JSON.stringify(normalizedHeaders))}`];\n if (signingCacheKey) parts.push(signingCacheKey);\n const providerKey = oauthProviderCacheKey(authProvider);\n if (providerKey) parts.push(providerKey);\n return parts.join('::');\n}\n\nfunction isKnownLegacy(cacheKey: string): boolean {\n const classifiedAt = knownLegacyConnections.get(cacheKey);\n if (classifiedAt === undefined) return false;\n if (Date.now() - classifiedAt > LEGACY_CLASSIFICATION_TTL_MS) {\n knownLegacyConnections.delete(cacheKey);\n return false;\n }\n knownLegacyConnections.delete(cacheKey);\n knownLegacyConnections.set(cacheKey, classifiedAt);\n return true;\n}\n\nfunction markKnownLegacy(cacheKey: string): void {\n knownLegacyConnections.delete(cacheKey);\n knownLegacyConnections.set(cacheKey, Date.now());\n while (knownLegacyConnections.size > MAX_CACHED_CONNECTIONS) {\n const oldest = knownLegacyConnections.keys().next().value;\n if (!oldest) break;\n knownLegacyConnections.delete(oldest);\n }\n}\n\nfunction httpStatusOf(error: unknown, depth = 0): number | undefined {\n if (!error || typeof error !== 'object' || depth > 4) return undefined;\n const candidate = error as { status?: unknown; code?: unknown; cause?: unknown; response?: { status?: unknown } };\n if (typeof candidate.status === 'number') return candidate.status;\n if (typeof candidate.response?.status === 'number') return candidate.response.status;\n if (typeof candidate.code === 'number' && candidate.code >= 100 && candidate.code <= 599) return candidate.code;\n return httpStatusOf(candidate.cause, depth + 1);\n}\n\nfunction withPerRequestTraceHeaders(fetchImpl: typeof fetch): typeof fetch {\n return (input, init) => {\n const headers = new Headers(input instanceof Request ? input.headers : undefined);\n new Headers(init?.headers).forEach((value, key) => headers.set(key, value));\n for (const [key, value] of Object.entries(injectTraceHeaders())) headers.set(key, value);\n return fetchImpl(input, { ...init, headers });\n };\n}\n\nfunction getCachedConnection(cacheKey: string): Client | undefined {\n const client = modernConnections.get(cacheKey);\n if (client) {\n const legacyExpiry = legacyConnectionExpiresAt.get(cacheKey);\n if (legacyExpiry !== undefined && legacyExpiry <= Date.now()) {\n modernConnections.delete(cacheKey);\n legacyConnectionExpiresAt.delete(cacheKey);\n void client.close().catch(() => {});\n return undefined;\n }\n modernConnections.delete(cacheKey);\n modernConnections.set(cacheKey, client);\n }\n return client;\n}\n\nfunction evictLeastRecentlyUsed(): void {\n if (modernConnections.size <= MAX_CACHED_CONNECTIONS) return;\n const oldestKey = modernConnections.keys().next().value;\n if (!oldestKey) return;\n const client = modernConnections.get(oldestKey);\n modernConnections.delete(oldestKey);\n legacyConnectionExpiresAt.delete(oldestKey);\n void client?.close().catch(() => {});\n}\n\nasync function createNegotiatedClient(\n options: ModernConnectionOptions,\n authHeaders: Record<string, string>\n): Promise<Client> {\n const requestTimeoutMs = resolveRequestTimeoutMs(options.requestTimeoutMs);\n const clientRequestTimeoutMs = resolveClientRequestTimeoutMs(options.requestTimeoutMs);\n const rawNetworkFetch: typeof fetch = (input, init) => fetch(input, init);\n const networkFetch: typeof fetch = (input, init) =>\n withAbortSignal<Response>([options.signal, init?.signal], requestTimeoutMs, signal =>\n rawNetworkFetch(input, { ...init, signal })\n );\n const diagnosticFetch = wrapFetchWithTransportDiagnostics(wrapFetchWithSizeLimit(networkFetch));\n const signedFetch: typeof fetch = options.signingContext\n ? (buildAgentSigningFetch({\n upstream: diagnosticFetch,\n signing: options.signingContext.signing,\n getCapability: options.signingContext.getCapability,\n }) as typeof fetch)\n : diagnosticFetch;\n const transport = new StreamableHTTPClientTransport(new URL(options.agentUrl), {\n requestInit: { headers: authHeaders, redirect: 'manual' },\n fetch: wrapFetchWithCapture(withPerRequestTraceHeaders(signedFetch)),\n ...(options.authProvider && {\n authProvider: options.authProvider as ModernOAuthClientProvider,\n }),\n });\n const client = new Client(\n { name: 'AdCP-Client', version: '1.0.0' },\n {\n versionNegotiation: {\n mode: 'auto',\n ...(clientRequestTimeoutMs !== undefined && { probe: { timeoutMs: clientRequestTimeoutMs } }),\n },\n }\n );\n\n try {\n await client.connect(transport, {\n ...(options.signal && { signal: options.signal }),\n ...(clientRequestTimeoutMs !== undefined && { timeout: clientRequestTimeoutMs }),\n });\n return client;\n } catch (error) {\n try {\n await client.close();\n } catch {\n /* ignore close errors */\n }\n throw error;\n }\n}\n\nasync function getOrCreateModernConnection(\n cacheKey: string,\n options: ModernConnectionOptions,\n authHeaders: Record<string, string>\n): Promise<Client> {\n const cached = getCachedConnection(cacheKey);\n if (cached) return cached;\n\n const pending = pendingModernConnections.get(cacheKey);\n if (pending) return pending;\n\n const generation = connectionGeneration;\n const promise = createNegotiatedClient(options, authHeaders)\n .then(client => {\n if (\n (client.getProtocolEra() === 'modern' || options.handleLegacy === true) &&\n generation === connectionGeneration\n ) {\n modernConnections.set(cacheKey, client);\n if (client.getProtocolEra() === 'legacy') {\n legacyConnectionExpiresAt.set(cacheKey, Date.now() + LEGACY_CLASSIFICATION_TTL_MS);\n } else {\n legacyConnectionExpiresAt.delete(cacheKey);\n }\n evictLeastRecentlyUsed();\n } else if (generation !== connectionGeneration) {\n void client.close().catch(() => {});\n }\n return client;\n })\n .finally(() => {\n if (pendingModernConnections.get(cacheKey) === promise) pendingModernConnections.delete(cacheKey);\n });\n pendingModernConnections.set(cacheKey, promise);\n return promise;\n}\n\nasync function callOnModernClient(\n client: Client,\n toolName: string,\n args: Record<string, unknown>,\n signal?: AbortSignal,\n requestTimeoutMs?: number\n): Promise<CallToolResponse> {\n const resolvedRequestTimeoutMs = resolveClientRequestTimeoutMs(requestTimeoutMs);\n return (await client.callTool(\n { name: toolName, arguments: args },\n {\n ...(signal && { signal }),\n ...(resolvedRequestTimeoutMs !== undefined && { timeout: resolvedRequestTimeoutMs }),\n }\n )) as CallToolResponse;\n}\n\nasync function attemptModernCall(\n options: ModernConnectionOptions,\n toolName: string,\n args: Record<string, unknown>\n): Promise<ModernMCPAttempt> {\n const authHeaders = buildAuthHeaders(options.authToken, options.customHeaders, options.authProvider);\n const cacheKey = connectionCacheKey(\n options.agentUrl,\n authHeaders,\n options.signingContext?.cacheKey,\n options.authProvider\n );\n if (isKnownLegacy(cacheKey)) return { handled: false };\n\n const guardedConnection = options.signal !== undefined || options.requestTimeoutMs !== undefined;\n let client: Client;\n try {\n client = guardedConnection\n ? await createNegotiatedClient(options, authHeaders)\n : await getOrCreateModernConnection(cacheKey, options, authHeaders);\n } catch (error) {\n const status = httpStatusOf(error);\n if (status === 404 || status === 405) {\n markKnownLegacy(cacheKey);\n options.debugLogs.push({\n type: 'info',\n message: `MCP: Modern Streamable HTTP is unavailable (HTTP ${status}); preserving the v1 transport path`,\n timestamp: new Date().toISOString(),\n });\n return { handled: false };\n }\n throw error;\n }\n\n if (client.getProtocolEra() !== 'modern') {\n if (options.handleLegacy === true) {\n options.debugLogs.push({\n type: 'info',\n message: `MCP: v2 client selected the legacy protocol era for ${toolName}`,\n timestamp: new Date().toISOString(),\n });\n } else {\n markKnownLegacy(cacheKey);\n try {\n await client.close();\n } catch {\n /* ignore close errors */\n }\n options.debugLogs.push({\n type: 'info',\n message: `MCP: Server selected the legacy protocol era for ${toolName}; preserving the v1 Tasks path`,\n timestamp: new Date().toISOString(),\n });\n return { handled: false };\n }\n }\n\n options.debugLogs.push({\n type: 'success',\n message: `MCP: Negotiated protocol ${client.getNegotiatedProtocolVersion()} for ${toolName}`,\n timestamp: new Date().toISOString(),\n });\n\n try {\n const response = await callOnModernClient(client, toolName, args, options.signal, options.requestTimeoutMs);\n return { handled: true, response };\n } catch (error) {\n // A tool request may have reached the server even when its response was\n // lost. Never replay automatically: mutating AdCP tools depend on the\n // caller's explicit idempotency policy, not transport guesswork.\n modernConnections.delete(cacheKey);\n legacyConnectionExpiresAt.delete(cacheKey);\n try {\n await client.close();\n } catch {\n /* ignore close errors */\n }\n throw error;\n } finally {\n if (guardedConnection) {\n try {\n await client.close();\n } catch {\n /* ignore close errors */\n }\n }\n }\n}\n\n/**\n * Try a tool call using the MCP 2026-07-28 protocol era.\n *\n * `handled: false` means the caller must use the existing v1 client. This is\n * deliberately a result rather than an exception because legacy negotiation\n * is normal during the transition window.\n */\nexport async function tryCallModernMCPTool(\n agentUrl: string,\n toolName: string,\n args: Record<string, unknown>,\n authToken?: string,\n debugLogs: DebugLogEntry[] = [],\n customHeaders?: Record<string, string>,\n options: ModernMCPConnectionOptions = {}\n): Promise<ModernMCPAttempt> {\n return withSpan('adcp.mcp.negotiate', { 'adcp.tool': toolName, 'http.url': agentUrl }, () =>\n signingContextStorage.run(options.signingContext, () =>\n attemptModernCall(\n {\n agentUrl,\n authToken,\n customHeaders,\n debugLogs,\n signingContext: options.signingContext,\n authProvider: options.authProvider,\n signal: options.signal,\n requestTimeoutMs: options.requestTimeoutMs,\n handleLegacy: options.handleLegacy,\n },\n toolName,\n args\n )\n )\n );\n}\n\n/**\n * Probe an endpoint with the official v2 client's auto negotiation.\n * `connected: false` lets endpoint discovery retain its v1 SSE fallback.\n */\nexport async function probeModernMCPConnection(\n agentUrl: string,\n authToken?: string,\n customHeaders?: Record<string, string>,\n options: ModernMCPConnectionOptions = {}\n): Promise<{ connected: boolean; era?: 'legacy' | 'modern' }> {\n const connectionOptions: ModernConnectionOptions = {\n agentUrl,\n authToken,\n customHeaders,\n debugLogs: [],\n signingContext: options.signingContext,\n authProvider: options.authProvider,\n signal: options.signal,\n requestTimeoutMs: options.requestTimeoutMs,\n handleLegacy: options.handleLegacy,\n };\n const authHeaders = buildAuthHeaders(authToken, customHeaders, options.authProvider);\n let client: Client | undefined;\n try {\n client = await createNegotiatedClient(connectionOptions, authHeaders);\n return { connected: true, era: client.getProtocolEra() };\n } catch (error) {\n if (is401Error(error) || isAbortOrTimeoutError(error)) throw error;\n const status = httpStatusOf(error);\n if (status === 404 || status === 405) return { connected: false };\n throw error;\n } finally {\n await client?.close().catch(() => {});\n }\n}\n\n/** List tools when the endpoint selected the modern era; otherwise let the v1 caller continue. */\nexport async function tryListModernMCPTools(\n agentUrl: string,\n authToken?: string,\n customHeaders?: Record<string, string>,\n options: ModernMCPConnectionOptions = {}\n): Promise<ModernMCPListAttempt> {\n const connectionOptions: ModernConnectionOptions = {\n agentUrl,\n authToken,\n customHeaders,\n debugLogs: [],\n signingContext: options.signingContext,\n authProvider: options.authProvider,\n signal: options.signal,\n requestTimeoutMs: options.requestTimeoutMs,\n };\n const authHeaders = buildAuthHeaders(authToken, customHeaders, options.authProvider);\n let client: Client | undefined;\n try {\n client = await createNegotiatedClient(connectionOptions, authHeaders);\n if (client.getProtocolEra() !== 'modern') return { handled: false };\n const resolvedRequestTimeoutMs = resolveClientRequestTimeoutMs(options.requestTimeoutMs);\n const result = await client.listTools(undefined, {\n ...(options.signal && { signal: options.signal }),\n ...(resolvedRequestTimeoutMs !== undefined && { timeout: resolvedRequestTimeoutMs }),\n });\n return { handled: true, tools: result.tools };\n } catch (error) {\n if (is401Error(error) || isAbortOrTimeoutError(error)) throw error;\n const status = httpStatusOf(error);\n if (status === 404 || status === 405) return { handled: false };\n throw error;\n } finally {\n await client?.close().catch(() => {});\n }\n}\n\nexport async function closeModernMCPConnections(): Promise<void> {\n connectionGeneration++;\n const pending = [...pendingModernConnections.values()];\n pendingModernConnections.clear();\n const settled = await Promise.allSettled(pending);\n const clients = new Set(modernConnections.values());\n for (const result of settled) {\n if (result.status === 'fulfilled') clients.add(result.value);\n }\n modernConnections.clear();\n legacyConnectionExpiresAt.clear();\n knownLegacyConnections.clear();\n for (const client of clients) {\n try {\n await client.close();\n } catch {\n /* ignore close errors */\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/protocols/mcp-modern.ts"],"sourcesContent":["/**\n * MCP 2026-07-28 client path.\n *\n * The v2 SDK removed the experimental 2025 Tasks interception API. During the\n * migration window we therefore negotiate with the v2 client first and use it\n * only when the peer selects the modern protocol era. Legacy peers fall back\n * to mcp-tasks.ts, which keeps the existing v1 Tasks behavior intact.\n */\n\nimport {\n Client,\n StreamableHTTPClientTransport,\n type OAuthClientProvider as ModernOAuthClientProvider,\n type Tool,\n} from '@modelcontextprotocol/client';\nimport { createHmac } from 'node:crypto';\nimport { createMCPAuthHeaders } from '../auth';\nimport { is401Error } from '../errors';\nimport { withSpan, injectTraceHeaders } from '../observability/tracing';\nimport { buildAgentSigningFetch, signingContextStorage, type AgentSigningContext } from '../signing/client';\nimport type { DebugLogEntry } from '../types/adcp';\nimport {\n isAbortOrTimeoutError,\n resolveClientRequestTimeoutMs,\n resolveRequestTimeoutMs,\n withAbortSignal,\n} from './abort';\nimport { wrapFetchWithCapture } from './rawResponseCapture';\nimport { wrapFetchWithSizeLimit } from './responseSizeLimit';\nimport { wrapFetchWithTransportDiagnostics } from './transportDiagnostics';\n\ntype CallToolResponse = {\n isError?: boolean;\n content?: Array<{ type: string; text?: string }>;\n [key: string]: unknown;\n};\n\nexport type ModernMCPAttempt = { handled: false } | { handled: true; response: CallToolResponse };\nexport type ModernMCPListAttempt = { handled: false } | { handled: true; tools: Tool[] };\n\nexport interface ModernMCPConnectionOptions {\n signingContext?: AgentSigningContext;\n authProvider?: object;\n signal?: AbortSignal;\n requestTimeoutMs?: number;\n fetchFn?: typeof fetch;\n /** Use the v2 SDK's negotiated legacy client instead of handing off to v1. */\n handleLegacy?: boolean;\n}\n\ninterface ModernConnectionOptions {\n agentUrl: string;\n authToken?: string;\n customHeaders?: Record<string, string>;\n debugLogs: DebugLogEntry[];\n signingContext?: AgentSigningContext;\n authProvider?: object;\n signal?: AbortSignal;\n requestTimeoutMs?: number;\n fetchFn?: typeof fetch;\n handleLegacy?: boolean;\n}\n\nconst modernConnections = new Map<string, Client>();\nconst legacyConnectionExpiresAt = new Map<string, number>();\nconst pendingModernConnections = new Map<string, Promise<Client>>();\nconst knownLegacyConnections = new Map<string, number>();\nconst MAX_CACHED_CONNECTIONS = 20;\nconst LEGACY_CLASSIFICATION_TTL_MS = 5 * 60 * 1000;\nconst modernOAuthProviderIds = new WeakMap<object, string>();\nconst modernFetchFnIds = new WeakMap<typeof fetch, string>();\nlet nextModernOAuthProviderId = 0;\nlet nextModernFetchFnId = 0;\nlet connectionGeneration = 0;\n\nfunction cacheDisambiguator(value: string): string {\n return createHmac('sha256', '').update(value).digest('hex');\n}\n\nfunction buildAuthHeaders(\n authToken: string | undefined,\n customHeaders: Record<string, string> | undefined,\n authProvider?: object\n): Record<string, string> {\n const filteredHeaders =\n authProvider || authToken\n ? Object.fromEntries(\n Object.entries(customHeaders ?? {}).filter(keyValue => {\n const key = keyValue[0].toLowerCase();\n return key !== 'authorization' && key !== 'x-adcp-auth';\n })\n )\n : customHeaders;\n return {\n ...filteredHeaders,\n ...(!authProvider && authToken ? createMCPAuthHeaders(authToken) : {}),\n };\n}\n\nfunction oauthProviderCacheKey(provider: object | undefined): string | undefined {\n if (!provider) return undefined;\n let key = modernOAuthProviderIds.get(provider);\n if (!key) {\n key = `oauth-provider:${++nextModernOAuthProviderId}`;\n modernOAuthProviderIds.set(provider, key);\n }\n return key;\n}\n\nfunction fetchFnCacheKey(fetchFn: typeof fetch | undefined): string | undefined {\n if (!fetchFn) return undefined;\n let key = modernFetchFnIds.get(fetchFn);\n if (!key) {\n key = `fetch:${++nextModernFetchFnId}`;\n modernFetchFnIds.set(fetchFn, key);\n }\n return key;\n}\n\nfunction connectionCacheKey(\n agentUrl: string,\n headers: Record<string, string>,\n signingCacheKey?: string,\n authProvider?: object,\n fetchFn?: typeof fetch\n): string {\n const normalizedHeaders = Object.entries(headers)\n .map(([key, value]) => [key.toLowerCase(), value] as const)\n .sort(([left], [right]) => left.localeCompare(right));\n const parts = [agentUrl, `headers:${cacheDisambiguator(JSON.stringify(normalizedHeaders))}`];\n if (signingCacheKey) parts.push(signingCacheKey);\n const providerKey = oauthProviderCacheKey(authProvider);\n if (providerKey) parts.push(providerKey);\n const fetchKey = fetchFnCacheKey(fetchFn);\n if (fetchKey) parts.push(fetchKey);\n return parts.join('::');\n}\n\nfunction isKnownLegacy(cacheKey: string): boolean {\n const classifiedAt = knownLegacyConnections.get(cacheKey);\n if (classifiedAt === undefined) return false;\n if (Date.now() - classifiedAt > LEGACY_CLASSIFICATION_TTL_MS) {\n knownLegacyConnections.delete(cacheKey);\n return false;\n }\n knownLegacyConnections.delete(cacheKey);\n knownLegacyConnections.set(cacheKey, classifiedAt);\n return true;\n}\n\nfunction markKnownLegacy(cacheKey: string): void {\n knownLegacyConnections.delete(cacheKey);\n knownLegacyConnections.set(cacheKey, Date.now());\n while (knownLegacyConnections.size > MAX_CACHED_CONNECTIONS) {\n const oldest = knownLegacyConnections.keys().next().value;\n if (!oldest) break;\n knownLegacyConnections.delete(oldest);\n }\n}\n\nfunction httpStatusOf(error: unknown, depth = 0): number | undefined {\n if (!error || typeof error !== 'object' || depth > 4) return undefined;\n const candidate = error as { status?: unknown; code?: unknown; cause?: unknown; response?: { status?: unknown } };\n if (typeof candidate.status === 'number') return candidate.status;\n if (typeof candidate.response?.status === 'number') return candidate.response.status;\n if (typeof candidate.code === 'number' && candidate.code >= 100 && candidate.code <= 599) return candidate.code;\n return httpStatusOf(candidate.cause, depth + 1);\n}\n\nfunction withPerRequestTraceHeaders(fetchImpl: typeof fetch): typeof fetch {\n return (input, init) => {\n const headers = new Headers(input instanceof Request ? input.headers : undefined);\n new Headers(init?.headers).forEach((value, key) => headers.set(key, value));\n for (const [key, value] of Object.entries(injectTraceHeaders())) headers.set(key, value);\n return fetchImpl(input, { ...init, headers });\n };\n}\n\nfunction getCachedConnection(cacheKey: string): Client | undefined {\n const client = modernConnections.get(cacheKey);\n if (client) {\n const legacyExpiry = legacyConnectionExpiresAt.get(cacheKey);\n if (legacyExpiry !== undefined && legacyExpiry <= Date.now()) {\n modernConnections.delete(cacheKey);\n legacyConnectionExpiresAt.delete(cacheKey);\n void client.close().catch(() => {});\n return undefined;\n }\n modernConnections.delete(cacheKey);\n modernConnections.set(cacheKey, client);\n }\n return client;\n}\n\nfunction evictLeastRecentlyUsed(): void {\n if (modernConnections.size <= MAX_CACHED_CONNECTIONS) return;\n const oldestKey = modernConnections.keys().next().value;\n if (!oldestKey) return;\n const client = modernConnections.get(oldestKey);\n modernConnections.delete(oldestKey);\n legacyConnectionExpiresAt.delete(oldestKey);\n void client?.close().catch(() => {});\n}\n\nasync function createNegotiatedClient(\n options: ModernConnectionOptions,\n authHeaders: Record<string, string>\n): Promise<Client> {\n const requestTimeoutMs = resolveRequestTimeoutMs(options.requestTimeoutMs);\n const clientRequestTimeoutMs = resolveClientRequestTimeoutMs(options.requestTimeoutMs);\n const rawNetworkFetch: typeof fetch = options.fetchFn ?? ((input, init) => fetch(input, init));\n const networkFetch: typeof fetch = (input, init) =>\n withAbortSignal<Response>([options.signal, init?.signal], requestTimeoutMs, signal =>\n rawNetworkFetch(input, { ...init, signal })\n );\n const diagnosticFetch = wrapFetchWithTransportDiagnostics(wrapFetchWithSizeLimit(networkFetch));\n const signedFetch: typeof fetch = options.signingContext\n ? (buildAgentSigningFetch({\n upstream: diagnosticFetch,\n signing: options.signingContext.signing,\n getCapability: options.signingContext.getCapability,\n }) as typeof fetch)\n : diagnosticFetch;\n const transport = new StreamableHTTPClientTransport(new URL(options.agentUrl), {\n requestInit: { headers: authHeaders, redirect: 'manual' },\n fetch: wrapFetchWithCapture(withPerRequestTraceHeaders(signedFetch)),\n ...(options.authProvider && {\n authProvider: options.authProvider as ModernOAuthClientProvider,\n }),\n });\n const client = new Client(\n { name: 'AdCP-Client', version: '1.0.0' },\n {\n versionNegotiation: {\n mode: 'auto',\n ...(clientRequestTimeoutMs !== undefined && { probe: { timeoutMs: clientRequestTimeoutMs } }),\n },\n }\n );\n\n try {\n await client.connect(transport, {\n ...(options.signal && { signal: options.signal }),\n ...(clientRequestTimeoutMs !== undefined && { timeout: clientRequestTimeoutMs }),\n });\n return client;\n } catch (error) {\n try {\n await client.close();\n } catch {\n /* ignore close errors */\n }\n throw error;\n }\n}\n\nasync function getOrCreateModernConnection(\n cacheKey: string,\n options: ModernConnectionOptions,\n authHeaders: Record<string, string>\n): Promise<Client> {\n const cached = getCachedConnection(cacheKey);\n if (cached) return cached;\n\n const pending = pendingModernConnections.get(cacheKey);\n if (pending) return pending;\n\n const generation = connectionGeneration;\n const promise = createNegotiatedClient(options, authHeaders)\n .then(client => {\n if (\n (client.getProtocolEra() === 'modern' || options.handleLegacy === true) &&\n generation === connectionGeneration\n ) {\n modernConnections.set(cacheKey, client);\n if (client.getProtocolEra() === 'legacy') {\n legacyConnectionExpiresAt.set(cacheKey, Date.now() + LEGACY_CLASSIFICATION_TTL_MS);\n } else {\n legacyConnectionExpiresAt.delete(cacheKey);\n }\n evictLeastRecentlyUsed();\n } else if (generation !== connectionGeneration) {\n void client.close().catch(() => {});\n }\n return client;\n })\n .finally(() => {\n if (pendingModernConnections.get(cacheKey) === promise) pendingModernConnections.delete(cacheKey);\n });\n pendingModernConnections.set(cacheKey, promise);\n return promise;\n}\n\nasync function callOnModernClient(\n client: Client,\n toolName: string,\n args: Record<string, unknown>,\n signal?: AbortSignal,\n requestTimeoutMs?: number\n): Promise<CallToolResponse> {\n const resolvedRequestTimeoutMs = resolveClientRequestTimeoutMs(requestTimeoutMs);\n return (await client.callTool(\n { name: toolName, arguments: args },\n {\n ...(signal && { signal }),\n ...(resolvedRequestTimeoutMs !== undefined && { timeout: resolvedRequestTimeoutMs }),\n }\n )) as CallToolResponse;\n}\n\nasync function attemptModernCall(\n options: ModernConnectionOptions,\n toolName: string,\n args: Record<string, unknown>\n): Promise<ModernMCPAttempt> {\n const authHeaders = buildAuthHeaders(options.authToken, options.customHeaders, options.authProvider);\n const cacheKey = connectionCacheKey(\n options.agentUrl,\n authHeaders,\n options.signingContext?.cacheKey,\n options.authProvider,\n options.fetchFn\n );\n if (isKnownLegacy(cacheKey)) return { handled: false };\n\n const guardedConnection =\n options.signal !== undefined || options.requestTimeoutMs !== undefined || options.fetchFn !== undefined;\n let client: Client;\n try {\n client = guardedConnection\n ? await createNegotiatedClient(options, authHeaders)\n : await getOrCreateModernConnection(cacheKey, options, authHeaders);\n } catch (error) {\n const status = httpStatusOf(error);\n if (status === 404 || status === 405) {\n markKnownLegacy(cacheKey);\n options.debugLogs.push({\n type: 'info',\n message: `MCP: Modern Streamable HTTP is unavailable (HTTP ${status}); preserving the v1 transport path`,\n timestamp: new Date().toISOString(),\n });\n return { handled: false };\n }\n throw error;\n }\n\n if (client.getProtocolEra() !== 'modern') {\n if (options.handleLegacy === true) {\n options.debugLogs.push({\n type: 'info',\n message: `MCP: v2 client selected the legacy protocol era for ${toolName}`,\n timestamp: new Date().toISOString(),\n });\n } else {\n markKnownLegacy(cacheKey);\n try {\n await client.close();\n } catch {\n /* ignore close errors */\n }\n options.debugLogs.push({\n type: 'info',\n message: `MCP: Server selected the legacy protocol era for ${toolName}; preserving the v1 Tasks path`,\n timestamp: new Date().toISOString(),\n });\n return { handled: false };\n }\n }\n\n options.debugLogs.push({\n type: 'success',\n message: `MCP: Negotiated protocol ${client.getNegotiatedProtocolVersion()} for ${toolName}`,\n timestamp: new Date().toISOString(),\n });\n\n try {\n const response = await callOnModernClient(client, toolName, args, options.signal, options.requestTimeoutMs);\n return { handled: true, response };\n } catch (error) {\n // A tool request may have reached the server even when its response was\n // lost. Never replay automatically: mutating AdCP tools depend on the\n // caller's explicit idempotency policy, not transport guesswork.\n modernConnections.delete(cacheKey);\n legacyConnectionExpiresAt.delete(cacheKey);\n try {\n await client.close();\n } catch {\n /* ignore close errors */\n }\n throw error;\n } finally {\n if (guardedConnection) {\n try {\n await client.close();\n } catch {\n /* ignore close errors */\n }\n }\n }\n}\n\n/**\n * Try a tool call using the MCP 2026-07-28 protocol era.\n *\n * `handled: false` means the caller must use the existing v1 client. This is\n * deliberately a result rather than an exception because legacy negotiation\n * is normal during the transition window.\n */\nexport async function tryCallModernMCPTool(\n agentUrl: string,\n toolName: string,\n args: Record<string, unknown>,\n authToken?: string,\n debugLogs: DebugLogEntry[] = [],\n customHeaders?: Record<string, string>,\n options: ModernMCPConnectionOptions = {}\n): Promise<ModernMCPAttempt> {\n return withSpan('adcp.mcp.negotiate', { 'adcp.tool': toolName, 'http.url': agentUrl }, () =>\n signingContextStorage.run(options.signingContext, () =>\n attemptModernCall(\n {\n agentUrl,\n authToken,\n customHeaders,\n debugLogs,\n signingContext: options.signingContext,\n authProvider: options.authProvider,\n signal: options.signal,\n requestTimeoutMs: options.requestTimeoutMs,\n fetchFn: options.fetchFn,\n handleLegacy: options.handleLegacy,\n },\n toolName,\n args\n )\n )\n );\n}\n\n/**\n * Probe an endpoint with the official v2 client's auto negotiation.\n * `connected: false` lets endpoint discovery retain its v1 SSE fallback.\n */\nexport async function probeModernMCPConnection(\n agentUrl: string,\n authToken?: string,\n customHeaders?: Record<string, string>,\n options: ModernMCPConnectionOptions = {}\n): Promise<{ connected: boolean; era?: 'legacy' | 'modern' }> {\n const connectionOptions: ModernConnectionOptions = {\n agentUrl,\n authToken,\n customHeaders,\n debugLogs: [],\n signingContext: options.signingContext,\n authProvider: options.authProvider,\n signal: options.signal,\n requestTimeoutMs: options.requestTimeoutMs,\n fetchFn: options.fetchFn,\n handleLegacy: options.handleLegacy,\n };\n const authHeaders = buildAuthHeaders(authToken, customHeaders, options.authProvider);\n let client: Client | undefined;\n try {\n client = await createNegotiatedClient(connectionOptions, authHeaders);\n return { connected: true, era: client.getProtocolEra() };\n } catch (error) {\n if (is401Error(error) || isAbortOrTimeoutError(error)) throw error;\n const status = httpStatusOf(error);\n if (status === 404 || status === 405) return { connected: false };\n throw error;\n } finally {\n await client?.close().catch(() => {});\n }\n}\n\n/** List tools when the endpoint selected the modern era; otherwise let the v1 caller continue. */\nexport async function tryListModernMCPTools(\n agentUrl: string,\n authToken?: string,\n customHeaders?: Record<string, string>,\n options: ModernMCPConnectionOptions = {}\n): Promise<ModernMCPListAttempt> {\n const connectionOptions: ModernConnectionOptions = {\n agentUrl,\n authToken,\n customHeaders,\n debugLogs: [],\n signingContext: options.signingContext,\n authProvider: options.authProvider,\n signal: options.signal,\n requestTimeoutMs: options.requestTimeoutMs,\n fetchFn: options.fetchFn,\n };\n const authHeaders = buildAuthHeaders(authToken, customHeaders, options.authProvider);\n let client: Client | undefined;\n try {\n client = await createNegotiatedClient(connectionOptions, authHeaders);\n if (client.getProtocolEra() !== 'modern') return { handled: false };\n const resolvedRequestTimeoutMs = resolveClientRequestTimeoutMs(options.requestTimeoutMs);\n const result = await client.listTools(undefined, {\n ...(options.signal && { signal: options.signal }),\n ...(resolvedRequestTimeoutMs !== undefined && { timeout: resolvedRequestTimeoutMs }),\n });\n return { handled: true, tools: result.tools };\n } catch (error) {\n if (is401Error(error) || isAbortOrTimeoutError(error)) throw error;\n const status = httpStatusOf(error);\n if (status === 404 || status === 405) return { handled: false };\n throw error;\n } finally {\n await client?.close().catch(() => {});\n }\n}\n\nexport async function closeModernMCPConnections(): Promise<void> {\n connectionGeneration++;\n const pending = [...pendingModernConnections.values()];\n pendingModernConnections.clear();\n const settled = await Promise.allSettled(pending);\n const clients = new Set(modernConnections.values());\n for (const result of settled) {\n if (result.status === 'fulfilled') clients.add(result.value);\n }\n modernConnections.clear();\n legacyConnectionExpiresAt.clear();\n knownLegacyConnections.clear();\n for (const client of clients) {\n try {\n await client.close();\n } catch {\n /* ignore close errors */\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -40,6 +40,12 @@ export interface MCPCallOptions {
|
|
|
40
40
|
signal?: AbortSignal;
|
|
41
41
|
/** Optional per-request timeout for connect and callTool. */
|
|
42
42
|
requestTimeoutMs?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Scoped fetch implementation used for MCP requests, OAuth discovery, and token exchange.
|
|
45
|
+
* Calls with a scoped fetcher use an isolated one-shot connection rather than the shared
|
|
46
|
+
* OAuth connection cache, so callers must not rely on cross-call MCP session state.
|
|
47
|
+
*/
|
|
48
|
+
fetchFn?: typeof fetch;
|
|
43
49
|
}
|
|
44
50
|
/**
|
|
45
51
|
* Result of an MCP connection attempt
|
|
@@ -123,6 +129,7 @@ export declare function connectMCP(options: {
|
|
|
123
129
|
signingContext?: AgentSigningContext;
|
|
124
130
|
signal?: AbortSignal;
|
|
125
131
|
requestTimeoutMs?: number;
|
|
132
|
+
fetchFn?: typeof fetch;
|
|
126
133
|
}): Promise<MCPConnectionResult>;
|
|
127
134
|
/**
|
|
128
135
|
* Call an MCP tool with OAuth support.
|
|
@@ -133,6 +140,10 @@ export declare function connectMCP(options: {
|
|
|
133
140
|
* session/source/principal; the provider owns token refresh state for the
|
|
134
141
|
* cached transport.
|
|
135
142
|
*
|
|
143
|
+
* Supplying `fetchFn` opts out of connection reuse. Scoped fetchers commonly
|
|
144
|
+
* carry request- or tenant-specific network policy, so each call gets an
|
|
145
|
+
* isolated connection that is closed after the tool response.
|
|
146
|
+
*
|
|
136
147
|
* Signing: this path consumes `options.signingContext` via the transport —
|
|
137
148
|
* `connectMCP` attaches a signing-fetch wrapper at transport-creation time —
|
|
138
149
|
* rather than via `signingContextStorage`. The OAuth cache key includes the
|
|
@@ -40,6 +40,12 @@ export interface MCPCallOptions {
|
|
|
40
40
|
signal?: AbortSignal;
|
|
41
41
|
/** Optional per-request timeout for connect and callTool. */
|
|
42
42
|
requestTimeoutMs?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Scoped fetch implementation used for MCP requests, OAuth discovery, and token exchange.
|
|
45
|
+
* Calls with a scoped fetcher use an isolated one-shot connection rather than the shared
|
|
46
|
+
* OAuth connection cache, so callers must not rely on cross-call MCP session state.
|
|
47
|
+
*/
|
|
48
|
+
fetchFn?: typeof fetch;
|
|
43
49
|
}
|
|
44
50
|
/**
|
|
45
51
|
* Result of an MCP connection attempt
|
|
@@ -123,6 +129,7 @@ export declare function connectMCP(options: {
|
|
|
123
129
|
signingContext?: AgentSigningContext;
|
|
124
130
|
signal?: AbortSignal;
|
|
125
131
|
requestTimeoutMs?: number;
|
|
132
|
+
fetchFn?: typeof fetch;
|
|
126
133
|
}): Promise<MCPConnectionResult>;
|
|
127
134
|
/**
|
|
128
135
|
* Call an MCP tool with OAuth support.
|
|
@@ -133,6 +140,10 @@ export declare function connectMCP(options: {
|
|
|
133
140
|
* session/source/principal; the provider owns token refresh state for the
|
|
134
141
|
* cached transport.
|
|
135
142
|
*
|
|
143
|
+
* Supplying `fetchFn` opts out of connection reuse. Scoped fetchers commonly
|
|
144
|
+
* carry request- or tenant-specific network policy, so each call gets an
|
|
145
|
+
* isolated connection that is closed after the tool response.
|
|
146
|
+
*
|
|
136
147
|
* Signing: this path consumes `options.signingContext` via the transport —
|
|
137
148
|
* `connectMCP` attaches a signing-fetch wrapper at transport-creation time —
|
|
138
149
|
* rather than via `signingContextStorage`. The OAuth cache key includes the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/lib/protocols/mcp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,2CAA2C,CAAC;AAChF,OAAO,EACL,6BAA6B,EAG9B,MAAM,oDAAoD,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAIpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAiD,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAc5G,OAAO,EAAE,iBAAiB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/lib/protocols/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -49,8 +49,10 @@ const pendingConnections = /* @__PURE__ */ new Map();
|
|
|
49
49
|
const oauthConnectionCache = /* @__PURE__ */ new Map();
|
|
50
50
|
const pendingOAuthConnections = /* @__PURE__ */ new Map();
|
|
51
51
|
const oauthProviderIds = /* @__PURE__ */ new WeakMap();
|
|
52
|
+
const oauthFetchFnIds = /* @__PURE__ */ new WeakMap();
|
|
52
53
|
const MAX_CACHED_CONNECTIONS = 20;
|
|
53
54
|
let nextOAuthProviderId = 0;
|
|
55
|
+
let nextOAuthFetchFnId = 0;
|
|
54
56
|
const knownStreamableHTTPUrls = /* @__PURE__ */ new Set();
|
|
55
57
|
function trackStreamableHTTPUrl(url) {
|
|
56
58
|
knownStreamableHTTPUrls.delete(url);
|
|
@@ -158,14 +160,23 @@ function getOAuthProviderDisambiguator(authProvider) {
|
|
|
158
160
|
}
|
|
159
161
|
return id;
|
|
160
162
|
}
|
|
163
|
+
function getOAuthFetchFnDisambiguator(fetchFn) {
|
|
164
|
+
let id = oauthFetchFnIds.get(fetchFn);
|
|
165
|
+
if (!id) {
|
|
166
|
+
id = cacheDisambiguator(`oauth-fetch:${++nextOAuthFetchFnId}`);
|
|
167
|
+
oauthFetchFnIds.set(fetchFn, id);
|
|
168
|
+
}
|
|
169
|
+
return id;
|
|
170
|
+
}
|
|
161
171
|
function customHeadersDisambiguator(customHeaders) {
|
|
162
172
|
return headersCacheDisambiguator(customHeaders);
|
|
163
173
|
}
|
|
164
|
-
function oauthConnectionCacheKey(agentUrl, authProvider, signingCacheKey, customHeaders) {
|
|
174
|
+
function oauthConnectionCacheKey(agentUrl, authProvider, signingCacheKey, customHeaders, fetchFn) {
|
|
165
175
|
const parts = [`${agentUrl}::oauth:${getOAuthProviderDisambiguator(authProvider)}`];
|
|
166
176
|
if (signingCacheKey) parts.push(signingCacheKey);
|
|
167
177
|
const headersKey = customHeadersDisambiguator(customHeaders);
|
|
168
178
|
if (headersKey) parts.push(`headers:${headersKey}`);
|
|
179
|
+
if (fetchFn) parts.push(`fetch:${getOAuthFetchFnDisambiguator(fetchFn)}`);
|
|
169
180
|
return parts.join("::");
|
|
170
181
|
}
|
|
171
182
|
function getCachedOAuthConnection(key) {
|
|
@@ -196,9 +207,10 @@ async function withCachedOAuthConnection(options, label, fn) {
|
|
|
196
207
|
options.agentUrl,
|
|
197
208
|
options.authProvider,
|
|
198
209
|
options.signingContext?.cacheKey,
|
|
199
|
-
options.customHeaders
|
|
210
|
+
options.customHeaders,
|
|
211
|
+
options.fetchFn
|
|
200
212
|
);
|
|
201
|
-
if (options.signal || options.requestTimeoutMs !== void 0) {
|
|
213
|
+
if (options.signal || options.requestTimeoutMs !== void 0 || options.fetchFn) {
|
|
202
214
|
const { client } = await connectMCP(options);
|
|
203
215
|
try {
|
|
204
216
|
return await fn(client);
|
|
@@ -586,7 +598,8 @@ async function connectMCP(options) {
|
|
|
586
598
|
customHeaders,
|
|
587
599
|
signingContext,
|
|
588
600
|
signal,
|
|
589
|
-
requestTimeoutMs: configuredRequestTimeoutMs
|
|
601
|
+
requestTimeoutMs: configuredRequestTimeoutMs,
|
|
602
|
+
fetchFn
|
|
590
603
|
} = options;
|
|
591
604
|
const baseUrl = new URL(agentUrl);
|
|
592
605
|
debugLogs.push({
|
|
@@ -632,11 +645,12 @@ async function connectMCP(options) {
|
|
|
632
645
|
...signal && { signal },
|
|
633
646
|
...clientRequestTimeoutMs !== void 0 && { timeout: clientRequestTimeoutMs }
|
|
634
647
|
};
|
|
648
|
+
const rawNetworkFetch = fetchFn ?? ((input, init) => fetch(input, init));
|
|
635
649
|
const sizeLimited = (0, import_responseSizeLimit.wrapFetchWithSizeLimit)(
|
|
636
650
|
(input, init) => (0, import_abort.withAbortSignal)(
|
|
637
651
|
[signal, init?.signal],
|
|
638
652
|
requestTimeoutMs,
|
|
639
|
-
(linkedSignal) =>
|
|
653
|
+
(linkedSignal) => rawNetworkFetch(input, { ...init, signal: linkedSignal })
|
|
640
654
|
)
|
|
641
655
|
);
|
|
642
656
|
const diagnosticFetch = (0, import_transportDiagnostics.wrapFetchWithTransportDiagnostics)(sizeLimited);
|
|
@@ -691,7 +705,8 @@ async function callMCPToolWithOAuth(options) {
|
|
|
691
705
|
customHeaders,
|
|
692
706
|
signingContext,
|
|
693
707
|
signal,
|
|
694
|
-
requestTimeoutMs
|
|
708
|
+
requestTimeoutMs,
|
|
709
|
+
fetchFn
|
|
695
710
|
} = options;
|
|
696
711
|
const resolvedRequestTimeoutMs = (0, import_abort.resolveClientRequestTimeoutMs)(requestTimeoutMs);
|
|
697
712
|
const requestOptions = {
|
|
@@ -699,7 +714,7 @@ async function callMCPToolWithOAuth(options) {
|
|
|
699
714
|
...resolvedRequestTimeoutMs !== void 0 && { timeout: resolvedRequestTimeoutMs }
|
|
700
715
|
};
|
|
701
716
|
if (!authProvider) {
|
|
702
|
-
return callMCPTool(agentUrl, toolName, args, authToken, debugLogs, customHeaders, signingContext,
|
|
717
|
+
return callMCPTool(agentUrl, toolName, args, authToken, debugLogs, customHeaders, signingContext, fetchFn, {
|
|
703
718
|
signal,
|
|
704
719
|
requestTimeoutMs
|
|
705
720
|
});
|
|
@@ -709,6 +724,7 @@ async function callMCPToolWithOAuth(options) {
|
|
|
709
724
|
signingContext,
|
|
710
725
|
signal,
|
|
711
726
|
requestTimeoutMs,
|
|
727
|
+
fetchFn,
|
|
712
728
|
handleLegacy: true
|
|
713
729
|
});
|
|
714
730
|
if (modernAttempt.handled) {
|
|
@@ -727,7 +743,8 @@ async function callMCPToolWithOAuth(options) {
|
|
|
727
743
|
customHeaders,
|
|
728
744
|
signingContext,
|
|
729
745
|
signal,
|
|
730
|
-
requestTimeoutMs
|
|
746
|
+
requestTimeoutMs,
|
|
747
|
+
fetchFn
|
|
731
748
|
},
|
|
732
749
|
toolName,
|
|
733
750
|
async (client) => {
|