oauthex: accept 200 in client registration (#877)

## Summary

Accepts HTTP 200 as a valid response in Dynamic Client Registration
(DCR), in addition to 201. Some authorization servers return 200 instead
of the RFC-specified 201 on successful registration.

Fixes https://github.com/modelcontextprotocol/go-sdk/issues/876

## Changes

- `oauthex/dcr.go`: accept 200 status code in client registration
response
- `oauthex/dcr_test.go`: add test coverage for the 200 response case
This commit is contained in:
MatyasVondraOutreach 2026-04-01 16:51:18 +02:00 • committed by GitHub
commit 76d5a54125
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 25 additions and 1 deletions

View file

@ -204,7 +204,7 @@ func RegisterClient(ctx context.Context, registrationEndpoint string, clientMeta
return nil, fmt.Errorf("failed to read registration response body: %w", err)
}
if resp.StatusCode == http.StatusCreated {
if resp.StatusCode == http.StatusCreated || resp.StatusCode == http.StatusOK {
var regResponse ClientRegistrationResponse
if err := internaljson.Unmarshal(body, &regResponse); err != nil {
return nil, fmt.Errorf("failed to decode successful registration response: %w (%s)", err, string(body))

View file

@ -70,6 +70,30 @@ func TestRegisterClient(t *testing.T) {
clientMeta: &ClientRegistrationMetadata{ClientName: "Test App", RedirectURIs: []string{"http://localhost/cb"}},
wantClientID: "test-client-id",
},
{
name: "Success with 200",
handler: func(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
t.Errorf("Expected POST, got %s", r.Method)
}
body, err := io.ReadAll(r.Body)
if err != nil {
t.Fatal(err)
}
var receivedMeta ClientRegistrationMetadata
if err := json.Unmarshal(body, &receivedMeta); err != nil {
t.Fatalf("Failed to unmarshal request body: %v", err)
}
if receivedMeta.ClientName != "Test App" {
t.Errorf("Expected ClientName 'Test App', got '%s'", receivedMeta.ClientName)
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"client_id":"test-client-id","client_secret":"test-client-secret","client_name":"Test App"}`))
},
clientMeta: &ClientRegistrationMetadata{ClientName: "Test App", RedirectURIs: []string{"http://localhost/cb"}},
wantClientID: "test-client-id",
},
{
name: "Missing ClientID in Response",
handler: func(w http.ResponseWriter, r *http.Request) {