-
Couldn't load subscription status.
- Fork 2.7k
Description
Initial Checks
- I confirm that I'm using the latest version of MCP Python SDK
- I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this issue
Description
The OAuth token endpoint (/token) returns unauthorized_client error when client authentication fails, but RFC 6749 specifies this should be invalid_client.
Current Behavior
When a client fails authentication at the token endpoint (wrong credentials, unknown client_id, missing client_secret), the endpoint returns:
{
"error": "unauthorized_client",
"error_description": "Invalid client_id"
}Expected Behavior
According to RFC 6749 Section 5.2, client authentication failures should return invalid_client:
{
"error": "invalid_client",
"error_description": "Invalid client_id"
}RFC 6749 Section 5.2 defines two distinct error codes with specific meanings:
| Error Code | When to Use |
|---|---|
invalid_client |
Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). |
unauthorized_client |
The authenticated client is not authorized to use this authorization grant type. |
The key distinction:
invalid_client= authentication failure (identity could not be verified)unauthorized_client= authorization failure (identity verified, but not permitted to use the grant type)
The code catches AuthenticationError, which indicates the client failed to authenticate:
try:
client_info = await self.client_authenticator.authenticate(
client_id=token_request.client_id,
client_secret=token_request.client_secret,
)
except AuthenticationError as e: # Authentication failed
# Should return "invalid_client", not "unauthorized_client"RFC 6749 provides unsupported_grant_type as the specific error for grant type authorization failures, which is even more precise than unauthorized_client. The authorization check (which should use unauthorized_client) is correctly implemented later:
if token_request.grant_type not in client_info.grant_types:
return self.response(
TokenErrorResponse(
error="unsupported_grant_type", # Correct for this case
error_description=f"Unsupported grant type..."
)
)Proposed Fix
Change the error code from "unauthorized_client" to "invalid_client" in src/mcp/server/auth/handlers/token.py:
except AuthenticationError as e:
return self.response(
TokenErrorResponse(
error="invalid_client", # Correct per RFC 6749
error_description=e.message,
)
)Example Code
Python & MCP Python SDK
Python 3.12.4
mcp version: 1.17.0