@@ -499,3 +499,58 @@ func TestCreateOAuthConfig_FallsBackToServerURL(t *testing.T) {
499499 assert .True (t , hasResource , "extraParams should contain 'resource' key (fallback)" )
500500 assert .Equal (t , mockMetadataServer .URL + "/mcp" , resource , "Resource should fall back to server URL" )
501501}
502+
503+ // Test CreateOAuthConfig auto-detects resource when HEAD returns 405 and POST is needed
504+ func TestCreateOAuthConfig_FallsBackToPostWhenHeadNotAllowed (t * testing.T ) {
505+ // Variable to hold server URL for use in handler
506+ var serverURL string
507+
508+ // Create a mock server that returns 405 for HEAD but 401 with WWW-Authenticate for POST
509+ mockMetadataServer := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
510+ if r .URL .Path == "/.well-known/oauth-protected-resource" {
511+ w .Header ().Set ("Content-Type" , "application/json" )
512+ w .WriteHeader (http .StatusOK )
513+ w .Write ([]byte (`{
514+ "resource": "https://api.example.com/mcp/v1",
515+ "authorization_servers": ["https://auth.example.com"],
516+ "scopes_supported": ["mcp"]
517+ }` ))
518+ return
519+ }
520+ // HEAD returns 405 Method Not Allowed (like MCP servers)
521+ if r .Method == "HEAD" {
522+ w .Header ().Set ("Allow" , "POST" )
523+ w .WriteHeader (http .StatusMethodNotAllowed )
524+ return
525+ }
526+ // POST returns 401 with WWW-Authenticate header
527+ if r .Method == "POST" {
528+ w .Header ().Set ("WWW-Authenticate" , fmt .Sprintf (`Bearer error="invalid_token", resource_metadata="%s/.well-known/oauth-protected-resource"` , serverURL ))
529+ w .WriteHeader (http .StatusUnauthorized )
530+ return
531+ }
532+ w .WriteHeader (http .StatusNotFound )
533+ }))
534+ defer mockMetadataServer .Close ()
535+
536+ // Assign server URL after server is created
537+ serverURL = mockMetadataServer .URL
538+
539+ testStorage := setupTestStorage (t )
540+ serverConfig := & config.ServerConfig {
541+ Name : "test-post-fallback" ,
542+ URL : mockMetadataServer .URL + "/mcp" ,
543+ // No OAuth config - should auto-detect via POST fallback
544+ }
545+
546+ // Call CreateOAuthConfigWithExtraParams to get both config and extraParams
547+ oauthConfig , extraParams := CreateOAuthConfigWithExtraParams (serverConfig , testStorage )
548+
549+ require .NotNil (t , oauthConfig , "OAuth config should be created" )
550+ require .NotNil (t , extraParams , "Extra params should be returned" )
551+
552+ // Verify resource was auto-detected via POST fallback
553+ resource , hasResource := extraParams ["resource" ]
554+ assert .True (t , hasResource , "extraParams should contain 'resource' key" )
555+ assert .Equal (t , "https://api.example.com/mcp/v1" , resource , "Resource should be auto-detected via POST fallback" )
556+ }
0 commit comments