@adcp/sdk 15.4.0 → 15.6.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 +15 -0
- package/dist/lib/advanced.d.mts +2 -2
- package/dist/lib/advanced.d.ts +2 -2
- package/dist/lib/advanced.js +8 -2
- package/dist/lib/advanced.mjs +8 -2
- package/dist/lib/auth/oauth/index.d.mts +1 -0
- package/dist/lib/auth/oauth/index.d.ts +1 -0
- package/dist/lib/auth/oauth/index.js +5 -0
- package/dist/lib/auth/oauth/index.mjs +3 -0
- package/dist/lib/auth/oauth/pending-web-flow.d.mts +16 -0
- package/dist/lib/auth/oauth/pending-web-flow.d.ts +16 -0
- package/dist/lib/auth/oauth/pending-web-flow.js +66 -0
- package/dist/lib/auth/oauth/pending-web-flow.mjs +41 -0
- package/dist/lib/auth/oauth/web-flow.js +3 -3
- package/dist/lib/auth/oauth/web-flow.mjs +3 -3
- package/dist/lib/core/AgentClient.d.mts +4 -0
- package/dist/lib/core/AgentClient.d.ts +4 -0
- package/dist/lib/core/AgentClient.js +8 -0
- package/dist/lib/core/AgentClient.mjs +8 -0
- package/dist/lib/core/SingleAgentClient.d.mts +154 -0
- package/dist/lib/core/SingleAgentClient.d.ts +154 -0
- package/dist/lib/core/SingleAgentClient.js +661 -23
- package/dist/lib/core/SingleAgentClient.mjs +666 -23
- package/dist/lib/core/agent-discovery-cache.d.mts +103 -0
- package/dist/lib/core/agent-discovery-cache.d.ts +103 -0
- package/dist/lib/core/agent-discovery-cache.js +121 -0
- package/dist/lib/core/agent-discovery-cache.mjs +92 -0
- package/dist/lib/index.d.mts +5 -3
- package/dist/lib/index.d.ts +5 -3
- package/dist/lib/index.js +7 -0
- package/dist/lib/index.mjs +6 -0
- package/dist/lib/protocols/index.d.mts +2 -2
- package/dist/lib/protocols/index.d.ts +2 -2
- package/dist/lib/protocols/index.js +1 -1
- package/dist/lib/protocols/index.mjs +1 -1
- package/dist/lib/protocols/mcp-call-context.d.mts +109 -0
- package/dist/lib/protocols/mcp-call-context.d.ts +109 -0
- package/dist/lib/protocols/mcp-call-context.js +221 -0
- package/dist/lib/protocols/mcp-call-context.mjs +186 -0
- package/dist/lib/protocols/mcp-modern.d.mts +9 -1
- package/dist/lib/protocols/mcp-modern.d.ts +9 -1
- package/dist/lib/protocols/mcp-modern.js +180 -104
- package/dist/lib/protocols/mcp-modern.mjs +193 -104
- package/dist/lib/protocols/mcp-scope.d.mts +15 -0
- package/dist/lib/protocols/mcp-scope.d.ts +15 -0
- package/dist/lib/protocols/mcp.d.mts +4 -2
- package/dist/lib/protocols/mcp.d.ts +4 -2
- package/dist/lib/protocols/mcp.js +178 -154
- package/dist/lib/protocols/mcp.mjs +189 -153
- package/dist/lib/protocols/transportDiagnostics.d.mts +33 -1
- package/dist/lib/protocols/transportDiagnostics.d.ts +33 -1
- package/dist/lib/protocols/transportDiagnostics.js +128 -12
- package/dist/lib/protocols/transportDiagnostics.mjs +128 -12
- package/dist/lib/registry/types.generated.d.mts +63 -1
- package/dist/lib/registry/types.generated.d.ts +63 -1
- package/dist/lib/reporting/azure/index.d.mts +26 -0
- package/dist/lib/reporting/azure/index.d.ts +26 -0
- package/dist/lib/reporting/azure/index.js +247 -0
- package/dist/lib/reporting/azure/index.mjs +230 -0
- package/dist/lib/reporting/bigquery/index.d.mts +127 -0
- package/dist/lib/reporting/bigquery/index.d.ts +127 -0
- package/dist/lib/reporting/bigquery/index.js +379 -0
- package/dist/lib/reporting/bigquery/index.mjs +341 -0
- package/dist/lib/reporting/gcs/index.d.mts +2 -0
- package/dist/lib/reporting/gcs/index.d.ts +2 -0
- package/dist/lib/reporting/gcs/index.js +3 -0
- package/dist/lib/reporting/gcs/index.mjs +2 -0
- package/dist/lib/reporting/gcs/row-provider.d.mts +32 -0
- package/dist/lib/reporting/gcs/row-provider.d.ts +32 -0
- package/dist/lib/reporting/gcs/row-provider.js +205 -0
- package/dist/lib/reporting/gcs/row-provider.mjs +188 -0
- package/dist/lib/reporting/ledger/change-feed.d.mts +41 -0
- package/dist/lib/reporting/ledger/change-feed.d.ts +41 -0
- package/dist/lib/reporting/ledger/change-feed.js +101 -0
- package/dist/lib/reporting/ledger/change-feed.mjs +74 -0
- package/dist/lib/reporting/ledger/handler.js +22 -8
- package/dist/lib/reporting/ledger/handler.mjs +22 -8
- package/dist/lib/reporting/ledger/index.d.mts +4 -0
- package/dist/lib/reporting/ledger/index.d.ts +4 -0
- package/dist/lib/reporting/ledger/index.js +9 -1
- package/dist/lib/reporting/ledger/index.mjs +4 -0
- package/dist/lib/reporting/ledger/managed-postgres.d.mts +2 -0
- package/dist/lib/reporting/ledger/managed-postgres.d.ts +2 -0
- package/dist/lib/reporting/ledger/managed-postgres.js +21 -1
- package/dist/lib/reporting/ledger/managed-postgres.mjs +21 -1
- package/dist/lib/reporting/ledger/managed.d.mts +9 -0
- package/dist/lib/reporting/ledger/managed.d.ts +9 -0
- package/dist/lib/reporting/ledger/managed.js +18 -0
- package/dist/lib/reporting/ledger/managed.mjs +18 -0
- package/dist/lib/reporting/ledger/postgres.d.mts +185 -0
- package/dist/lib/reporting/ledger/postgres.d.ts +185 -0
- package/dist/lib/reporting/ledger/postgres.js +872 -26
- package/dist/lib/reporting/ledger/postgres.mjs +880 -26
- package/dist/lib/reporting/ledger/producer.js +10 -1
- package/dist/lib/reporting/ledger/producer.mjs +10 -1
- package/dist/lib/reporting/ledger/row-storage-errors.d.mts +7 -0
- package/dist/lib/reporting/ledger/row-storage-errors.d.ts +7 -0
- package/dist/lib/reporting/ledger/row-storage-errors.js +41 -0
- package/dist/lib/reporting/ledger/row-storage-errors.mjs +16 -0
- package/dist/lib/reporting/ledger/row-storage-migration.d.mts +41 -0
- package/dist/lib/reporting/ledger/row-storage-migration.d.ts +41 -0
- package/dist/lib/reporting/ledger/row-storage-migration.js +234 -0
- package/dist/lib/reporting/ledger/row-storage-migration.mjs +208 -0
- package/dist/lib/reporting/ledger/row-storage-object.d.mts +112 -0
- package/dist/lib/reporting/ledger/row-storage-object.d.ts +112 -0
- package/dist/lib/reporting/ledger/row-storage-object.js +304 -0
- package/dist/lib/reporting/ledger/row-storage-object.mjs +262 -0
- package/dist/lib/reporting/ledger/row-storage-provider-io.d.mts +44 -0
- package/dist/lib/reporting/ledger/row-storage-provider-io.d.ts +44 -0
- package/dist/lib/reporting/ledger/row-storage-provider-io.js +142 -0
- package/dist/lib/reporting/ledger/row-storage-provider-io.mjs +111 -0
- package/dist/lib/reporting/ledger/row-storage.d.mts +224 -0
- package/dist/lib/reporting/ledger/row-storage.d.ts +224 -0
- package/dist/lib/reporting/ledger/row-storage.js +692 -0
- package/dist/lib/reporting/ledger/row-storage.mjs +680 -0
- package/dist/lib/reporting/ledger/types.d.mts +8 -0
- package/dist/lib/reporting/ledger/types.d.ts +8 -0
- package/dist/lib/reporting/s3/index.d.mts +29 -0
- package/dist/lib/reporting/s3/index.d.ts +29 -0
- package/dist/lib/reporting/s3/index.js +324 -0
- package/dist/lib/reporting/s3/index.mjs +317 -0
- package/dist/lib/reporting/service/index.d.mts +43 -1
- package/dist/lib/reporting/service/index.d.ts +43 -1
- package/dist/lib/reporting/service/index.js +69 -1
- package/dist/lib/reporting/service/index.mjs +71 -1
- package/dist/lib/schemas/browser.d.mts +14 -0
- package/dist/lib/schemas/browser.d.ts +14 -0
- package/dist/lib/schemas/browser.js +48 -0
- package/dist/lib/schemas/browser.mjs +20 -0
- package/dist/lib/schemas/index.d.mts +2 -120
- package/dist/lib/schemas/index.d.ts +2 -120
- package/dist/lib/schemas/index.js +3 -11
- package/dist/lib/schemas/index.mjs +1 -9
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/testing/index.d.mts +1 -0
- package/dist/lib/testing/index.d.ts +1 -0
- package/dist/lib/testing/index.js +3 -0
- package/dist/lib/testing/index.mjs +2 -0
- package/dist/lib/testing/pending-web-flow-store.d.mts +20 -0
- package/dist/lib/testing/pending-web-flow-store.d.ts +20 -0
- package/dist/lib/testing/pending-web-flow-store.js +132 -0
- package/dist/lib/testing/pending-web-flow-store.mjs +98 -0
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/validation/get-products-request.d.mts +122 -0
- package/dist/lib/validation/get-products-request.d.ts +122 -0
- package/dist/lib/validation/get-products-request.js +39 -0
- package/dist/lib/validation/get-products-request.mjs +14 -0
- 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.mjs +3 -3
- package/docs/README.md +1 -1
- package/docs/TYPE-SUMMARY.md +35 -2
- package/docs/ZOD-SCHEMAS.md +13 -1
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +142 -0
- package/docs/guides/EXISTING-PLATFORM.md +43 -12
- package/docs/guides/OAUTH-ISSUER-BINDING.md +6 -0
- package/docs/guides/REPORTING-LEDGER.md +374 -0
- package/docs/guides/REPORTING-OPERATIONS.md +76 -1
- package/docs/guides/WEB-OAUTH.md +48 -1
- package/docs/llms.txt +4 -2
- package/docs/migration-14.x-rc-worksheet.md +6 -4
- package/package.json +64 -1
|
@@ -26,7 +26,8 @@ __export(mcp_exports, {
|
|
|
26
26
|
closeOAuthConnections: () => closeOAuthConnections,
|
|
27
27
|
connectMCP: () => connectMCP,
|
|
28
28
|
connectMCPWithFallback: () => connectMCPWithFallback,
|
|
29
|
-
withCachedConnection: () => withCachedConnection
|
|
29
|
+
withCachedConnection: () => withCachedConnection,
|
|
30
|
+
withScopedLegacyConnection: () => withScopedLegacyConnection
|
|
30
31
|
});
|
|
31
32
|
module.exports = __toCommonJS(mcp_exports);
|
|
32
33
|
var import_client = require("@modelcontextprotocol/sdk/client/index.js");
|
|
@@ -48,6 +49,7 @@ var import_abort = require('./abort.js');
|
|
|
48
49
|
var import_mcp_modern = require('./mcp-modern.js');
|
|
49
50
|
var import_mcp_scope = require('./mcp-scope.js');
|
|
50
51
|
var import_session_termination = require('./session-termination.js');
|
|
52
|
+
var import_mcp_call_context = require('./mcp-call-context.js');
|
|
51
53
|
var import_agent_transport_fetch = require('../net/agent-transport-fetch.js');
|
|
52
54
|
const connectionCache = /* @__PURE__ */ new Map();
|
|
53
55
|
const pendingConnections = /* @__PURE__ */ new Map();
|
|
@@ -56,11 +58,9 @@ const pendingOAuthConnections = /* @__PURE__ */ new Map();
|
|
|
56
58
|
const streamableTransports = /* @__PURE__ */ new WeakMap();
|
|
57
59
|
const oauthProviderIds = /* @__PURE__ */ new WeakMap();
|
|
58
60
|
const transportFetchFnIds = /* @__PURE__ */ new WeakMap();
|
|
59
|
-
const transportSignalIds = /* @__PURE__ */ new WeakMap();
|
|
60
61
|
const MAX_CACHED_CONNECTIONS = 20;
|
|
61
62
|
let nextOAuthProviderId = 0;
|
|
62
63
|
let nextTransportFetchFnId = 0;
|
|
63
|
-
let nextTransportSignalId = 0;
|
|
64
64
|
let connectionGeneration = 0;
|
|
65
65
|
let oauthConnectionGeneration = 0;
|
|
66
66
|
async function closeMCPClient(client, terminateSession = true) {
|
|
@@ -80,7 +80,7 @@ function trackStreamableHTTPUrl(url) {
|
|
|
80
80
|
if (oldest) knownStreamableHTTPUrls.delete(oldest);
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
function connectionCacheKey(agentUrl, authToken, signingCacheKey, authHeaders, transportFetch,
|
|
83
|
+
function connectionCacheKey(agentUrl, authToken, signingCacheKey, authHeaders, transportFetch, allowPrivateIp) {
|
|
84
84
|
const parts = [agentUrl];
|
|
85
85
|
const fingerprint = authToken ?? extractAuthHeader(authHeaders);
|
|
86
86
|
if (fingerprint) parts.push(cacheDisambiguator(fingerprint));
|
|
@@ -88,8 +88,6 @@ function connectionCacheKey(agentUrl, authToken, signingCacheKey, authHeaders, t
|
|
|
88
88
|
if (headersKey) parts.push(`headers:${headersKey}`);
|
|
89
89
|
if (signingCacheKey) parts.push(signingCacheKey);
|
|
90
90
|
if (transportFetch) parts.push(`fetch:${getTransportFetchFnDisambiguator(transportFetch)}`);
|
|
91
|
-
if (signal) parts.push(`signal:${getTransportSignalDisambiguator(signal)}`);
|
|
92
|
-
if (requestTimeoutMs !== void 0) parts.push(`timeout:${requestTimeoutMs}`);
|
|
93
91
|
if (allowPrivateIp !== void 0) parts.push(`allow-private-ip:${allowPrivateIp}`);
|
|
94
92
|
const scopeKey = (0, import_mcp_scope.currentMCPConnectionScopeKey)();
|
|
95
93
|
if (scopeKey) parts.push(scopeKey);
|
|
@@ -107,18 +105,19 @@ function extractAuthHeader(headers) {
|
|
|
107
105
|
return void 0;
|
|
108
106
|
}
|
|
109
107
|
function headersCacheDisambiguator(headers) {
|
|
110
|
-
const entries = Object.entries(headers
|
|
111
|
-
const lower = key.toLowerCase();
|
|
112
|
-
return lower !== "traceparent" && lower !== "tracestate" && lower !== "baggage";
|
|
113
|
-
}).map(([key, value]) => [key.toLowerCase(), value]).sort(([a], [b]) => a.localeCompare(b));
|
|
108
|
+
const entries = Object.entries((0, import_mcp_call_context.splitConnectionHeaders)(headers).identity).map(([key, value]) => [key.toLowerCase(), value]).sort(([a], [b]) => a.localeCompare(b));
|
|
114
109
|
return entries.length > 0 ? cacheDisambiguator(JSON.stringify(entries)) : void 0;
|
|
115
110
|
}
|
|
116
|
-
function withPerRequestTraceHeaders(fetchImpl) {
|
|
111
|
+
function withPerRequestTraceHeaders(fetchImpl, directDefaults) {
|
|
117
112
|
return (input, init) => {
|
|
118
113
|
const headers = new Headers(input instanceof Request ? input.headers : void 0);
|
|
119
114
|
new Headers(init?.headers).forEach((value, key) => headers.set(key, value));
|
|
120
|
-
|
|
121
|
-
return fetchImpl(input, { ...init, headers });
|
|
115
|
+
(0, import_mcp_call_context.applyMCPCallHeaders)(headers, directDefaults);
|
|
116
|
+
if (headers.has("traceparent")) return fetchImpl(input, { ...init, headers, ...(0, import_mcp_call_context.linkedCallSignal)(init) });
|
|
117
|
+
for (const [key, value] of Object.entries((0, import_tracing.injectTraceHeaders)())) {
|
|
118
|
+
if ((0, import_mcp_call_context.isCorrelationHeader)(key) && !headers.has(key)) headers.set(key, value);
|
|
119
|
+
}
|
|
120
|
+
return fetchImpl(input, { ...init, headers, ...(0, import_mcp_call_context.linkedCallSignal)(init) });
|
|
122
121
|
};
|
|
123
122
|
}
|
|
124
123
|
function getCachedConnection(key) {
|
|
@@ -135,7 +134,7 @@ function evictLeastRecentlyUsed() {
|
|
|
135
134
|
if (!lruKey) return;
|
|
136
135
|
const oldClient = connectionCache.get(lruKey);
|
|
137
136
|
connectionCache.delete(lruKey);
|
|
138
|
-
if (oldClient) void closeMCPClient(oldClient).catch(() => {
|
|
137
|
+
if (oldClient) void (0, import_mcp_call_context.closeWhenIdle)(oldClient, () => closeMCPClient(oldClient)).catch(() => {
|
|
139
138
|
});
|
|
140
139
|
}
|
|
141
140
|
function evictLeastRecentlyUsedOAuth() {
|
|
@@ -144,7 +143,7 @@ function evictLeastRecentlyUsedOAuth() {
|
|
|
144
143
|
if (!lruKey) return;
|
|
145
144
|
const oldClient = oauthConnectionCache.get(lruKey);
|
|
146
145
|
oauthConnectionCache.delete(lruKey);
|
|
147
|
-
if (oldClient) void closeMCPClient(oldClient).catch(() => {
|
|
146
|
+
if (oldClient) void (0, import_mcp_call_context.closeWhenIdle)(oldClient, () => closeMCPClient(oldClient)).catch(() => {
|
|
148
147
|
});
|
|
149
148
|
}
|
|
150
149
|
async function closeOAuthConnections() {
|
|
@@ -185,31 +184,37 @@ async function closeMCPConnections() {
|
|
|
185
184
|
await (0, import_mcp_modern.closeModernMCPConnections)();
|
|
186
185
|
}
|
|
187
186
|
async function getOrCreateConnection(cacheKey, baseUrl, authHeaders, debugLogs, label, transportFetch, requestOptions = {}) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
});
|
|
197
|
-
throw new Error(`MCP ${label} completed after connection teardown`);
|
|
187
|
+
for (let attempt = 0; ; attempt++) {
|
|
188
|
+
const cached = getCachedConnection(cacheKey);
|
|
189
|
+
if (cached) return cached;
|
|
190
|
+
const pending = pendingConnections.get(cacheKey);
|
|
191
|
+
if (pending) {
|
|
192
|
+
const joined = await (0, import_mcp_call_context.joinPendingConnection)(pending, requestOptions, attempt);
|
|
193
|
+
if (joined === import_mcp_call_context.RETRY_CONNECT) continue;
|
|
194
|
+
return joined;
|
|
198
195
|
}
|
|
199
|
-
|
|
200
|
-
(
|
|
201
|
-
if (
|
|
202
|
-
|
|
203
|
-
|
|
196
|
+
const generation = connectionGeneration;
|
|
197
|
+
const promise = connectMCPWithFallback(baseUrl, authHeaders, debugLogs, label, transportFetch, requestOptions).then(async (client) => {
|
|
198
|
+
if (generation !== connectionGeneration) {
|
|
199
|
+
await closeMCPClient(client).catch(() => {
|
|
200
|
+
});
|
|
201
|
+
throw new Error(`MCP ${label} completed after connection teardown`);
|
|
202
|
+
}
|
|
203
|
+
connectionCache.set(cacheKey, client);
|
|
204
|
+
(0, import_mcp_scope.registerMCPConnectionScopeCleanup)("legacy", cacheKey, async () => {
|
|
205
|
+
if (connectionCache.get(cacheKey) !== client) return;
|
|
206
|
+
connectionCache.delete(cacheKey);
|
|
207
|
+
await closeMCPClient(client);
|
|
208
|
+
});
|
|
209
|
+
evictLeastRecentlyUsed();
|
|
210
|
+
return client;
|
|
211
|
+
}).finally(() => {
|
|
212
|
+
if (pendingConnections.get(cacheKey) === promise) pendingConnections.delete(cacheKey);
|
|
204
213
|
});
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
});
|
|
210
|
-
pendingConnections.set(cacheKey, promise);
|
|
211
|
-
(0, import_mcp_scope.registerMCPConnectionScopePending)(promise);
|
|
212
|
-
return promise;
|
|
214
|
+
pendingConnections.set(cacheKey, promise);
|
|
215
|
+
(0, import_mcp_scope.registerMCPConnectionScopePending)(promise);
|
|
216
|
+
return promise;
|
|
217
|
+
}
|
|
213
218
|
}
|
|
214
219
|
function getOAuthProviderDisambiguator(authProvider) {
|
|
215
220
|
let id = oauthProviderIds.get(authProvider);
|
|
@@ -227,25 +232,15 @@ function getTransportFetchFnDisambiguator(fetchFn) {
|
|
|
227
232
|
}
|
|
228
233
|
return id;
|
|
229
234
|
}
|
|
230
|
-
function getTransportSignalDisambiguator(signal) {
|
|
231
|
-
let id = transportSignalIds.get(signal);
|
|
232
|
-
if (!id) {
|
|
233
|
-
id = cacheDisambiguator(`transport-signal:${++nextTransportSignalId}`);
|
|
234
|
-
transportSignalIds.set(signal, id);
|
|
235
|
-
}
|
|
236
|
-
return id;
|
|
237
|
-
}
|
|
238
235
|
function customHeadersDisambiguator(customHeaders) {
|
|
239
236
|
return headersCacheDisambiguator(customHeaders);
|
|
240
237
|
}
|
|
241
|
-
function oauthConnectionCacheKey(agentUrl, authProvider, signingCacheKey, customHeaders, fetchFn,
|
|
238
|
+
function oauthConnectionCacheKey(agentUrl, authProvider, signingCacheKey, customHeaders, fetchFn, allowPrivateIp) {
|
|
242
239
|
const parts = [`${agentUrl}::oauth:${getOAuthProviderDisambiguator(authProvider)}`];
|
|
243
240
|
if (signingCacheKey) parts.push(signingCacheKey);
|
|
244
241
|
const headersKey = customHeadersDisambiguator(customHeaders);
|
|
245
242
|
if (headersKey) parts.push(`headers:${headersKey}`);
|
|
246
243
|
if (fetchFn) parts.push(`fetch:${getTransportFetchFnDisambiguator(fetchFn)}`);
|
|
247
|
-
if (signal) parts.push(`signal:${getTransportSignalDisambiguator(signal)}`);
|
|
248
|
-
if (requestTimeoutMs !== void 0) parts.push(`timeout:${requestTimeoutMs}`);
|
|
249
244
|
if (allowPrivateIp !== void 0) parts.push(`allow-private-ip:${allowPrivateIp}`);
|
|
250
245
|
const scopeKey = (0, import_mcp_scope.currentMCPConnectionScopeKey)();
|
|
251
246
|
if (scopeKey) parts.push(scopeKey);
|
|
@@ -260,39 +255,52 @@ function getCachedOAuthConnection(key) {
|
|
|
260
255
|
return client;
|
|
261
256
|
}
|
|
262
257
|
async function getOrCreateOAuthConnection(cacheKey, options) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
});
|
|
272
|
-
throw new Error("OAuth MCP connection completed after connection teardown");
|
|
258
|
+
for (let attempt = 0; ; attempt++) {
|
|
259
|
+
const cached = getCachedOAuthConnection(cacheKey);
|
|
260
|
+
if (cached) return cached;
|
|
261
|
+
const pending = pendingOAuthConnections.get(cacheKey);
|
|
262
|
+
if (pending) {
|
|
263
|
+
const joined = await (0, import_mcp_call_context.joinPendingConnection)(pending, options, attempt);
|
|
264
|
+
if (joined === import_mcp_call_context.RETRY_CONNECT) continue;
|
|
265
|
+
return joined;
|
|
273
266
|
}
|
|
274
|
-
|
|
275
|
-
(
|
|
276
|
-
if (
|
|
277
|
-
|
|
278
|
-
|
|
267
|
+
const generation = oauthConnectionGeneration;
|
|
268
|
+
const promise = connectMCP(options).then(async ({ client }) => {
|
|
269
|
+
if (generation !== oauthConnectionGeneration) {
|
|
270
|
+
await closeMCPClient(client).catch(() => {
|
|
271
|
+
});
|
|
272
|
+
throw new Error("OAuth MCP connection completed after connection teardown");
|
|
273
|
+
}
|
|
274
|
+
oauthConnectionCache.set(cacheKey, client);
|
|
275
|
+
(0, import_mcp_scope.registerMCPConnectionScopeCleanup)("oauth", cacheKey, async () => {
|
|
276
|
+
if (oauthConnectionCache.get(cacheKey) !== client) return;
|
|
277
|
+
oauthConnectionCache.delete(cacheKey);
|
|
278
|
+
await closeMCPClient(client);
|
|
279
|
+
});
|
|
280
|
+
evictLeastRecentlyUsedOAuth();
|
|
281
|
+
return client;
|
|
282
|
+
}).finally(() => {
|
|
283
|
+
if (pendingOAuthConnections.get(cacheKey) === promise) pendingOAuthConnections.delete(cacheKey);
|
|
279
284
|
});
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
});
|
|
285
|
-
pendingOAuthConnections.set(cacheKey, promise);
|
|
286
|
-
(0, import_mcp_scope.registerMCPConnectionScopePending)(promise);
|
|
287
|
-
return promise;
|
|
285
|
+
pendingOAuthConnections.set(cacheKey, promise);
|
|
286
|
+
(0, import_mcp_scope.registerMCPConnectionScopePending)(promise);
|
|
287
|
+
return promise;
|
|
288
|
+
}
|
|
288
289
|
}
|
|
289
290
|
async function withCachedOAuthConnection(options, label, fn) {
|
|
290
|
-
|
|
291
|
+
options = { ...options, customHeaders: (0, import_mcp_call_context.withAmbientIdentityHeaders)(options.customHeaders) };
|
|
292
|
+
return (0, import_mcp_call_context.runWithMCPCallContext)(
|
|
293
|
+
callContextFor(options.customHeaders, options.requestTimeoutMs),
|
|
294
|
+
() => withCachedOAuthConnectionImpl(options, label, fn)
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
async function withCachedOAuthConnectionImpl(options, label, fn) {
|
|
298
|
+
const guardedConnection = options.fetchFn !== void 0;
|
|
291
299
|
if (guardedConnection && (0, import_mcp_scope.currentMCPConnectionScopeKey)() === void 0) {
|
|
292
300
|
const { client } = await connectMCP(options);
|
|
293
301
|
let succeeded = false;
|
|
294
302
|
try {
|
|
295
|
-
const result = await fn(client);
|
|
303
|
+
const result = await (0, import_mcp_call_context.runCallPhase)(options.signal, () => fn(client));
|
|
296
304
|
succeeded = true;
|
|
297
305
|
return result;
|
|
298
306
|
} finally {
|
|
@@ -306,13 +314,11 @@ async function withCachedOAuthConnection(options, label, fn) {
|
|
|
306
314
|
options.signingContext?.cacheKey,
|
|
307
315
|
options.customHeaders,
|
|
308
316
|
options.fetchFn,
|
|
309
|
-
options.signal,
|
|
310
|
-
options.requestTimeoutMs,
|
|
311
317
|
options.allowPrivateIp
|
|
312
318
|
);
|
|
313
319
|
const mcpClient = await getOrCreateOAuthConnection(cacheKey, options);
|
|
314
320
|
try {
|
|
315
|
-
return await fn(mcpClient);
|
|
321
|
+
return await (0, import_mcp_call_context.trackConnectionUse)(mcpClient, () => (0, import_mcp_call_context.runCallPhase)(options.signal, () => fn(mcpClient)));
|
|
316
322
|
} catch (error) {
|
|
317
323
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
318
324
|
options.debugLogs.push({
|
|
@@ -321,52 +327,38 @@ async function withCachedOAuthConnection(options, label, fn) {
|
|
|
321
327
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
322
328
|
error
|
|
323
329
|
});
|
|
330
|
+
if ((0, import_abort.isAbortOrTimeoutError)(error)) throw error;
|
|
324
331
|
if ((0, import_errors.is401Error)(error)) {
|
|
325
|
-
oauthConnectionCache.delete(cacheKey);
|
|
326
|
-
try {
|
|
327
|
-
await closeMCPClient(mcpClient, false);
|
|
328
|
-
} catch {
|
|
329
|
-
}
|
|
330
332
|
options.debugLogs.push({
|
|
331
333
|
type: "warning",
|
|
332
334
|
message: `MCP: OAuth authentication issue detected for ${label}; evicted cached connection`,
|
|
333
335
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
334
336
|
});
|
|
335
|
-
throw error;
|
|
336
|
-
}
|
|
337
|
-
if ((0, import_abort.isAbortOrTimeoutError)(error)) {
|
|
338
|
-
oauthConnectionCache.delete(cacheKey);
|
|
339
|
-
try {
|
|
340
|
-
await closeMCPClient(mcpClient, false);
|
|
341
|
-
} catch {
|
|
342
|
-
}
|
|
343
|
-
throw error;
|
|
344
|
-
}
|
|
345
|
-
if (httpStatusOf(error) === 404) {
|
|
346
|
-
oauthConnectionCache.delete(cacheKey);
|
|
347
|
-
try {
|
|
348
|
-
await closeMCPClient(mcpClient, false);
|
|
349
|
-
} catch {
|
|
350
|
-
}
|
|
351
|
-
throw error;
|
|
352
|
-
}
|
|
353
|
-
oauthConnectionCache.delete(cacheKey);
|
|
354
|
-
try {
|
|
355
|
-
await closeMCPClient(mcpClient, false);
|
|
356
|
-
} catch {
|
|
357
337
|
}
|
|
338
|
+
await retireLegacyConnection(oauthConnectionCache, cacheKey, mcpClient);
|
|
358
339
|
throw error;
|
|
359
340
|
}
|
|
360
341
|
}
|
|
361
342
|
async function withCachedConnection(agentUrl, authToken, authHeaders, debugLogs, label, fn, transportFetch, requestOptions = {}) {
|
|
343
|
+
authHeaders = (0, import_mcp_call_context.withAmbientIdentityHeaders)(authHeaders);
|
|
344
|
+
return (0, import_mcp_call_context.runWithMCPCallContext)(
|
|
345
|
+
callContextFor(authHeaders, requestOptions.requestTimeoutMs),
|
|
346
|
+
() => withCachedConnectionImpl(agentUrl, authToken, authHeaders, debugLogs, label, fn, transportFetch, requestOptions)
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
async function withCachedConnectionImpl(agentUrl, authToken, authHeaders, debugLogs, label, fn, transportFetch, requestOptions) {
|
|
362
350
|
const signingContext = import_client2.signingContextStorage.getStore();
|
|
363
351
|
const baseUrl = new URL(agentUrl);
|
|
364
|
-
const guardedConnection = transportFetch !== void 0
|
|
352
|
+
const guardedConnection = transportFetch !== void 0;
|
|
365
353
|
if (guardedConnection && (0, import_mcp_scope.currentMCPConnectionScopeKey)() === void 0) {
|
|
366
354
|
const client = await connectMCPWithFallback(baseUrl, authHeaders, debugLogs, label, transportFetch, requestOptions);
|
|
367
355
|
let succeeded = false;
|
|
368
356
|
try {
|
|
369
|
-
const result = await (0, import_abort.withAbortSignal)(
|
|
357
|
+
const result = await (0, import_abort.withAbortSignal)(
|
|
358
|
+
[requestOptions.signal],
|
|
359
|
+
void 0,
|
|
360
|
+
() => (0, import_mcp_call_context.runCallPhase)(requestOptions.signal, () => fn(client))
|
|
361
|
+
);
|
|
370
362
|
succeeded = true;
|
|
371
363
|
return result;
|
|
372
364
|
} finally {
|
|
@@ -380,8 +372,6 @@ async function withCachedConnection(agentUrl, authToken, authHeaders, debugLogs,
|
|
|
380
372
|
signingContext?.cacheKey,
|
|
381
373
|
authHeaders,
|
|
382
374
|
transportFetch,
|
|
383
|
-
requestOptions.signal,
|
|
384
|
-
requestOptions.requestTimeoutMs,
|
|
385
375
|
requestOptions.allowPrivateIp
|
|
386
376
|
);
|
|
387
377
|
const mcpClient = await getOrCreateConnection(
|
|
@@ -394,7 +384,7 @@ async function withCachedConnection(agentUrl, authToken, authHeaders, debugLogs,
|
|
|
394
384
|
requestOptions
|
|
395
385
|
);
|
|
396
386
|
try {
|
|
397
|
-
return await fn(mcpClient);
|
|
387
|
+
return await (0, import_mcp_call_context.trackConnectionUse)(mcpClient, () => (0, import_mcp_call_context.runCallPhase)(requestOptions.signal, () => fn(mcpClient)));
|
|
398
388
|
} catch (error) {
|
|
399
389
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
400
390
|
debugLogs.push({
|
|
@@ -403,48 +393,63 @@ async function withCachedConnection(agentUrl, authToken, authHeaders, debugLogs,
|
|
|
403
393
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
404
394
|
error
|
|
405
395
|
});
|
|
396
|
+
if ((0, import_abort.isAbortOrTimeoutError)(error)) throw error;
|
|
406
397
|
if ((0, import_errors.is401Error)(error)) {
|
|
407
|
-
connectionCache.delete(cacheKey);
|
|
408
|
-
try {
|
|
409
|
-
await closeMCPClient(mcpClient, false);
|
|
410
|
-
} catch {
|
|
411
|
-
}
|
|
412
398
|
debugLogs.push({
|
|
413
399
|
type: "warning",
|
|
414
400
|
message: `MCP: Authentication issue detected for ${label} - headers may not be reaching server`,
|
|
415
401
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
416
402
|
});
|
|
417
|
-
|
|
418
|
-
}
|
|
419
|
-
if ((0, import_abort.isAbortOrTimeoutError)(error)) {
|
|
420
|
-
connectionCache.delete(cacheKey);
|
|
421
|
-
try {
|
|
422
|
-
await closeMCPClient(mcpClient, false);
|
|
423
|
-
} catch {
|
|
424
|
-
}
|
|
425
|
-
throw error;
|
|
426
|
-
}
|
|
427
|
-
if (httpStatusOf(error) === 404) {
|
|
428
|
-
connectionCache.delete(cacheKey);
|
|
429
|
-
try {
|
|
430
|
-
await closeMCPClient(mcpClient, false);
|
|
431
|
-
} catch {
|
|
432
|
-
}
|
|
403
|
+
} else if (httpStatusOf(error) === 404) {
|
|
433
404
|
debugLogs.push({
|
|
434
405
|
type: "warning",
|
|
435
406
|
message: `MCP: Session not found for ${label}; evicted cached connection without retry`,
|
|
436
407
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
437
408
|
});
|
|
438
|
-
throw error;
|
|
439
|
-
}
|
|
440
|
-
connectionCache.delete(cacheKey);
|
|
441
|
-
try {
|
|
442
|
-
await closeMCPClient(mcpClient, false);
|
|
443
|
-
} catch {
|
|
444
409
|
}
|
|
410
|
+
await retireLegacyConnection(connectionCache, cacheKey, mcpClient);
|
|
445
411
|
throw error;
|
|
446
412
|
}
|
|
447
413
|
}
|
|
414
|
+
async function withScopedLegacyConnection(options, label, fn) {
|
|
415
|
+
if ((0, import_mcp_scope.currentMCPConnectionScopeKey)() === void 0) return void 0;
|
|
416
|
+
const debugLogs = options.debugLogs ?? [];
|
|
417
|
+
if (options.authProvider) {
|
|
418
|
+
return {
|
|
419
|
+
value: await withCachedOAuthConnection({ ...options, authProvider: options.authProvider, debugLogs }, label, fn)
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
const authHeaders = (0, import_auth2.createMCPRequestHeaders)(options.customHeaders, options.authToken);
|
|
423
|
+
return {
|
|
424
|
+
value: await withCachedConnection(
|
|
425
|
+
options.agentUrl,
|
|
426
|
+
options.authToken,
|
|
427
|
+
authHeaders,
|
|
428
|
+
debugLogs,
|
|
429
|
+
label,
|
|
430
|
+
fn,
|
|
431
|
+
options.fetchFn,
|
|
432
|
+
{
|
|
433
|
+
signal: options.signal,
|
|
434
|
+
requestTimeoutMs: options.requestTimeoutMs,
|
|
435
|
+
allowPrivateIp: options.allowPrivateIp
|
|
436
|
+
}
|
|
437
|
+
)
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function callContextFor(headers, requestTimeoutMs) {
|
|
441
|
+
const { perRequest } = (0, import_mcp_call_context.splitConnectionHeaders)(headers);
|
|
442
|
+
const timeoutMs = (0, import_abort.resolveRequestTimeoutMs)(requestTimeoutMs);
|
|
443
|
+
return {
|
|
444
|
+
...Object.keys(perRequest).length > 0 && { headers: perRequest },
|
|
445
|
+
...timeoutMs !== void 0 && { requestTimeoutMs: timeoutMs }
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
async function retireLegacyConnection(cache, cacheKey, client) {
|
|
449
|
+
if (cache.get(cacheKey) === client) cache.delete(cacheKey);
|
|
450
|
+
await (0, import_mcp_call_context.closeWhenIdle)(client, () => closeMCPClient(client, false)).catch(() => {
|
|
451
|
+
});
|
|
452
|
+
}
|
|
448
453
|
function httpStatusOf(error, depth = 0) {
|
|
449
454
|
if (!error || typeof error !== "object" || depth > 4) return void 0;
|
|
450
455
|
const candidate = error;
|
|
@@ -454,6 +459,7 @@ function httpStatusOf(error, depth = 0) {
|
|
|
454
459
|
return httpStatusOf(candidate.cause, depth + 1);
|
|
455
460
|
}
|
|
456
461
|
async function connectMCPWithFallback(url, authHeaders, debugLogs = [], label = "connection", transportFetch, requestOptions = {}) {
|
|
462
|
+
authHeaders = (0, import_mcp_call_context.withAmbientIdentityHeaders)(authHeaders);
|
|
457
463
|
return (0, import_tracing.withSpan)(
|
|
458
464
|
"adcp.mcp.connect",
|
|
459
465
|
{
|
|
@@ -476,11 +482,15 @@ async function connectMCPWithFallbackImpl(url, authHeaders, debugLogs = [], labe
|
|
|
476
482
|
trustedFetchFn: transportFetch,
|
|
477
483
|
allowPrivateIp: requestOptions.allowPrivateIp
|
|
478
484
|
});
|
|
479
|
-
const networkFetch = (input, init) =>
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
485
|
+
const networkFetch = (input, init) => (
|
|
486
|
+
// Cancellation stays linked for the entire response-body lifetime, through
|
|
487
|
+
// `init.signal`: the v1 transport does not forward a request's own signal, so
|
|
488
|
+
// the active call's signal is linked to that call's POST at the outermost
|
|
489
|
+
// transport wrapper (aborting one call cancels its HTTP request without
|
|
490
|
+
// closing a session other calls share). The background GET/SSE listener
|
|
491
|
+
// never carries a call signal.
|
|
492
|
+
rawNetworkFetch(input, { ...init, signal: init?.signal ?? void 0 })
|
|
493
|
+
);
|
|
484
494
|
const sizeLimited = (0, import_responseSizeLimit.wrapFetchWithSizeLimit)(networkFetch);
|
|
485
495
|
const diagnosticFetch = (0, import_transportDiagnostics.wrapFetchWithTransportDiagnostics)(sizeLimited);
|
|
486
496
|
const baseFetch = signingContext ? (0, import_client2.buildAgentSigningFetch)({
|
|
@@ -490,8 +500,8 @@ async function connectMCPWithFallbackImpl(url, authHeaders, debugLogs = [], labe
|
|
|
490
500
|
adcpVersion: signingContext.adcpVersion
|
|
491
501
|
}) : diagnosticFetch;
|
|
492
502
|
const transportOptions = {
|
|
493
|
-
requestInit: { headers: authHeaders, redirect: "manual" },
|
|
494
|
-
fetch: (0, import_rawResponseCapture.wrapFetchWithCapture)(withPerRequestTraceHeaders(baseFetch))
|
|
503
|
+
requestInit: { headers: (0, import_mcp_call_context.splitConnectionHeaders)(authHeaders).identity, redirect: "manual" },
|
|
504
|
+
fetch: (0, import_rawResponseCapture.wrapFetchWithCapture)(withPerRequestTraceHeaders(baseFetch, (0, import_mcp_call_context.splitConnectionHeaders)(authHeaders).perRequest))
|
|
495
505
|
};
|
|
496
506
|
let failedClient;
|
|
497
507
|
try {
|
|
@@ -585,8 +595,10 @@ async function connectMCPWithFallbackImpl(url, authHeaders, debugLogs = [], labe
|
|
|
585
595
|
try {
|
|
586
596
|
await client.connect(
|
|
587
597
|
new import_sse.SSEClientTransport(url, {
|
|
588
|
-
requestInit: { headers: authHeaders, redirect: "manual" },
|
|
589
|
-
fetch: (0, import_rawResponseCapture.wrapFetchWithCapture)(
|
|
598
|
+
requestInit: { headers: (0, import_mcp_call_context.splitConnectionHeaders)(authHeaders).identity, redirect: "manual" },
|
|
599
|
+
fetch: (0, import_rawResponseCapture.wrapFetchWithCapture)(
|
|
600
|
+
withPerRequestTraceHeaders(baseFetch, (0, import_mcp_call_context.splitConnectionHeaders)(authHeaders).perRequest)
|
|
601
|
+
)
|
|
590
602
|
}),
|
|
591
603
|
mcpRequestOptions
|
|
592
604
|
);
|
|
@@ -733,11 +745,11 @@ async function connectMCP(options) {
|
|
|
733
745
|
return normalized !== "authorization" && normalized !== "x-adcp-auth";
|
|
734
746
|
})
|
|
735
747
|
) : customHeaders;
|
|
736
|
-
const authHeaders = (0, import_auth2.createMCPRequestHeaders)(filteredCustomHeaders, authToken);
|
|
748
|
+
const authHeaders = (0, import_mcp_call_context.withAmbientIdentityHeaders)((0, import_auth2.createMCPRequestHeaders)(filteredCustomHeaders, authToken));
|
|
737
749
|
const hasNonAcceptCustomHeaders = Object.keys(filteredCustomHeaders ?? {}).some(
|
|
738
750
|
(key) => key.toLowerCase() !== "accept"
|
|
739
751
|
);
|
|
740
|
-
transportOptions.requestInit = { headers: authHeaders, redirect: "manual" };
|
|
752
|
+
transportOptions.requestInit = { headers: (0, import_mcp_call_context.splitConnectionHeaders)(authHeaders).identity, redirect: "manual" };
|
|
741
753
|
if (authProvider) {
|
|
742
754
|
transportOptions.authProvider = authProvider;
|
|
743
755
|
debugLogs.push({
|
|
@@ -758,18 +770,27 @@ async function connectMCP(options) {
|
|
|
758
770
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
759
771
|
});
|
|
760
772
|
}
|
|
761
|
-
const requestTimeoutMs = (0, import_abort.resolveRequestTimeoutMs)(configuredRequestTimeoutMs);
|
|
762
773
|
const clientRequestTimeoutMs = (0, import_abort.resolveClientRequestTimeoutMs)(configuredRequestTimeoutMs);
|
|
774
|
+
const directRequestTimeoutMs = (0, import_abort.resolveRequestTimeoutMs)(configuredRequestTimeoutMs);
|
|
763
775
|
const requestOptions = {
|
|
764
776
|
...signal && { signal },
|
|
765
777
|
...clientRequestTimeoutMs !== void 0 && { timeout: clientRequestTimeoutMs }
|
|
766
778
|
};
|
|
767
779
|
const rawNetworkFetch = (0, import_agent_transport_fetch.createAgentTransportFetch)(agentUrl, { trustedFetchFn: fetchFn, allowPrivateIp });
|
|
768
780
|
const sizeLimited = (0, import_responseSizeLimit.wrapFetchWithSizeLimit)(
|
|
769
|
-
(input, init) => (
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
781
|
+
(input, init) => (
|
|
782
|
+
// Inside a call context the deadline is that call's; a direct caller who
|
|
783
|
+
// holds the returned client keeps the timeout configured on connect. The
|
|
784
|
+
// call's own signal is already linked into `init.signal` for the whole
|
|
785
|
+
// response body, so aborting one call cancels its streamed POST only.
|
|
786
|
+
(0, import_abort.withAbortSignal)(
|
|
787
|
+
[init?.signal],
|
|
788
|
+
(0, import_mcp_call_context.requestTimeoutFor)(init, directRequestTimeoutMs),
|
|
789
|
+
(deadline) => rawNetworkFetch(input, {
|
|
790
|
+
...init,
|
|
791
|
+
signal: init?.signal && deadline ? AbortSignal.any([init.signal, deadline]) : deadline ?? init?.signal
|
|
792
|
+
})
|
|
793
|
+
)
|
|
773
794
|
)
|
|
774
795
|
);
|
|
775
796
|
const diagnosticFetch = (0, import_transportDiagnostics.wrapFetchWithTransportDiagnostics)(sizeLimited);
|
|
@@ -779,7 +800,9 @@ async function connectMCP(options) {
|
|
|
779
800
|
getCapability: signingContext.getCapability,
|
|
780
801
|
adcpVersion: signingContext.adcpVersion
|
|
781
802
|
}) : diagnosticFetch;
|
|
782
|
-
transportOptions.fetch = (0, import_rawResponseCapture.wrapFetchWithCapture)(
|
|
803
|
+
transportOptions.fetch = (0, import_rawResponseCapture.wrapFetchWithCapture)(
|
|
804
|
+
withPerRequestTraceHeaders(signedFetch, (0, import_mcp_call_context.splitConnectionHeaders)(authHeaders).perRequest)
|
|
805
|
+
);
|
|
783
806
|
const transport = new import_streamableHttp.StreamableHTTPClientTransport(baseUrl, transportOptions);
|
|
784
807
|
try {
|
|
785
808
|
await mcpClient.connect(transport, requestOptions);
|
|
@@ -903,5 +926,6 @@ async function callMCPToolWithOAuth(options) {
|
|
|
903
926
|
closeOAuthConnections,
|
|
904
927
|
connectMCP,
|
|
905
928
|
connectMCPWithFallback,
|
|
906
|
-
withCachedConnection
|
|
929
|
+
withCachedConnection,
|
|
930
|
+
withScopedLegacyConnection
|
|
907
931
|
});
|