@@ -292,25 +292,25 @@ export async function discoverOAuthProtectedResourceMetadata(
292292 return OAuthProtectedResourceMetadataSchema . parse ( await response . json ( ) ) ;
293293}
294294
295- /**
296- * Looks up RFC 8414 OAuth 2.0 Authorization Server Metadata.
297- *
298- * If the server returns a 404 for the well-known endpoint, this function will
299- * return `undefined`. Any other errors will be thrown as exceptions.
300- */
301295/**
302296 * Helper function to handle fetch with CORS retry logic
303297 */
304298async function fetchWithCorsRetry (
305299 url : URL ,
306- headers : Record < string , string > ,
307- ) : Promise < Response > {
300+ headers ?: Record < string , string > ,
301+ ) : Promise < Response | undefined > {
302+ console . log ( 'fetchWithCorsRetry called with:' , { url, headers } ) ;
308303 try {
309304 return await fetch ( url , { headers } ) ;
310305 } catch ( error ) {
311- // CORS errors come back as TypeError, retry without headers
312306 if ( error instanceof TypeError ) {
313- return await fetch ( url ) ;
307+ if ( headers ) {
308+ // CORS errors come back as TypeError, retry without headers
309+ return fetchWithCorsRetry ( url )
310+ } else {
311+ // We're getting CORS errors on retry too, return undefined
312+ return undefined
313+ }
314314 }
315315 throw error ;
316316 }
@@ -334,7 +334,7 @@ function buildWellKnownPath(pathname: string): string {
334334async function tryMetadataDiscovery (
335335 url : URL ,
336336 protocolVersion : string ,
337- ) : Promise < Response > {
337+ ) : Promise < Response | undefined > {
338338 const headers = {
339339 "MCP-Protocol-Version" : protocolVersion
340340 } ;
@@ -344,10 +344,16 @@ async function tryMetadataDiscovery(
344344/**
345345 * Determines if fallback to root discovery should be attempted
346346 */
347- function shouldAttemptFallback ( response : Response , pathname : string ) : boolean {
348- return response . status === 404 && pathname !== '/' ;
347+ function shouldAttemptFallback ( response : Response | undefined , pathname : string ) : boolean {
348+ return ! response || response . status === 404 && pathname !== '/' ;
349349}
350350
351+ /**
352+ * Looks up RFC 8414 OAuth 2.0 Authorization Server Metadata.
353+ *
354+ * If the server returns a 404 for the well-known endpoint, this function will
355+ * return `undefined`. Any other errors will be thrown as exceptions.
356+ */
351357export async function discoverOAuthMetadata (
352358 authorizationServerUrl : string | URL ,
353359 opts ?: { protocolVersion ?: string } ,
@@ -362,18 +368,10 @@ export async function discoverOAuthMetadata(
362368
363369 // If path-aware discovery fails with 404, try fallback to root discovery
364370 if ( shouldAttemptFallback ( response , issuer . pathname ) ) {
365- try {
366- const rootUrl = new URL ( "/.well-known/oauth-authorization-server" , issuer ) ;
367- response = await tryMetadataDiscovery ( rootUrl , protocolVersion ) ;
368-
369- if ( response . status === 404 ) {
370- return undefined ;
371- }
372- } catch {
373- // If fallback fails, return undefined
374- return undefined ;
375- }
376- } else if ( response . status === 404 ) {
371+ const rootUrl = new URL ( "/.well-known/oauth-authorization-server" , issuer ) ;
372+ response = await tryMetadataDiscovery ( rootUrl , protocolVersion ) ;
373+ }
374+ if ( ! response || response . status === 404 ) {
377375 return undefined ;
378376 }
379377
0 commit comments