You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
RevocationRequest requires client_secret, so public clients get 400 from /revoke #3648
POST /revoke answers 400 invalid_request to a public client (token_endpoint_auth_method: none) that sends only token and client_id, which is what RFC 7009 allows for a client without credentials.
Cause
In mcp/server/auth/handlers/revoke.py the form model is
client_secret: str | None has no default, so pydantic treats the field as required (nullable, but it must be present). A public client omits it, RevocationRequest.model_validate(dict(form_data)) fails and the handler returns 400 before the provider's revoke_token is called. ClientAuthenticator already handles the secret on its own (it reads it from the form or the Basic header and demands it only for a client registered with one), so the model does not need the field at all, or it needs = None.
Reproduction
Register a client with token_endpoint_auth_method: "none", obtain tokens, then POST /revoke with token=<refresh token>&client_id=<id>. Expected 200, actual 400 {"error": "invalid_request", ...}. Claude Code registers this way and hit it (mcp 2.2.0).
Suggested fix
client_secret: str | None = None (or drop the field).
Thanks for the clear report. This is the same problem as #3508, so I'm going to close this one as a duplicate to keep everything in one place.
Your diagnosis matches what's there: the field has no default, so a public client that leaves it out is rejected before the provider is called. It's also useful to know you hit this through Claude Code on 2.2.0, since that's what helps us prioritise it. Feel free to add anything else on #3508 :)
Activity
maxisbey commentedon Oct 6, 2026
Thanks for the clear report. This is the same problem as #3508, so I'm going to close this one as a duplicate to keep everything in one place.
Your diagnosis matches what's there: the field has no default, so a public client that leaves it out is rejected before the provider is called. It's also useful to know you hit this through Claude Code on 2.2.0, since that's what helps us prioritise it. Feel free to add anything else on #3508 :)
AI Disclaimer
Generated by Claude Code