deadbyte-mcp 0.15.49 → 0.15.50
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/MANIFEST.SHA256 +82 -78
- package/PROVENANCE.json +3 -3
- package/README.txt +18 -18
- package/RELEASE.json +5 -5
- package/SBOM.cdx.json +2 -2
- package/TEST-MATRIX.json +2 -2
- package/docs/R130-SDK-SECURITY-PATCH.md +34 -0
- package/node_modules/@modelcontextprotocol/client/README.md +1 -7
- package/node_modules/@modelcontextprotocol/client/dist/{index-BCtJi0p5.d.mts → index-B-4n9P0J.d.mts} +5 -1
- package/node_modules/@modelcontextprotocol/client/dist/index-B-4n9P0J.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/{index-CEk3qkZM.d.cts → index-J2FaQ-KY.d.cts} +5 -1
- package/node_modules/@modelcontextprotocol/client/dist/index-J2FaQ-KY.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/index.cjs +175 -76
- package/node_modules/@modelcontextprotocol/client/dist/index.cjs.map +1 -1
- package/node_modules/@modelcontextprotocol/client/dist/index.d.cts +214 -35
- package/node_modules/@modelcontextprotocol/client/dist/index.d.cts.map +1 -1
- package/node_modules/@modelcontextprotocol/client/dist/index.d.mts +214 -35
- package/node_modules/@modelcontextprotocol/client/dist/index.d.mts.map +1 -1
- package/node_modules/@modelcontextprotocol/client/dist/index.mjs +175 -76
- package/node_modules/@modelcontextprotocol/client/dist/index.mjs.map +1 -1
- package/node_modules/@modelcontextprotocol/client/dist/shimsWorkerd.cjs +1 -1
- package/node_modules/@modelcontextprotocol/client/dist/shimsWorkerd.mjs +1 -1
- package/node_modules/@modelcontextprotocol/client/dist/{src-D0qEN74R.cjs → src-DpAS0jfg.cjs} +125 -11
- package/node_modules/@modelcontextprotocol/client/dist/src-DpAS0jfg.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/{src-DDAAhLnO.mjs → src-WCy6ifGf.mjs} +102 -12
- package/node_modules/@modelcontextprotocol/client/dist/src-WCy6ifGf.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/stdio.cjs +1 -1
- package/node_modules/@modelcontextprotocol/client/dist/stdio.d.cts +1 -1
- package/node_modules/@modelcontextprotocol/client/dist/stdio.d.mts +1 -1
- package/node_modules/@modelcontextprotocol/client/dist/stdio.mjs +1 -1
- package/node_modules/@modelcontextprotocol/client/package.json +5 -5
- package/node_modules/@modelcontextprotocol/core/dist/{auth--n_Yzytt.d.cts → auth-Anm-lwWi.d.mts} +9 -8
- package/node_modules/@modelcontextprotocol/core/dist/{auth--n_Yzytt.d.cts.map → auth-Anm-lwWi.d.mts.map} +1 -1
- package/node_modules/@modelcontextprotocol/core/dist/{auth-CGP0BDVq.mjs → auth-BNDyLTqp.mjs} +5 -3
- package/node_modules/@modelcontextprotocol/core/dist/{auth-CGP0BDVq.mjs.map → auth-BNDyLTqp.mjs.map} +1 -1
- package/node_modules/@modelcontextprotocol/core/dist/{auth-4-zilcqg.cjs → auth-D1CeV_Jr.cjs} +5 -3
- package/node_modules/@modelcontextprotocol/core/dist/{auth-4-zilcqg.cjs.map → auth-D1CeV_Jr.cjs.map} +1 -1
- package/node_modules/@modelcontextprotocol/core/dist/{auth-YUQV3RRv.d.mts → auth-V9XJSCfa.d.cts} +9 -8
- package/node_modules/@modelcontextprotocol/core/dist/{auth-YUQV3RRv.d.mts.map → auth-V9XJSCfa.d.cts.map} +1 -1
- package/node_modules/@modelcontextprotocol/core/dist/index.cjs +1 -1
- package/node_modules/@modelcontextprotocol/core/dist/index.d.cts +1 -1
- package/node_modules/@modelcontextprotocol/core/dist/index.d.mts +1 -1
- package/node_modules/@modelcontextprotocol/core/dist/index.mjs +1 -1
- package/node_modules/@modelcontextprotocol/core/dist/internal.cjs +1 -1
- package/node_modules/@modelcontextprotocol/core/dist/internal.d.cts +1 -1
- package/node_modules/@modelcontextprotocol/core/dist/internal.d.mts +1 -1
- package/node_modules/@modelcontextprotocol/core/dist/internal.mjs +1 -1
- package/node_modules/@modelcontextprotocol/core/package.json +2 -2
- package/node_modules/@modelcontextprotocol/server/README.md +1 -7
- package/node_modules/@modelcontextprotocol/server/dist/{createMcpHandler-Bt6U_Fqb.d.mts → createMcpHandler-D4NN8WsG.d.mts} +35 -13
- package/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-D4NN8WsG.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/{createMcpHandler-BLVe3qmU.d.cts → createMcpHandler-DZmmlN8e.d.cts} +35 -13
- package/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-DZmmlN8e.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/index.cjs +32 -5
- package/node_modules/@modelcontextprotocol/server/dist/index.cjs.map +1 -1
- package/node_modules/@modelcontextprotocol/server/dist/index.d.cts +41 -5
- package/node_modules/@modelcontextprotocol/server/dist/index.d.cts.map +1 -1
- package/node_modules/@modelcontextprotocol/server/dist/index.d.mts +41 -5
- package/node_modules/@modelcontextprotocol/server/dist/index.d.mts.map +1 -1
- package/node_modules/@modelcontextprotocol/server/dist/index.mjs +32 -5
- package/node_modules/@modelcontextprotocol/server/dist/index.mjs.map +1 -1
- package/node_modules/@modelcontextprotocol/server/dist/{mcp-DUcCQSTW.cjs → mcp-BumlNux0.cjs} +73 -23
- package/node_modules/@modelcontextprotocol/server/dist/mcp-BumlNux0.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/{mcp-Dw2OlZ1f.mjs → mcp-DIH4cS6P.mjs} +73 -23
- package/node_modules/@modelcontextprotocol/server/dist/mcp-DIH4cS6P.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.cjs +1 -1
- package/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.mjs +1 -1
- package/node_modules/@modelcontextprotocol/server/dist/{src-CgFsfg3E.cjs → src-BhnGYybN.cjs} +29 -11
- package/node_modules/@modelcontextprotocol/server/dist/src-BhnGYybN.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/{src-D-y6h4N7.mjs → src-Cqbh3MYc.mjs} +29 -11
- package/node_modules/@modelcontextprotocol/server/dist/src-Cqbh3MYc.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/stdio.cjs +2 -2
- package/node_modules/@modelcontextprotocol/server/dist/stdio.d.cts +1 -1
- package/node_modules/@modelcontextprotocol/server/dist/stdio.d.mts +1 -1
- package/node_modules/@modelcontextprotocol/server/dist/stdio.mjs +2 -2
- package/node_modules/@modelcontextprotocol/server/package.json +4 -4
- package/node_modules/which/CHANGELOG.md +166 -0
- package/package.json +3 -3
- package/src/version.mjs +1 -1
- package/test/r129-sdk-security-baseline.test.mjs +38 -0
- package/test/r130-release-security-contract.test.mjs +28 -0
- package/test/r59-tool-surface-compat.test.mjs +1 -1
- package/test/r74-prepublish-contract.test.mjs +2 -2
- package/node_modules/@modelcontextprotocol/client/dist/index-BCtJi0p5.d.mts.map +0 -1
- package/node_modules/@modelcontextprotocol/client/dist/index-CEk3qkZM.d.cts.map +0 -1
- package/node_modules/@modelcontextprotocol/client/dist/src-D0qEN74R.cjs.map +0 -1
- package/node_modules/@modelcontextprotocol/client/dist/src-DDAAhLnO.mjs.map +0 -1
- package/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-BLVe3qmU.d.cts.map +0 -1
- package/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-Bt6U_Fqb.d.mts.map +0 -1
- package/node_modules/@modelcontextprotocol/server/dist/mcp-DUcCQSTW.cjs.map +0 -1
- package/node_modules/@modelcontextprotocol/server/dist/mcp-Dw2OlZ1f.mjs.map +0 -1
- package/node_modules/@modelcontextprotocol/server/dist/src-CgFsfg3E.cjs.map +0 -1
- package/node_modules/@modelcontextprotocol/server/dist/src-D-y6h4N7.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require('./chunk-Bnu9O96Y.cjs');
|
|
2
|
-
const require_src = require('./src-
|
|
2
|
+
const require_src = require('./src-DpAS0jfg.cjs');
|
|
3
3
|
let _modelcontextprotocol_client__shims = require("@modelcontextprotocol/client/_shims");
|
|
4
4
|
let pkce_challenge = require("pkce-challenge");
|
|
5
5
|
pkce_challenge = require_chunk.__toESM(pkce_challenge);
|
|
@@ -115,10 +115,12 @@ var RegistrationRejectedError = class extends OAuthClientFlowError {
|
|
|
115
115
|
};
|
|
116
116
|
/**
|
|
117
117
|
* Thrown by the token-exchange and refresh paths when the resolved token
|
|
118
|
-
* endpoint is not `https:` and is not a loopback host
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
118
|
+
* endpoint is not `https:` and is not a loopback host. The MCP authorization
|
|
119
|
+
* specification requires authorization server endpoints to use HTTPS; loopback
|
|
120
|
+
* hosts are exempt here for local development. This is a configuration error —
|
|
121
|
+
* re-authorizing cannot fix it — so it intentionally does **not** extend
|
|
122
|
+
* `OAuthError` and `auth()`'s refresh branch rethrows it instead of falling
|
|
123
|
+
* through to a fresh `/authorize` redirect.
|
|
122
124
|
*/
|
|
123
125
|
var InsecureTokenEndpointError = class extends OAuthClientFlowError {
|
|
124
126
|
static {
|
|
@@ -127,7 +129,7 @@ var InsecureTokenEndpointError = class extends OAuthClientFlowError {
|
|
|
127
129
|
/** The token endpoint URL that was rejected. */
|
|
128
130
|
tokenEndpoint;
|
|
129
131
|
constructor(tokenEndpoint) {
|
|
130
|
-
super(`Refusing to send credentials to non-https token endpoint '${tokenEndpoint}'. OAuth token requests MUST use TLS (localhost / 127.0.0.1 / ::1 are exempt).`);
|
|
132
|
+
super(`Refusing to send credentials to non-https token endpoint '${tokenEndpoint}'. OAuth token requests MUST use TLS (localhost / *.localhost / 127.0.0.1 / ::1 are exempt).`);
|
|
131
133
|
this.tokenEndpoint = tokenEndpoint;
|
|
132
134
|
}
|
|
133
135
|
};
|
|
@@ -152,21 +154,25 @@ var InsecureTokenEndpointError = class extends OAuthClientFlowError {
|
|
|
152
154
|
* `requiredScope`, which appears in the error message).
|
|
153
155
|
*/
|
|
154
156
|
/**
|
|
155
|
-
* Thrown by `auth()`
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
157
|
+
* Thrown by `auth()` and `fetchToken()` when the authorization server in use differs
|
|
158
|
+
* from the one a credential is bound to and the flow cannot simply start over:
|
|
159
|
+
*
|
|
160
|
+
* - on the authorization-code callback leg, when it differs from the one recorded
|
|
161
|
+
* in `discoveryState()` at redirect time — the `authorization_code` and PKCE
|
|
162
|
+
* `code_verifier` are bound to the AS that minted the code (RFC 7636);
|
|
163
|
+
* - for client information whose `issuer` stamp names a different authorization
|
|
164
|
+
* server on a provider that cannot re-register (no `saveClientInformation()`,
|
|
165
|
+
* e.g. the bundled static-credential providers); `fetchToken()` throws for any provider.
|
|
166
|
+
*
|
|
167
|
+
* Stored tokens and re-registrable client information are protected structurally
|
|
168
|
+
* by the `issuer` stamp instead (they read back as absent).
|
|
163
169
|
*/
|
|
164
170
|
var AuthorizationServerMismatchError = class extends OAuthClientFlowError {
|
|
165
171
|
static {
|
|
166
172
|
Object.defineProperty(this, "mcpBrand", { value: "mcp.AuthorizationServerMismatchError" });
|
|
167
173
|
}
|
|
168
174
|
constructor(recordedIssuer, currentIssuer) {
|
|
169
|
-
super(`Authorization server
|
|
175
|
+
super(`Authorization server mismatch: credentials are bound to ${JSON.stringify(recordedIssuer)} but this call resolved ${JSON.stringify(currentIssuer)}; refusing to present them to a different authorization server`);
|
|
170
176
|
this.recordedIssuer = recordedIssuer;
|
|
171
177
|
this.currentIssuer = currentIssuer;
|
|
172
178
|
}
|
|
@@ -210,10 +216,13 @@ var InsufficientScopeError = class extends OAuthClientFlowError {
|
|
|
210
216
|
* "binding on first use" claim would be false and would fire on every call.
|
|
211
217
|
*/
|
|
212
218
|
function discardIfIssuerMismatch(stored, issuer, opts) {
|
|
213
|
-
if (stored
|
|
214
|
-
if (stored.issuer
|
|
219
|
+
if (!stored) return void 0;
|
|
220
|
+
if (typeof stored.issuer !== "string") {
|
|
215
221
|
if (opts?.canPersistStamp !== false) console.warn("[mcp-sdk] SEP-2352: stored OAuth credential has no 'issuer' stamp (pre-upgrade storage or provider not round-tripping the value). SEP-2352 isolation is inactive for this read; ensure your provider round-trips the issuer field.");
|
|
216
|
-
return stored
|
|
222
|
+
return stored.issuer === void 0 ? stored : {
|
|
223
|
+
...stored,
|
|
224
|
+
issuer: void 0
|
|
225
|
+
};
|
|
217
226
|
}
|
|
218
227
|
return issuersMatch(stored.issuer, issuer) ? stored : void 0;
|
|
219
228
|
}
|
|
@@ -521,13 +530,19 @@ function applyPostAuth(clientId, clientSecret, params) {
|
|
|
521
530
|
function applyPublicAuth(clientId, params) {
|
|
522
531
|
params.set("client_id", clientId);
|
|
523
532
|
}
|
|
524
|
-
/**
|
|
533
|
+
/**
|
|
534
|
+
* Loopback hosts exempt from the in-transit `https:` requirement (RFC 8252 §7.3).
|
|
535
|
+
* Includes bare `localhost` and any name ending in `.localhost` (RFC 6761 §6.3).
|
|
536
|
+
*/
|
|
525
537
|
function isLoopbackHost(hostname) {
|
|
526
|
-
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]" || hostname === "::1";
|
|
538
|
+
return hostname === "localhost" || hostname.endsWith(".localhost") || hostname === "127.0.0.1" || hostname === "[::1]" || hostname === "::1";
|
|
527
539
|
}
|
|
528
540
|
/**
|
|
529
|
-
*
|
|
530
|
-
*
|
|
541
|
+
* Refuse to send credentials to a non-TLS token endpoint. The MCP authorization
|
|
542
|
+
* specification requires authorization server endpoints to use HTTPS. Loopback
|
|
543
|
+
* hosts are exempt here for local development.
|
|
544
|
+
*
|
|
545
|
+
* @throws {@linkcode InsecureTokenEndpointError} if the endpoint is insecure.
|
|
531
546
|
*/
|
|
532
547
|
function assertSecureTokenEndpoint(tokenEndpoint) {
|
|
533
548
|
const url = new URL(String(tokenEndpoint));
|
|
@@ -977,12 +992,13 @@ async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn =
|
|
|
977
992
|
* error object alone, so the swallow-and-fallthrough heuristic is preserved there.
|
|
978
993
|
*/
|
|
979
994
|
async function fetchWithCorsRetry(url, headers, fetchFn = fetch) {
|
|
995
|
+
const withinOrigin = require_src.fetchWithinOrigin(fetchFn);
|
|
980
996
|
try {
|
|
981
|
-
return await
|
|
997
|
+
return await withinOrigin(url, { headers });
|
|
982
998
|
} catch (error) {
|
|
983
999
|
if (!(error instanceof TypeError) || !_modelcontextprotocol_client__shims.CORS_IS_POSSIBLE) throw error;
|
|
984
1000
|
if (headers) try {
|
|
985
|
-
return await
|
|
1001
|
+
return await withinOrigin(url, {});
|
|
986
1002
|
} catch (retryError) {
|
|
987
1003
|
if (!(retryError instanceof TypeError)) throw retryError;
|
|
988
1004
|
return;
|
|
@@ -1009,7 +1025,7 @@ async function tryMetadataDiscovery(url, protocolVersion, fetchFn = fetch) {
|
|
|
1009
1025
|
function shouldAttemptFallback(response, pathname) {
|
|
1010
1026
|
if (!response) return true;
|
|
1011
1027
|
if (pathname === "/") return false;
|
|
1012
|
-
return response.
|
|
1028
|
+
return !response.ok && response.status < 500 || response.status === 502;
|
|
1013
1029
|
}
|
|
1014
1030
|
/**
|
|
1015
1031
|
* Generic function for discovering OAuth metadata with fallback support
|
|
@@ -1132,7 +1148,7 @@ async function discoverAuthorizationServerMetadata(authorizationServerUrl, { fet
|
|
|
1132
1148
|
continue;
|
|
1133
1149
|
if (!response.ok) {
|
|
1134
1150
|
await response.text?.().catch(() => {});
|
|
1135
|
-
if (response.status
|
|
1151
|
+
if (response.status < 500 || response.status === 502) continue;
|
|
1136
1152
|
throw new Error(`HTTP ${response.status} trying to load ${type === "oauth" ? "OAuth" : "OpenID provider"} metadata from ${endpointUrl}`);
|
|
1137
1153
|
}
|
|
1138
1154
|
const parsed = type === "oauth" ? _modelcontextprotocol_core_internal.OAuthMetadataSchema.parse(await response.json()) : _modelcontextprotocol_core_internal.OpenIdProviderDiscoveryMetadataSchema.parse(await response.json());
|
|
@@ -1251,7 +1267,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
|
|
|
1251
1267
|
htm: "POST",
|
|
1252
1268
|
htu: tokenUrl
|
|
1253
1269
|
}));
|
|
1254
|
-
return (fetchFn ?? fetch)(tokenUrl, {
|
|
1270
|
+
return require_src.fetchWithinOrigin(fetchFn ?? fetch)(tokenUrl, {
|
|
1255
1271
|
method: "POST",
|
|
1256
1272
|
headers: requestHeaders,
|
|
1257
1273
|
body: tokenRequestParams
|
|
@@ -1268,7 +1284,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
|
|
|
1268
1284
|
if (!response.ok) throw await parseErrorResponse(response);
|
|
1269
1285
|
const json = await response.json();
|
|
1270
1286
|
try {
|
|
1271
|
-
return _modelcontextprotocol_core_internal.OAuthTokensSchema.parse(json);
|
|
1287
|
+
return _modelcontextprotocol_core_internal.OAuthTokensSchema.parse(require_src.withoutIssuer(json));
|
|
1272
1288
|
} catch (parseError) {
|
|
1273
1289
|
if (typeof json === "object" && json !== null && "error" in json) throw await parseErrorResponse(JSON.stringify(json));
|
|
1274
1290
|
throw parseError;
|
|
@@ -1364,6 +1380,14 @@ async function fetchToken(provider, authorizationServerUrl, { metadata, resource
|
|
|
1364
1380
|
expectedIssuer: metadata?.issuer,
|
|
1365
1381
|
issParameterSupported: isIssParameterSupported(metadata)
|
|
1366
1382
|
});
|
|
1383
|
+
const issuer = metadata?.issuer ?? String(authorizationServerUrl);
|
|
1384
|
+
const readClientInformation = async () => {
|
|
1385
|
+
const rawClientInfo = await provider.clientInformation({ issuer });
|
|
1386
|
+
const checked = discardIfIssuerMismatch(rawClientInfo, issuer, { canPersistStamp: false });
|
|
1387
|
+
if (rawClientInfo && checked === void 0) throw new AuthorizationServerMismatchError(String(rawClientInfo.issuer), issuer);
|
|
1388
|
+
return checked;
|
|
1389
|
+
};
|
|
1390
|
+
let clientInformation = await readClientInformation();
|
|
1367
1391
|
const effectiveScope = scope ?? provider.clientMetadata.scope;
|
|
1368
1392
|
let tokenRequestParams;
|
|
1369
1393
|
if (provider.prepareTokenRequest) tokenRequestParams = await provider.prepareTokenRequest(effectiveScope);
|
|
@@ -1372,11 +1396,11 @@ async function fetchToken(provider, authorizationServerUrl, { metadata, resource
|
|
|
1372
1396
|
if (!provider.redirectUrl) throw new Error("redirectUrl is required for authorization_code flow");
|
|
1373
1397
|
tokenRequestParams = prepareAuthorizationCodeRequest(authorizationCode, await provider.codeVerifier(), provider.redirectUrl);
|
|
1374
1398
|
}
|
|
1375
|
-
|
|
1399
|
+
clientInformation ??= await readClientInformation();
|
|
1376
1400
|
return executeTokenRequest(authorizationServerUrl, {
|
|
1377
1401
|
metadata,
|
|
1378
1402
|
tokenRequestParams,
|
|
1379
|
-
clientInformation
|
|
1403
|
+
clientInformation,
|
|
1380
1404
|
addClientAuthentication: provider.addClientAuthentication,
|
|
1381
1405
|
resource,
|
|
1382
1406
|
dpop: await provider.dpop?.(),
|
|
@@ -1392,10 +1416,17 @@ async function fetchToken(provider, authorizationServerUrl, { metadata, resource
|
|
|
1392
1416
|
* consistently across both DCR and the subsequent authorization request.
|
|
1393
1417
|
*
|
|
1394
1418
|
* @deprecated Dynamic Client Registration is deprecated as of protocol version
|
|
1395
|
-
* 2026-07-28
|
|
1396
|
-
*
|
|
1397
|
-
*
|
|
1398
|
-
*
|
|
1419
|
+
* 2026-07-28 in favor of Client ID Metadata Documents (SEP-991); the deprecation
|
|
1420
|
+
* landed via spec PR
|
|
1421
|
+
* {@link https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2858 | modelcontextprotocol#2858}
|
|
1422
|
+
* (SEP-2577 is the separate roots/sampling/logging deprecation). Remains
|
|
1423
|
+
* functional during the deprecation window — at least twelve months under the
|
|
1424
|
+
* feature lifecycle policy (SEP-2596), so 2027-07-28 is the earliest possible
|
|
1425
|
+
* removal date. Prefer a CIMD URL `client_id` when the authorization server
|
|
1426
|
+
* advertises `client_id_metadata_document_supported`: the built-in `auth()` flow
|
|
1427
|
+
* skips registration for you when that capability is advertised AND your
|
|
1428
|
+
* provider supplies `clientMetadataUrl`, but `registerClient` itself does not
|
|
1429
|
+
* gate — calling it directly always sends the registration request.
|
|
1399
1430
|
*/
|
|
1400
1431
|
async function registerClient(authorizationServerUrl, { metadata, clientMetadata, scope, fetchFn }) {
|
|
1401
1432
|
let registrationUrl;
|
|
@@ -1407,7 +1438,7 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
|
|
|
1407
1438
|
...clientMetadata,
|
|
1408
1439
|
...scope === void 0 ? {} : { scope }
|
|
1409
1440
|
};
|
|
1410
|
-
const response = await (fetchFn ?? fetch)(registrationUrl, {
|
|
1441
|
+
const response = await require_src.fetchWithinOrigin(fetchFn ?? fetch)(registrationUrl, {
|
|
1411
1442
|
method: "POST",
|
|
1412
1443
|
headers: { "Content-Type": "application/json" },
|
|
1413
1444
|
body: JSON.stringify(submittedMetadata)
|
|
@@ -1417,7 +1448,7 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
|
|
|
1417
1448
|
body: await response.text(),
|
|
1418
1449
|
submittedMetadata
|
|
1419
1450
|
});
|
|
1420
|
-
return _modelcontextprotocol_core_internal.OAuthClientInformationFullSchema.parse(await response.json());
|
|
1451
|
+
return _modelcontextprotocol_core_internal.OAuthClientInformationFullSchema.parse(require_src.withoutIssuer(await response.json()));
|
|
1421
1452
|
}
|
|
1422
1453
|
|
|
1423
1454
|
//#endregion
|
|
@@ -1472,6 +1503,15 @@ function createPrivateKeyJwtAuth(options) {
|
|
|
1472
1503
|
};
|
|
1473
1504
|
}
|
|
1474
1505
|
/**
|
|
1506
|
+
* The `issuer` stamp for constructor-supplied client information. Omitting `expectedIssuer` is
|
|
1507
|
+
* deprecated: nothing else says which authorization server such credentials belong to.
|
|
1508
|
+
*/
|
|
1509
|
+
function checkedExpectedIssuer(expectedIssuer) {
|
|
1510
|
+
if (expectedIssuer === void 0) console.warn("[mcp-sdk] Omitting `expectedIssuer` is deprecated. Without it, the MCP server decides which authorization server receives this client's credentials; pass your authorization server's issuer URL as `expectedIssuer` so they are only sent there.");
|
|
1511
|
+
else if (typeof expectedIssuer !== "string" || !expectedIssuer) throw new Error("expectedIssuer must be the authorization server's issuer URL");
|
|
1512
|
+
return expectedIssuer;
|
|
1513
|
+
}
|
|
1514
|
+
/**
|
|
1475
1515
|
* OAuth provider for `client_credentials` grant with `client_secret_basic` authentication.
|
|
1476
1516
|
*
|
|
1477
1517
|
* This provider is designed for machine-to-machine authentication where
|
|
@@ -1481,7 +1521,8 @@ function createPrivateKeyJwtAuth(options) {
|
|
|
1481
1521
|
* ```ts source="./authExtensions.examples.ts#ClientCredentialsProvider_basicUsage"
|
|
1482
1522
|
* const provider = new ClientCredentialsProvider({
|
|
1483
1523
|
* clientId: 'my-client',
|
|
1484
|
-
* clientSecret: 'my-secret'
|
|
1524
|
+
* clientSecret: 'my-secret',
|
|
1525
|
+
* expectedIssuer: 'https://auth.example.com'
|
|
1485
1526
|
* });
|
|
1486
1527
|
*
|
|
1487
1528
|
* const transport = new StreamableHTTPClientTransport(serverUrl, {
|
|
@@ -1497,7 +1538,7 @@ var ClientCredentialsProvider = class {
|
|
|
1497
1538
|
this._clientInfo = {
|
|
1498
1539
|
client_id: options.clientId,
|
|
1499
1540
|
client_secret: options.clientSecret,
|
|
1500
|
-
issuer: options.expectedIssuer
|
|
1541
|
+
issuer: checkedExpectedIssuer(options.expectedIssuer)
|
|
1501
1542
|
};
|
|
1502
1543
|
this._clientMetadata = {
|
|
1503
1544
|
client_name: options.clientName ?? "client-credentials-client",
|
|
@@ -1545,7 +1586,8 @@ var ClientCredentialsProvider = class {
|
|
|
1545
1586
|
* const provider = new PrivateKeyJwtProvider({
|
|
1546
1587
|
* clientId: 'my-client',
|
|
1547
1588
|
* privateKey: pemEncodedPrivateKey,
|
|
1548
|
-
* algorithm: 'RS256'
|
|
1589
|
+
* algorithm: 'RS256',
|
|
1590
|
+
* expectedIssuer: 'https://auth.example.com'
|
|
1549
1591
|
* });
|
|
1550
1592
|
*
|
|
1551
1593
|
* const transport = new StreamableHTTPClientTransport(serverUrl, {
|
|
@@ -1561,7 +1603,7 @@ var PrivateKeyJwtProvider = class {
|
|
|
1561
1603
|
constructor(options) {
|
|
1562
1604
|
this._clientInfo = {
|
|
1563
1605
|
client_id: options.clientId,
|
|
1564
|
-
issuer: options.expectedIssuer
|
|
1606
|
+
issuer: checkedExpectedIssuer(options.expectedIssuer)
|
|
1565
1607
|
};
|
|
1566
1608
|
this._clientMetadata = {
|
|
1567
1609
|
client_name: options.clientName ?? "private-key-jwt-client",
|
|
@@ -1620,7 +1662,7 @@ var StaticPrivateKeyJwtProvider = class {
|
|
|
1620
1662
|
constructor(options) {
|
|
1621
1663
|
this._clientInfo = {
|
|
1622
1664
|
client_id: options.clientId,
|
|
1623
|
-
issuer: options.expectedIssuer
|
|
1665
|
+
issuer: checkedExpectedIssuer(options.expectedIssuer)
|
|
1624
1666
|
};
|
|
1625
1667
|
this._clientMetadata = {
|
|
1626
1668
|
client_name: options.clientName ?? "static-private-key-jwt-client",
|
|
@@ -1692,7 +1734,8 @@ var StaticPrivateKeyJwtProvider = class {
|
|
|
1692
1734
|
* return result.jwtAuthGrant;
|
|
1693
1735
|
* },
|
|
1694
1736
|
* clientId: 'my-mcp-client',
|
|
1695
|
-
* clientSecret: 'my-mcp-secret'
|
|
1737
|
+
* clientSecret: 'my-mcp-secret',
|
|
1738
|
+
* expectedIssuer: 'https://auth.example.com'
|
|
1696
1739
|
* });
|
|
1697
1740
|
*
|
|
1698
1741
|
* const transport = new StreamableHTTPClientTransport(serverUrl, {
|
|
@@ -1713,7 +1756,7 @@ var CrossAppAccessProvider = class {
|
|
|
1713
1756
|
this._clientInfo = {
|
|
1714
1757
|
client_id: options.clientId,
|
|
1715
1758
|
client_secret: options.clientSecret,
|
|
1716
|
-
issuer: options.expectedIssuer
|
|
1759
|
+
issuer: checkedExpectedIssuer(options.expectedIssuer)
|
|
1717
1760
|
};
|
|
1718
1761
|
this._clientMetadata = {
|
|
1719
1762
|
client_name: options.clientName ?? "cross-app-access-client",
|
|
@@ -2376,6 +2419,10 @@ function classifyProbeOutcome(outcome, context) {
|
|
|
2376
2419
|
case "rpc-error": return classifyRpcError(outcome, context);
|
|
2377
2420
|
case "http-error": return classifyHttpError(outcome, context);
|
|
2378
2421
|
case "network-error": return classifyNetworkError(outcome.error, context);
|
|
2422
|
+
case "unusable-reply": return {
|
|
2423
|
+
kind: "error",
|
|
2424
|
+
error: new require_src.SdkError(require_src.SdkErrorCode.EraNegotiationFailed, `Version negotiation probe failed: the server answered with an unusable reply (${describeError(outcome.error)})`, { cause: outcome.error }, { cause: outcome.error })
|
|
2425
|
+
};
|
|
2379
2426
|
case "auth-required": return {
|
|
2380
2427
|
kind: "error",
|
|
2381
2428
|
error: outcome.error
|
|
@@ -2713,6 +2760,11 @@ function buildProbeRequest(id, protocolVersion, clientInfo, capabilities) {
|
|
|
2713
2760
|
}) }
|
|
2714
2761
|
};
|
|
2715
2762
|
}
|
|
2763
|
+
/** True for what the transport throws when the probe was answered 2xx without a usable reply. */
|
|
2764
|
+
function isUnusableReplyError(error) {
|
|
2765
|
+
if (error instanceof require_src.SdkError && error.code === require_src.SdkErrorCode.ClientHttpUnexpectedContent) return true;
|
|
2766
|
+
return error instanceof Error && error.name === "SyntaxError";
|
|
2767
|
+
}
|
|
2716
2768
|
function normalizeReply(reply, timeoutMs) {
|
|
2717
2769
|
switch (reply.kind) {
|
|
2718
2770
|
case "response": return reply.error === void 0 ? {
|
|
@@ -2737,6 +2789,10 @@ function normalizeReply(reply, timeoutMs) {
|
|
|
2737
2789
|
statusText: error.data.statusText
|
|
2738
2790
|
};
|
|
2739
2791
|
}
|
|
2792
|
+
if (isUnusableReplyError(error)) return {
|
|
2793
|
+
kind: "unusable-reply",
|
|
2794
|
+
error
|
|
2795
|
+
};
|
|
2740
2796
|
return {
|
|
2741
2797
|
kind: "network-error",
|
|
2742
2798
|
error
|
|
@@ -3635,7 +3691,7 @@ var Client = class extends require_src.Protocol {
|
|
|
3635
3691
|
}, options);
|
|
3636
3692
|
const hit = await this._serveFromCache("prompts/list", void 0, options);
|
|
3637
3693
|
if (hit !== void 0) return hit;
|
|
3638
|
-
return this._listAllPages("prompts/list", params, options, (
|
|
3694
|
+
return this._listAllPages("prompts/list", params, options, (r) => r.prompts);
|
|
3639
3695
|
}
|
|
3640
3696
|
/**
|
|
3641
3697
|
* Lists available resources.
|
|
@@ -3674,7 +3730,7 @@ var Client = class extends require_src.Protocol {
|
|
|
3674
3730
|
}, options);
|
|
3675
3731
|
const hit = await this._serveFromCache("resources/list", void 0, options);
|
|
3676
3732
|
if (hit !== void 0) return hit;
|
|
3677
|
-
return this._listAllPages("resources/list", params, options, (
|
|
3733
|
+
return this._listAllPages("resources/list", params, options, (r) => r.resources);
|
|
3678
3734
|
}
|
|
3679
3735
|
/**
|
|
3680
3736
|
* Lists available resource URI templates for dynamic resources.
|
|
@@ -3699,7 +3755,7 @@ var Client = class extends require_src.Protocol {
|
|
|
3699
3755
|
}, options);
|
|
3700
3756
|
const hit = await this._serveFromCache("resources/templates/list", void 0, options);
|
|
3701
3757
|
if (hit !== void 0) return hit;
|
|
3702
|
-
return this._listAllPages("resources/templates/list", params, options, (
|
|
3758
|
+
return this._listAllPages("resources/templates/list", params, options, (r) => r.resourceTemplates);
|
|
3703
3759
|
}
|
|
3704
3760
|
/**
|
|
3705
3761
|
* Walk every page of a paginated list verb, aggregate, and write ONE
|
|
@@ -3707,8 +3763,7 @@ var Client = class extends require_src.Protocol {
|
|
|
3707
3763
|
* methods' no-`cursor` auto-aggregate path. Page 1's result object is
|
|
3708
3764
|
* mutated in place (its items array is extended; `nextCursor` is
|
|
3709
3765
|
* cleared); page-1 metadata (`ttlMs`, `cacheScope`, `_meta`) is preserved.
|
|
3710
|
-
* A `nextCursor`
|
|
3711
|
-
* non-converging server, mcp.d's `drainList` guard);
|
|
3766
|
+
* A page with the same items and `nextCursor` as the previous page ends the walk;
|
|
3712
3767
|
* {@linkcode ClientOptions.listMaxPages} is a hard cap — hitting it
|
|
3713
3768
|
* throws, so a partial aggregate is never cached. The
|
|
3714
3769
|
* captured-generation guard skips the write when a `list_changed` landed
|
|
@@ -3723,7 +3778,7 @@ var Client = class extends require_src.Protocol {
|
|
|
3723
3778
|
* trace context) supplied to the public `list*()` reaches every wire
|
|
3724
3779
|
* request the walk issues.
|
|
3725
3780
|
*/
|
|
3726
|
-
async _listAllPages(method, baseParams, options,
|
|
3781
|
+
async _listAllPages(method, baseParams, options, items, finalize) {
|
|
3727
3782
|
const bypass = options?.cacheMode === "bypass";
|
|
3728
3783
|
const generation = this._cache.captureGeneration(method);
|
|
3729
3784
|
const acc = await this.request({
|
|
@@ -3731,14 +3786,13 @@ var Client = class extends require_src.Protocol {
|
|
|
3731
3786
|
...baseParams && { params: { ...baseParams } }
|
|
3732
3787
|
}, options);
|
|
3733
3788
|
let cursor = acc.nextCursor;
|
|
3734
|
-
|
|
3789
|
+
let previous = acc;
|
|
3735
3790
|
let pages = 1;
|
|
3736
|
-
while (cursor !== void 0
|
|
3791
|
+
while (cursor !== void 0) {
|
|
3737
3792
|
if (this._listMaxPages !== 0 && pages >= this._listMaxPages) throw new require_src.SdkError(require_src.SdkErrorCode.ListPaginationExceeded, `${method}: exceeded listMaxPages (${this._listMaxPages}); server pagination did not terminate`, {
|
|
3738
3793
|
method,
|
|
3739
3794
|
listMaxPages: this._listMaxPages
|
|
3740
3795
|
});
|
|
3741
|
-
seen.add(cursor);
|
|
3742
3796
|
const page = await this.request({
|
|
3743
3797
|
method,
|
|
3744
3798
|
params: {
|
|
@@ -3746,7 +3800,9 @@ var Client = class extends require_src.Protocol {
|
|
|
3746
3800
|
cursor
|
|
3747
3801
|
}
|
|
3748
3802
|
}, options);
|
|
3749
|
-
|
|
3803
|
+
if (page.nextCursor === cursor && JSON.stringify(items(page)) === JSON.stringify(items(previous))) break;
|
|
3804
|
+
items(acc).push(...items(page));
|
|
3805
|
+
previous = page;
|
|
3750
3806
|
cursor = page.nextCursor;
|
|
3751
3807
|
pages++;
|
|
3752
3808
|
}
|
|
@@ -4007,19 +4063,22 @@ var Client = class extends require_src.Protocol {
|
|
|
4007
4063
|
notifications: filter
|
|
4008
4064
|
}
|
|
4009
4065
|
};
|
|
4066
|
+
const routeSendFailure = (error) => {
|
|
4067
|
+
settle({
|
|
4068
|
+
cause: "remote",
|
|
4069
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
4070
|
+
});
|
|
4071
|
+
};
|
|
4010
4072
|
try {
|
|
4011
|
-
|
|
4073
|
+
this.transport.send(jsonrpcRequest, {
|
|
4012
4074
|
requestSignal: requestAbort.signal,
|
|
4013
4075
|
onRequestStreamEnd: () => settle({
|
|
4014
4076
|
cause: "remote",
|
|
4015
4077
|
error: /* @__PURE__ */ new Error("subscriptions/listen: stream ended")
|
|
4016
4078
|
})
|
|
4017
|
-
});
|
|
4079
|
+
}).catch(routeSendFailure);
|
|
4018
4080
|
} catch (error) {
|
|
4019
|
-
|
|
4020
|
-
cause: "remote",
|
|
4021
|
-
error: error instanceof Error ? error : new Error(String(error))
|
|
4022
|
-
});
|
|
4081
|
+
routeSendFailure(error);
|
|
4023
4082
|
}
|
|
4024
4083
|
return {
|
|
4025
4084
|
honoredFilter: await opening,
|
|
@@ -4271,7 +4330,7 @@ var Client = class extends require_src.Protocol {
|
|
|
4271
4330
|
}
|
|
4272
4331
|
const hit = await this._serveFromCache("tools/list", void 0, options);
|
|
4273
4332
|
if (hit !== void 0) return hit;
|
|
4274
|
-
return this._listAllPages("tools/list", params, options, (
|
|
4333
|
+
return this._listAllPages("tools/list", params, options, (r) => r.tools, (acc) => this._excludeInvalidXMcpHeaderTools(acc));
|
|
4275
4334
|
}
|
|
4276
4335
|
/**
|
|
4277
4336
|
* SEP-2243 (protocol revision 2026-07-28): a Streamable HTTP client MUST
|
|
@@ -4384,7 +4443,7 @@ async function requestJwtAuthorizationGrant(options) {
|
|
|
4384
4443
|
});
|
|
4385
4444
|
if (clientSecret) params.set("client_secret", clientSecret);
|
|
4386
4445
|
if (scope) params.set("scope", scope);
|
|
4387
|
-
const response = await fetchFn(tokenUrl, {
|
|
4446
|
+
const response = await require_src.fetchWithinOrigin(fetchFn)(tokenUrl, {
|
|
4388
4447
|
method: "POST",
|
|
4389
4448
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
4390
4449
|
body: params.toString()
|
|
@@ -4477,7 +4536,7 @@ async function exchangeJwtAuthGrant(options) {
|
|
|
4477
4536
|
client_id: clientId,
|
|
4478
4537
|
client_secret: clientSecret
|
|
4479
4538
|
}, headers, params);
|
|
4480
|
-
const response = await fetchFn(tokenUrl, {
|
|
4539
|
+
const response = await require_src.fetchWithinOrigin(fetchFn)(tokenUrl, {
|
|
4481
4540
|
method: "POST",
|
|
4482
4541
|
headers,
|
|
4483
4542
|
body: params.toString()
|
|
@@ -4492,7 +4551,7 @@ async function exchangeJwtAuthGrant(options) {
|
|
|
4492
4551
|
throw new Error(`JWT grant exchange failed with status ${response.status}: ${JSON.stringify(errorBody)}`);
|
|
4493
4552
|
}
|
|
4494
4553
|
const responseBody = await response.json();
|
|
4495
|
-
const parseResult = _modelcontextprotocol_core_internal.OAuthTokensSchema.safeParse(responseBody);
|
|
4554
|
+
const parseResult = _modelcontextprotocol_core_internal.OAuthTokensSchema.safeParse(require_src.withoutIssuer(responseBody));
|
|
4496
4555
|
if (!parseResult.success) throw new Error(`Invalid token response: ${parseResult.error.message}`);
|
|
4497
4556
|
return parseResult.data;
|
|
4498
4557
|
}
|
|
@@ -4997,6 +5056,7 @@ var SSEClientTransport = class {
|
|
|
4997
5056
|
_skipIssuerMetadataValidation;
|
|
4998
5057
|
_fetch;
|
|
4999
5058
|
_fetchWithInit;
|
|
5059
|
+
_redirectPolicy;
|
|
5000
5060
|
_dpop;
|
|
5001
5061
|
_protocolVersion;
|
|
5002
5062
|
onclose;
|
|
@@ -5018,9 +5078,21 @@ var SSEClientTransport = class {
|
|
|
5018
5078
|
this._fetch = this._dpop(opts.fetch ?? fetch);
|
|
5019
5079
|
}
|
|
5020
5080
|
} else this._authProvider = opts?.authProvider;
|
|
5081
|
+
this._redirectPolicy = opts?.redirectPolicy;
|
|
5021
5082
|
this._fetchWithInit = require_src.createFetchWithInit(opts?.fetch, opts?.requestInit);
|
|
5083
|
+
if (this._redirectPolicy === "follow") this._fetchWithInit = require_src.fetchLeavingRedirects(this._fetchWithInit);
|
|
5022
5084
|
}
|
|
5023
5085
|
_last401Response;
|
|
5086
|
+
_connectAuthRetried = false;
|
|
5087
|
+
/** `baseFetch` with redirects handled as `redirectPolicy` says. */
|
|
5088
|
+
_redirects(baseFetch) {
|
|
5089
|
+
return this._redirectPolicy === "follow" ? baseFetch : require_src.fetchWithinOrigin(baseFetch);
|
|
5090
|
+
}
|
|
5091
|
+
/** Error text for a redirect `response` that was not followed, or `undefined` for any other response. */
|
|
5092
|
+
_unfollowedRedirect(url, response) {
|
|
5093
|
+
const text = this._redirectPolicy === "follow" ? void 0 : require_src.unfollowedRedirect(url, response);
|
|
5094
|
+
return text && `${text} (redirectPolicy: 'same-origin')`;
|
|
5095
|
+
}
|
|
5024
5096
|
async _commonHeaders() {
|
|
5025
5097
|
const headers = new Headers(this._requestInit?.headers || void 0);
|
|
5026
5098
|
let token;
|
|
@@ -5035,7 +5107,8 @@ var SSEClientTransport = class {
|
|
|
5035
5107
|
}
|
|
5036
5108
|
_startOrAuth() {
|
|
5037
5109
|
const eventSourceFetch = this._eventSourceInit?.fetch;
|
|
5038
|
-
const fetchImpl = eventSourceFetch ? this._dpop?.(eventSourceFetch) ?? eventSourceFetch : this._fetch ?? fetch;
|
|
5110
|
+
const fetchImpl = this._redirects(eventSourceFetch ? this._dpop?.(eventSourceFetch) ?? eventSourceFetch : this._fetch ?? fetch);
|
|
5111
|
+
let redirect;
|
|
5039
5112
|
return new Promise((resolve, reject) => {
|
|
5040
5113
|
this._eventSource = new eventsource.EventSource(this._url.href, {
|
|
5041
5114
|
...this._eventSourceInit,
|
|
@@ -5046,6 +5119,7 @@ var SSEClientTransport = class {
|
|
|
5046
5119
|
...init,
|
|
5047
5120
|
headers
|
|
5048
5121
|
});
|
|
5122
|
+
redirect = this._unfollowedRedirect(url, response);
|
|
5049
5123
|
if (response.status === 401) {
|
|
5050
5124
|
this._last401Response = response;
|
|
5051
5125
|
if (response.headers.has("www-authenticate")) {
|
|
@@ -5060,31 +5134,42 @@ var SSEClientTransport = class {
|
|
|
5060
5134
|
this._abortController = new AbortController();
|
|
5061
5135
|
this._eventSource.onerror = (event) => {
|
|
5062
5136
|
if (event.code === 401 && this._authProvider) {
|
|
5063
|
-
if (this._authProvider.onUnauthorized && this._last401Response) {
|
|
5137
|
+
if (this._authProvider.onUnauthorized && this._last401Response && !this._connectAuthRetried) {
|
|
5064
5138
|
const response = this._last401Response;
|
|
5065
5139
|
this._last401Response = void 0;
|
|
5140
|
+
this._connectAuthRetried = true;
|
|
5066
5141
|
this._eventSource?.close();
|
|
5067
5142
|
this._authProvider.onUnauthorized({
|
|
5068
5143
|
response,
|
|
5069
5144
|
serverUrl: this._url,
|
|
5070
5145
|
fetchFn: this._fetchWithInit
|
|
5071
5146
|
}).then(() => this._startOrAuth().then(resolve, reject), (error$2) => {
|
|
5147
|
+
this._connectAuthRetried = false;
|
|
5072
5148
|
markAuthSeamEscape(error$2);
|
|
5073
5149
|
this.onerror?.(error$2);
|
|
5074
5150
|
reject(error$2);
|
|
5075
5151
|
});
|
|
5076
5152
|
return;
|
|
5077
5153
|
}
|
|
5078
|
-
const
|
|
5154
|
+
const retried = this._connectAuthRetried;
|
|
5155
|
+
this._connectAuthRetried = false;
|
|
5156
|
+
const error$1 = markAuthSeamEscape(retried ? new require_src.SdkHttpError(require_src.SdkErrorCode.ClientHttpAuthentication, "Server returned 401 after re-authentication", {
|
|
5157
|
+
status: 401,
|
|
5158
|
+
statusText: this._last401Response?.statusText ?? ""
|
|
5159
|
+
}) : new UnauthorizedError());
|
|
5160
|
+
this._last401Response = void 0;
|
|
5079
5161
|
reject(error$1);
|
|
5080
5162
|
this.onerror?.(error$1);
|
|
5081
5163
|
return;
|
|
5082
5164
|
}
|
|
5083
|
-
|
|
5165
|
+
this._connectAuthRetried = false;
|
|
5166
|
+
const error = new SseError(event.code, redirect ?? event.message, event);
|
|
5084
5167
|
reject(error);
|
|
5085
5168
|
this.onerror?.(error);
|
|
5086
5169
|
};
|
|
5087
|
-
this._eventSource.onopen = () => {
|
|
5170
|
+
this._eventSource.onopen = () => {
|
|
5171
|
+
this._connectAuthRetried = false;
|
|
5172
|
+
};
|
|
5088
5173
|
this._eventSource.addEventListener("endpoint", (event) => {
|
|
5089
5174
|
const messageEvent = event;
|
|
5090
5175
|
try {
|
|
@@ -5151,7 +5236,7 @@ var SSEClientTransport = class {
|
|
|
5151
5236
|
body: JSON.stringify(message),
|
|
5152
5237
|
signal: this._abortController?.signal
|
|
5153
5238
|
};
|
|
5154
|
-
const response = await (this._fetch ?? fetch)(this._endpoint, init);
|
|
5239
|
+
const response = await this._redirects(this._fetch ?? fetch)(this._endpoint, init);
|
|
5155
5240
|
if (!response.ok) {
|
|
5156
5241
|
if (response.status === 401 && this._authProvider) {
|
|
5157
5242
|
if (response.headers.has("www-authenticate")) {
|
|
@@ -5180,7 +5265,7 @@ var SSEClientTransport = class {
|
|
|
5180
5265
|
throw markAuthSeamEscape(new UnauthorizedError());
|
|
5181
5266
|
}
|
|
5182
5267
|
const text = await response.text?.().catch(() => null);
|
|
5183
|
-
throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${text}`);
|
|
5268
|
+
throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${this._unfollowedRedirect(this._endpoint, response) ?? text}`);
|
|
5184
5269
|
}
|
|
5185
5270
|
await response.text?.().catch(() => {});
|
|
5186
5271
|
} catch (error) {
|
|
@@ -5265,6 +5350,7 @@ var StreamableHTTPClientTransport = class {
|
|
|
5265
5350
|
_skipIssuerMetadataValidation;
|
|
5266
5351
|
_fetch;
|
|
5267
5352
|
_fetchWithInit;
|
|
5353
|
+
_redirectPolicy;
|
|
5268
5354
|
_sessionId;
|
|
5269
5355
|
_reconnectionOptions;
|
|
5270
5356
|
_protocolVersion;
|
|
@@ -5295,7 +5381,9 @@ var StreamableHTTPClientTransport = class {
|
|
|
5295
5381
|
this._authProvider = adaptOAuthProvider(opts.authProvider, { skipIssuerMetadataValidation: opts.skipIssuerMetadataValidation });
|
|
5296
5382
|
if (opts.authProvider.dpop) this._fetch = withDpopFromProvider(opts.authProvider)(opts.fetch ?? fetch);
|
|
5297
5383
|
} else this._authProvider = opts?.authProvider;
|
|
5384
|
+
this._redirectPolicy = opts?.redirectPolicy;
|
|
5298
5385
|
this._fetchWithInit = require_src.createFetchWithInit(opts?.fetch, opts?.requestInit);
|
|
5386
|
+
if (this._redirectPolicy === "follow") this._fetchWithInit = require_src.fetchLeavingRedirects(this._fetchWithInit);
|
|
5299
5387
|
this._sessionId = opts?.sessionId;
|
|
5300
5388
|
this._protocolVersion = opts?.protocolVersion;
|
|
5301
5389
|
this._reconnectionOptions = opts?.reconnectionOptions ?? DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS;
|
|
@@ -5347,6 +5435,15 @@ var StreamableHTTPClientTransport = class {
|
|
|
5347
5435
|
skipIssuerMetadataValidation: this._skipIssuerMetadataValidation
|
|
5348
5436
|
});
|
|
5349
5437
|
}
|
|
5438
|
+
/** `baseFetch` with redirects handled as `redirectPolicy` says. */
|
|
5439
|
+
_redirects(baseFetch) {
|
|
5440
|
+
return this._redirectPolicy === "follow" ? baseFetch : require_src.fetchWithinOrigin(baseFetch);
|
|
5441
|
+
}
|
|
5442
|
+
/** Error text for a redirect `response` that was not followed, or `undefined` for any other response. */
|
|
5443
|
+
_unfollowedRedirect(url, response) {
|
|
5444
|
+
const text = this._redirectPolicy === "follow" ? void 0 : require_src.unfollowedRedirect(url, response);
|
|
5445
|
+
return text && `${text} (redirectPolicy: 'same-origin')`;
|
|
5446
|
+
}
|
|
5350
5447
|
async _commonHeaders() {
|
|
5351
5448
|
const headers = new Headers(this._requestInit?.headers || void 0);
|
|
5352
5449
|
let token;
|
|
@@ -5398,7 +5495,7 @@ var StreamableHTTPClientTransport = class {
|
|
|
5398
5495
|
if (resumptionToken) headers.set("last-event-id", resumptionToken);
|
|
5399
5496
|
const transportSignal = this._abortController?.signal;
|
|
5400
5497
|
const signal = requestSignal !== void 0 && transportSignal !== void 0 ? anySignal(transportSignal, requestSignal) : requestSignal ?? transportSignal;
|
|
5401
|
-
const response = await (this._fetch ?? fetch)(this._url, {
|
|
5498
|
+
const response = await this._redirects(this._fetch ?? fetch)(this._url, {
|
|
5402
5499
|
...this._requestInit,
|
|
5403
5500
|
method: "GET",
|
|
5404
5501
|
headers,
|
|
@@ -5450,7 +5547,8 @@ var StreamableHTTPClientTransport = class {
|
|
|
5450
5547
|
options.onRequestStreamEnd?.();
|
|
5451
5548
|
return;
|
|
5452
5549
|
}
|
|
5453
|
-
|
|
5550
|
+
const reason = this._unfollowedRedirect(this._url, response) ?? response.statusText;
|
|
5551
|
+
throw new require_src.SdkHttpError(require_src.SdkErrorCode.ClientHttpFailedToOpenStream, `Failed to open SSE stream: ${reason}`, {
|
|
5454
5552
|
status: response.status,
|
|
5455
5553
|
statusText: response.statusText
|
|
5456
5554
|
});
|
|
@@ -5639,7 +5737,7 @@ var StreamableHTTPClientTransport = class {
|
|
|
5639
5737
|
body: JSON.stringify(message),
|
|
5640
5738
|
signal
|
|
5641
5739
|
};
|
|
5642
|
-
const response = await (this._fetch ?? fetch)(this._url, init);
|
|
5740
|
+
const response = await this._redirects(this._fetch ?? fetch)(this._url, init);
|
|
5643
5741
|
if (isHandshake && response.ok) this._sessionId = response.headers.get("mcp-session-id") || void 0;
|
|
5644
5742
|
if (!response.ok) {
|
|
5645
5743
|
if (response.status === 401 && this._authProvider) {
|
|
@@ -5690,7 +5788,8 @@ var StreamableHTTPClientTransport = class {
|
|
|
5690
5788
|
return;
|
|
5691
5789
|
}
|
|
5692
5790
|
} catch {}
|
|
5693
|
-
|
|
5791
|
+
const reason = this._unfollowedRedirect(this._url, response) ?? text;
|
|
5792
|
+
throw new require_src.SdkHttpError(require_src.SdkErrorCode.ClientHttpNotImplemented, `Error POSTing to endpoint: ${reason}`, {
|
|
5694
5793
|
status: response.status,
|
|
5695
5794
|
statusText: response.statusText,
|
|
5696
5795
|
text
|
|
@@ -5747,9 +5846,9 @@ var StreamableHTTPClientTransport = class {
|
|
|
5747
5846
|
headers,
|
|
5748
5847
|
signal: this._abortController?.signal
|
|
5749
5848
|
};
|
|
5750
|
-
const response = await (this._fetch ?? fetch)(this._url, init);
|
|
5849
|
+
const response = await this._redirects(this._fetch ?? fetch)(this._url, init);
|
|
5751
5850
|
await response.text?.().catch(() => {});
|
|
5752
|
-
if (!response.ok && response.status !== 405) throw new require_src.SdkHttpError(require_src.SdkErrorCode.ClientHttpFailedToTerminateSession, `Failed to terminate session: ${response.statusText}`, {
|
|
5851
|
+
if (!response.ok && response.status !== 405) throw new require_src.SdkHttpError(require_src.SdkErrorCode.ClientHttpFailedToTerminateSession, `Failed to terminate session: ${this._unfollowedRedirect(this._url, response) ?? response.statusText}`, {
|
|
5753
5852
|
status: response.status,
|
|
5754
5853
|
statusText: response.statusText
|
|
5755
5854
|
});
|