🔄 refactor: OAuth Metadata Discovery with Origin Fallback (#12170)

* 🔄 refactor: OAuth Metadata Discovery with Origin Fallback

Updated the `discoverWithOriginFallback` method to improve the handling of OAuth authorization server metadata discovery. The method now retries with the origin URL when discovery fails for a path-based URL, ensuring consistent behavior across `discoverMetadata` and token refresh flows. This change reduces code duplication and enhances the reliability of the OAuth flow by providing a unified implementation for origin fallback logic.

* 🧪 test: Add tests for OAuth Token Refresh with Origin Fallback

Introduced new tests for the `refreshOAuthTokens` method in `MCPOAuthHandler` to validate the retry mechanism with the origin URL when path-based discovery fails. The tests cover scenarios where the first discovery attempt throws an error and the subsequent attempt succeeds, as well as cases where the discovery fails entirely. This enhances the reliability of the OAuth token refresh process by ensuring proper handling of discovery failures.

* chore: imports order

* fix: Improve Base URL Logging and Metadata Discovery in MCPOAuthHandler

Updated the logging to use a consistent base URL object when handling discovery failures in the MCPOAuthHandler. This change enhances error reporting by ensuring that the base URL is logged correctly, and it refines the metadata discovery process by returning the result of the discovery attempt with the base URL, improving the reliability of the OAuth flow.
This commit is contained in:
Danny Avila 2026-03-10 16:19:07 -04:00 committed by GitHub
parent eb6328c1d9
commit c0e876a2e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 153 additions and 16 deletions

View file

@ -209,16 +209,28 @@ export class MCPOAuthHandler {
}
/**
* Discovers OAuth authorization server metadata with origin-URL fallback.
* If discovery fails for a path-based URL, retries with just the origin.
* Mirrors the fallback behavior in `discoverMetadata` and `initiateOAuthFlow`.
* Discovers OAuth authorization server metadata, retrying with just the origin
* when discovery fails for a path-based URL. Shared implementation used by
* `discoverMetadata` and both `refreshOAuthTokens` branches.
*/
private static async discoverWithOriginFallback(
serverUrl: URL,
fetchFn: FetchLike,
): ReturnType<typeof discoverAuthorizationServerMetadata> {
const metadata = await discoverAuthorizationServerMetadata(serverUrl, { fetchFn });
// If discovery failed and we're using a path-based URL, try the base URL
let metadata: Awaited<ReturnType<typeof discoverAuthorizationServerMetadata>>;
try {
metadata = await discoverAuthorizationServerMetadata(serverUrl, { fetchFn });
} catch (err) {
if (serverUrl.pathname === '/') {
throw err;
}
const baseUrl = new URL(serverUrl.origin);
logger.debug(
`[MCPOAuth] Discovery threw for path URL, trying base URL: ${sanitizeUrlForLogging(baseUrl)}`,
{ error: err },
);
return discoverAuthorizationServerMetadata(baseUrl, { fetchFn });
}
if (!metadata && serverUrl.pathname !== '/') {
const baseUrl = new URL(serverUrl.origin);
logger.debug(