modelcontextprotocol / modelcontextprotocol/python-sdk

Revocation requires client_secret to be present

未关闭 适合新手
#3,508 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

v1 v2
主要语言
Python
星标
24.3k
派生
4k
平均合并
1 天 1 小时
30 天内合并 PR
31

描述

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

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 src/mcp/server/auth/handlers/revoke.py 中的 RevocationRequest 开始,检查相关的验证行为。确认公共客户端的撤销请求可以省略 client_secret,然后使用仅包含 token 和 client_id 的 Pydantic 示例来验证验证是否成功。

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
authentication
Issue 类型
缺陷
难度
1/5
预计耗时
1 小时以内
活跃度
活跃
描述清晰度
描述清楚
新手友好度
91/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。