From 76d5a54125a3f1f0fa182a90f040ffc0c4164fb8 Mon Sep 17 00:00:00 2001 From: MatyasVondraOutreach Date: Wed, 1 Apr 2026 16:51:18 +0200 Subject: [PATCH] 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 --- oauthex/dcr.go | 2 +- oauthex/dcr_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/oauthex/dcr.go b/oauthex/dcr.go index 653cf5b..ce21467 100644 --- a/oauthex/dcr.go +++ b/oauthex/dcr.go @@ -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, ®Response); err != nil { return nil, fmt.Errorf("failed to decode successful registration response: %w (%s)", err, string(body)) diff --git a/oauthex/dcr_test.go b/oauthex/dcr_test.go index ec94c49..afff34c 100644 --- a/oauthex/dcr_test.go +++ b/oauthex/dcr_test.go @@ -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) {