Responses¶
RFC 6749 OAuth error response helpers. Each function returns a Starlette
JSONResponse with the appropriate status code and a Cache-Control: no-store
header.
responses
¶
OAuth error response helpers for MCP Auth server.
This module provides standardized error response functions following OAuth 2.0 error response format (RFC 6749).
oauth_error
¶
oauth_error(
error: str,
description: str,
status_code: int = 400,
extra_headers: dict[str, str] | None = None,
) -> JSONResponse
Create a standard OAuth error response.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
error
|
str
|
OAuth error code (e.g., "invalid_request", "server_error") |
required |
description
|
str
|
Human-readable error description |
required |
status_code
|
int
|
HTTP status code (default 400) |
400
|
extra_headers
|
dict[str, str] | None
|
Additional headers to include (e.g., Retry-After) |
None
|
Returns:
| Type | Description |
|---|---|
JSONResponse
|
JSONResponse with OAuth error format |
Source code in mcp_authflow/responses.py
invalid_request
¶
Create an invalid_request error response (400).
Use for: missing required parameters, invalid parameter format.
invalid_client
¶
Create an invalid_client error response (401).
Use for: client authentication failed, unknown client.
slow_down
¶
Create a slow_down error response (400, RFC 8628 §3.5).
Use for: rate limiting during device flow polling.
The status code is always 400, like the other device-flow polling errors —
RFC 8628 §3.5 defines slow_down as a token-endpoint error response, so
it uses the RFC 6749 §5.2 status. For a generic 429 on a non-polling
endpoint use :func:rate_limit_exceeded instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
description
|
str
|
Error description |
required |
retry_after
|
int | None
|
Optional retry-after value in seconds |
None
|
Source code in mcp_authflow/responses.py
rate_limit_exceeded
¶
Create a rate limit exceeded error response (429).
Use for: too many requests to a generic endpoint (registration, introspection, etc.).
Emits the too_many_requests error code so it does not collide with the
device-flow polling signal produced by :func:slow_down. RFC 8628 §3.5
reserves slow_down specifically for device-flow token polling, so a
generic 429 must use a distinct code to avoid pushing clients into
device-flow backoff.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
description
|
str
|
Error description |
required |
retry_after
|
int | None
|
Optional retry-after value in seconds |
None
|
Source code in mcp_authflow/responses.py
server_error
¶
Create a server_error response.
Use for: internal server errors, backend failures.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
description
|
str
|
Error description |
required |
status_code
|
int
|
HTTP status code (500, 502, 504, etc.) |
500
|
Source code in mcp_authflow/responses.py
backend_timeout
¶
backend_connection_error
¶
backend_invalid_response
¶
invalid_grant
¶
Create an invalid_grant error response (400).
Use for: invalid or expired authorization codes, refresh tokens, or device codes.
Source code in mcp_authflow/responses.py
invalid_scope
¶
Create an invalid_scope error response (400).
Use for: requested scope is invalid, unknown, or exceeds what was granted.
unsupported_grant_type
¶
Create an unsupported_grant_type error response (400, RFC 6749 §5.2).
Use for: token endpoint received a grant_type the AS does not support.
Source code in mcp_authflow/responses.py
access_denied
¶
Create an access_denied error response (400, RFC 6749 §4.1.2.1 / §5.2).
Use for: resource owner or AS denied the request (e.g., user declined
consent at the /authorize step, or device flow authorize_device
was called with action=deny).
Source code in mcp_authflow/responses.py
invalid_redirect_uri
¶
Create an invalid_redirect_uri error response (400, RFC 7591 §3.2.2).
Use for: registration or authorization request supplied a redirect_uri that is not allowed for the client.
Source code in mcp_authflow/responses.py
authorization_pending
¶
Create an authorization_pending error response (400, RFC 8628 §3.5).
Use for: device flow token polling while the user has not yet completed
authorization. Clients should continue polling at the configured
interval.
Source code in mcp_authflow/responses.py
expired_token
¶
Create an expired_token error response (400, RFC 8628 §3.5).
Use for: device flow token polling after the device_code has expired.
Source code in mcp_authflow/responses.py
pkce_required
¶
Create an invalid_request error indicating PKCE is required (400).
Public clients (no client_secret) MUST use PKCE per OAuth 2.1 / RFC 9700.
This returns the standard invalid_request OAuth error code with a
description that calls out the missing PKCE binding.
Source code in mcp_authflow/responses.py
backend_oauth_error
¶
Create a JSONResponse from an already-formatted OAuth error dict.
Use for: forwarding transformed backend errors that are already in {"error": "...", "error_description": "..."} format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
error_dict
|
dict[str, str]
|
Dict with "error" and "error_description" keys |
required |
status_code
|
int
|
HTTP status code from the backend response |
required |
Returns:
| Type | Description |
|---|---|
JSONResponse
|
JSONResponse with Cache-Control: no-store header |