From c748ffae7422cd38494abf5670fa8322daa8bf96 Mon Sep 17 00:00:00 2001 From: guoyangzhen Date: Fri, 20 Mar 2026 23:13:21 +0800 Subject: [PATCH 1/2] fix: throw error on auth fallback for non-root AS paths Fixes #1716 When authorization server metadata discovery fails and the server URL has a non-root path, the fallback to /authorize, /token, and /register endpoints silently constructs wrong URLs (losing the path prefix). This fix throws a descriptive error instead of silently redirecting to nonexistent endpoints. Affected locations: - startAuthorization: /authorize fallback - executeTokenRequest: /token fallback - registerClient: /register fallback --- packages/client/src/client/auth.ts | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/client/src/client/auth.ts b/packages/client/src/client/auth.ts index 58ec23ddd..76d35bd7b 100644 --- a/packages/client/src/client/auth.ts +++ b/packages/client/src/client/auth.ts @@ -1200,6 +1200,11 @@ export async function startAuthorization( ) { throw new Error(`Incompatible auth server: does not support code challenge method ${AUTHORIZATION_CODE_CHALLENGE_METHOD}`); } + } else if (authorizationServerUrl.pathname !== '/') { + throw new Error( + `Authorization server metadata discovery failed and the server URL (${authorizationServerUrl}) has a non-root path. ` + + `Cannot determine the authorization endpoint. Please ensure the authorization server is reachable and supports metadata discovery.` + ); } else { authorizationUrl = new URL('/authorize', authorizationServerUrl); } @@ -1283,7 +1288,14 @@ async function executeTokenRequest( fetchFn?: FetchLike; } ): Promise { - const tokenUrl = metadata?.token_endpoint ? new URL(metadata.token_endpoint) : new URL('/token', authorizationServerUrl); + const tokenUrl = metadata?.token_endpoint + ? new URL(metadata.token_endpoint) + : authorizationServerUrl.pathname !== '/' + ? (() => { throw new Error( + `Authorization server metadata discovery failed and the server URL (${authorizationServerUrl}) has a non-root path. ` + + `Cannot determine the token endpoint.` + ); })() + : new URL('/token', authorizationServerUrl); const headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded', @@ -1530,6 +1542,12 @@ export async function registerClient( registrationUrl = new URL(metadata.registration_endpoint); } else { + if (authorizationServerUrl.pathname !== '/') { + throw new Error( + `Authorization server metadata discovery failed and the server URL (${authorizationServerUrl}) has a non-root path. ` + + `Cannot determine the registration endpoint.` + ); + } registrationUrl = new URL('/register', authorizationServerUrl); } From ea8ea36fa4d7a764e3fe0911c3841f310454a3be Mon Sep 17 00:00:00 2001 From: guoyangzhen Date: Sat, 21 Mar 2026 02:09:20 +0800 Subject: [PATCH 2/2] add changeset --- .changeset/fix-auth-fallback-non-root-path.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/fix-auth-fallback-non-root-path.md diff --git a/.changeset/fix-auth-fallback-non-root-path.md b/.changeset/fix-auth-fallback-non-root-path.md new file mode 100644 index 000000000..41ccc693c --- /dev/null +++ b/.changeset/fix-auth-fallback-non-root-path.md @@ -0,0 +1,7 @@ +--- +'@modelcontextprotocol/client': patch +--- + +Throw error on auth fallback for non-root AS paths instead of silently using incorrect absolute paths. Fixes URL path prefix loss when authorization server metadata discovery fails. + +Fixes modelcontextprotocol/typescript-sdk#1716