Summary
mcp/server/auth/provider.py defines AuthorizationErrorCode as a Literal of seven OAuth 2.0 error codes but is missing "invalid_target", the error code defined by RFC 8707 §2 for resource-indicator mismatches. As a result, the auth-handler framework cannot return the correct error code when a downstream client sends an authorization request whose resource parameter doesn't match the protected resource, and any provider that raises AuthorizeError(error="invalid_target", …) triggers a pydantic ValidationError instead of an OAuth-compliant error response.
Current behaviour
In mcp/server/auth/provider.py:
AuthorizationErrorCode = Literal[
"invalid_request",
"unauthorized_client",
"access_denied",
"unsupported_response_type",
"invalid_scope",
"server_error",
"temporarily_unavailable",
]
AuthorizationErrorResponse.error is typed against this Literal, so when the authorize handler at mcp/server/auth/handlers/authorize.py:123 tries to build AuthorizationErrorResponse(error="invalid_target", …), pydantic rejects it:
pydantic_core._pydantic_core.ValidationError: 1 validation error for AuthorizationErrorResponse
error
Input should be 'invalid_request', 'unauthorized_client', 'access_denied', 'unsupported_response_type',
'invalid_scope', 'server_error' or 'temporarily_unavailable'
[type=literal_error, input_value='invalid_target', input_type=str]
That ValidationError propagates out of the framework's own except block and ultimately surfaces to the downstream client as a generic server_error instead of invalid_target, masking the real cause.
Where it surfaces today
FastMCP's OAuthProxy already raises AuthorizeError(error="invalid_target", …) for RFC 8707 resource-indicator mismatches, with # type: ignore[arg-type] annotations acknowledging the upstream-SDK gap (see fastmcp/server/auth/oauth_proxy/proxy.py:895-898):
raise AuthorizeError(
error="invalid_target", # type: ignore[arg-type] # ty:ignore[invalid-argument-type]
error_description="Resource does not match this server",
)
In practice this means any MCP proxy fronting multiple resources cannot return spec-compliant errors when a client's resource parameter doesn't match, and operators see misleading server_error responses in logs and clients see a generic OAuth error.
Proposed fix
Add "invalid_target" to AuthorizationErrorCode:
AuthorizationErrorCode = Literal[
"invalid_request",
"unauthorized_client",
"access_denied",
"unsupported_response_type",
"invalid_scope",
"server_error",
"temporarily_unavailable",
"invalid_target", # RFC 8707
]
No other changes required — AuthorizationErrorResponse and AuthorizeError already accept the Literal type by reference.
Environment
mcp 1.27.1
fastmcp 3.3.1
- Python 3.13
Happy to submit a PR if useful.
Summary
mcp/server/auth/provider.pydefinesAuthorizationErrorCodeas aLiteralof seven OAuth 2.0 error codes but is missing"invalid_target", the error code defined by RFC 8707 §2 for resource-indicator mismatches. As a result, the auth-handler framework cannot return the correct error code when a downstream client sends an authorization request whoseresourceparameter doesn't match the protected resource, and any provider that raisesAuthorizeError(error="invalid_target", …)triggers a pydanticValidationErrorinstead of an OAuth-compliant error response.Current behaviour
In
mcp/server/auth/provider.py:AuthorizationErrorResponse.erroris typed against this Literal, so when the authorize handler atmcp/server/auth/handlers/authorize.py:123tries to buildAuthorizationErrorResponse(error="invalid_target", …), pydantic rejects it:That
ValidationErrorpropagates out of the framework's ownexceptblock and ultimately surfaces to the downstream client as a genericserver_errorinstead ofinvalid_target, masking the real cause.Where it surfaces today
FastMCP's
OAuthProxyalready raisesAuthorizeError(error="invalid_target", …)for RFC 8707 resource-indicator mismatches, with# type: ignore[arg-type]annotations acknowledging the upstream-SDK gap (seefastmcp/server/auth/oauth_proxy/proxy.py:895-898):In practice this means any MCP proxy fronting multiple resources cannot return spec-compliant errors when a client's
resourceparameter doesn't match, and operators see misleadingserver_errorresponses in logs and clients see a generic OAuth error.Proposed fix
Add
"invalid_target"toAuthorizationErrorCode:No other changes required —
AuthorizationErrorResponseandAuthorizeErroralready accept the Literal type by reference.Environment
mcp1.27.1fastmcp3.3.1Happy to submit a PR if useful.