@@ -518,7 +518,21 @@ export class McpManager {
518518 try {
519519 const headResp = await fetch ( base , { method : 'HEAD' , headers } )
520520 const www = headResp . headers . get ( 'www-authenticate' ) || ''
521- needsOAuth = headResp . status === 401 || headResp . status === 403 || / b e a r e r / i. test ( www )
521+ this . features . logging . info ( `MCP: HEAD response status: ${ headResp . status } ` )
522+
523+ if ( headResp . status === 401 || headResp . status === 403 || / b e a r e r / i. test ( www ) ) {
524+ needsOAuth = true
525+ this . features . logging . info ( `MCP: OAuth detected via HEAD (${ headResp . status } )` )
526+ } else if ( headResp . status === 405 || headResp . status === 404 ) {
527+ // HEAD not supported (405) or endpoint not found for HEAD (404), try POST-based OAuth detection
528+ this . features . logging . info (
529+ `MCP: HEAD returned ${ headResp . status } , trying POST-based OAuth detection`
530+ )
531+ needsOAuth = await this . detectOAuthFromPostError ( base , headers )
532+ if ( needsOAuth ) {
533+ this . features . logging . info ( `MCP: OAuth detected via POST error` )
534+ }
535+ }
522536 } catch {
523537 this . features . logging . info ( `MCP: HEAD not available` )
524538 }
@@ -1489,6 +1503,30 @@ export class McpManager {
14891503 return Array . from ( serverNames )
14901504 }
14911505
1506+ /**
1507+ * Detect OAuth requirement from POST error response
1508+ * Used when HEAD method returns 405 (Method Not Allowed)
1509+ */
1510+ private async detectOAuthFromPostError ( url : URL , headers : Record < string , string > ) : Promise < boolean > {
1511+ try {
1512+ const testPayload = { jsonrpc : '2.0' , method : 'initialize' , id : 1 }
1513+ const response = await fetch ( url , {
1514+ method : 'POST' ,
1515+ headers : { ...headers , 'Content-Type' : 'application/json' } ,
1516+ body : JSON . stringify ( testPayload ) ,
1517+ } )
1518+
1519+ if ( response . status === 401 ) {
1520+ const errorText = await response . text ( )
1521+ // Check for OAuth-related error messages
1522+ return / b e a r e r | t o k e n | a u t h | m i s s i n g .* a u t h / i. test ( errorText )
1523+ }
1524+ } catch ( e ) {
1525+ // Ignore errors, assume no OAuth required
1526+ }
1527+ return false
1528+ }
1529+
14921530 /**
14931531 * Get all builtin tool names
14941532 */
0 commit comments