modelcontextprotocol / modelcontextprotocol/python-sdk

Revocation requires client_secret to be present

Offen Anfängerfreundlich
#3,508 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

v1 v2
Vorherrschende Sprache
Python
Sterne
24.3k
Forks
4k
Ø Merge
1 T. 1 Std.
Gemergte PRs (30 T.)
31

Beschreibung

Initial Checks
Release line

2.x (current stable)

Description
What happened?

When Claude Code (or any other public client) triggers revocation - revoke handler requires client_secret to be present, as seen here:

https://github.com/modelcontextprotocol/python-sdk/blob/9972c21aa42054fb1450c5fc614761ed11847ec6/src/mcp/server/auth/handlers/revoke.py#L23

Per OAuth 2.0 specifications (RFC 6749 Section 2.3 and RFC 7009 Section 5), public clients do not have a client_secret and identify themselves using only client_id.
This leads to issue when public clients do not sent client secret at all.

In Pydantic v2, defining a field as str | None without a default value still marks the field as required (i.e., nullable value, but the key must exist in the request body).

Steps to reproduce
  1. Authenticate using a public OAuth client (e.g., Claude Code CLI).
  2. Trigger token revocation (e.g., re-authenticating or logging out).
  3. The authorization server returns a 400 Bad Request with:
    {"error":"invalid_request","error_description":"client_secret: Field required"}
Expected behavior

client_secret should be optional so public clients can revoke tokens without sending a client_secret key.

Fix

Adding default value for client_secret:

client_secret: str | None = None
Workaround

As workaround I'm overriding Request type:

from mcp.server.auth.handlers import revoke

class FixedRevocationRequest(revoke.RevocationRequest):
    client_secret: str | None = None

revoke.RevocationRequest = FixedRevocationRequest
Example Code
from mcp.server.auth.handlers.revoke import RevocationRequest
from pydantic import ValidationError

# Simulate a public client request: client_secret parameter omitted entirely
form_no_secret = {"token": "abc", "client_id": "local-scurri-mcp"}

try:
    req = RevocationRequest.model_validate(form_no_secret)
    print("no-secret: OK ->", req)
except ValidationError as e:
    print("no-secret: FAILS ->", e.errors()[0]["msg"])
Python & MCP Python SDK
MCP version:                                                                                                     2.2.0
Python version:                                                                                                 3.13.9

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginnen Sie in src/mcp/server/auth/handlers/revoke.py bei RevocationRequest und überprüfen Sie das verknüpfte Validierungsverhalten. Bestätigen Sie, dass eine Revocation-Anfrage eines Public Clients client_secret weglassen darf, und verwenden Sie anschließend das bereitgestellte Pydantic-Beispiel mit nur token und client_id, um zu überprüfen, dass die Validierung erfolgreich ist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
authentication
Issue-Typ
Bug
Schwierigkeit
1/5
Geschätzter Aufwand
Unter einer Stunde
Aktivitätsstatus
Aktiv
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
91/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.