RevocationRequest requires client_secret, so public clients get 400 from /revoke
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 88/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- python
- Domain
- api, authentication, backend
Research direction
The form model lives in mcp/server/auth/handlers/revoke.py. Give client_secret a default of None (or drop the field) so pydantic no longer treats it as required, then confirm ClientAuthenticator still enforces secrets only for confidential clients. Reproduce with a public client (token_endpoint_auth_method: none) posting only token and client_id to /revoke; done when that returns 200 instead of 400 invalid_request.
Written by the indexing model from the issue text.
Description
Summary
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
class RevocationRequest(BaseModel):
token: str
token_type_hint: Literal["access_token", "refresh_token"] | None = None
client_id: str
client_secret: str | None
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).
- Dominant language
- Python
- Stars
- 24.5k
- Forks
- 4k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 35
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from modelcontextprotocol/python-sdk
-
v1 v2
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
modelcontextprotocol/python-sdk#3652 · 1 comment ·
Maintainers usually reply within 1 day
-
spec-2026-07-28 v2
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
modelcontextprotocol/python-sdk#3649 ·
Maintainers usually reply within 1 day
-
v1 v2
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
modelcontextprotocol/python-sdk#3639 · 1 comment ·
Maintainers usually reply within 1 day
-
P3
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
modelcontextprotocol/python-sdk#3597 · 1 comment ·
Maintainers usually reply within 1 day
-
v1 v2
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
modelcontextprotocol/python-sdk#3592 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day
All issues in modelcontextprotocol/python-sdk
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Task
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
war-and-code/dircue#200 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 87/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day