Skip to content

CORS

cors

CORS origin validation for MCP OAuth endpoints.

parse_allowed_origins

parse_allowed_origins(
    env_var: str = "ALLOWED_MCP_ORIGINS",
) -> list[str]

Parse allowed CORS origins from a comma-separated environment variable.

Parameters:

Name Type Description Default
env_var str

Name of the environment variable to read.

'ALLOWED_MCP_ORIGINS'

Returns:

Type Description
list[str]

List of allowed origin strings, stripped of whitespace.

Source code in mcp_authflow/cors.py
def parse_allowed_origins(env_var: str = "ALLOWED_MCP_ORIGINS") -> list[str]:
    """Parse allowed CORS origins from a comma-separated environment variable.

    Args:
        env_var: Name of the environment variable to read.

    Returns:
        List of allowed origin strings, stripped of whitespace.
    """
    raw = os.getenv(env_var, "")
    if not raw:
        return []
    return [origin.strip() for origin in raw.split(",") if origin.strip()]

get_cors_origin

get_cors_origin(
    request: Request, allowed_origins: list[str]
) -> str

Get CORS origin header value based on request origin.

Only returns the origin if it's in the allowed list, otherwise returns empty string to deny CORS access.

Parameters:

Name Type Description Default
request Request

The incoming request.

required
allowed_origins list[str]

List of allowed origin strings.

required

Returns:

Type Description
str

Origin value for Access-Control-Allow-Origin header.

Source code in mcp_authflow/cors.py
def get_cors_origin(request: Request, allowed_origins: list[str]) -> str:
    """Get CORS origin header value based on request origin.

    Only returns the origin if it's in the allowed list, otherwise returns
    empty string to deny CORS access.

    Args:
        request: The incoming request.
        allowed_origins: List of allowed origin strings.

    Returns:
        Origin value for Access-Control-Allow-Origin header.
    """
    request_origin = request.headers.get("origin", "")
    if request_origin in allowed_origins:
        return request_origin
    return ""

build_cors_headers

build_cors_headers(
    request: Request, allowed_origins: list[str]
) -> dict[str, str]

Build standard CORS headers for OAuth discovery endpoints.

Only includes Access-Control-Allow-Origin when the request origin is in the allowlist. Omits it entirely for disallowed origins per the CORS specification.

Parameters:

Name Type Description Default
request Request

The incoming request.

required
allowed_origins list[str]

List of allowed origin strings.

required

Returns:

Type Description
dict[str, str]

Dict of CORS headers.

Source code in mcp_authflow/cors.py
def build_cors_headers(request: Request, allowed_origins: list[str]) -> dict[str, str]:
    """Build standard CORS headers for OAuth discovery endpoints.

    Only includes Access-Control-Allow-Origin when the request origin is
    in the allowlist. Omits it entirely for disallowed origins per the
    CORS specification.

    Args:
        request: The incoming request.
        allowed_origins: List of allowed origin strings.

    Returns:
        Dict of CORS headers.
    """
    headers: dict[str, str] = {
        "Access-Control-Allow-Methods": "GET, OPTIONS",
        "Access-Control-Allow-Headers": "Authorization, Content-Type, Accept",
        # Access-Control-Allow-Origin is derived from the request Origin, so
        # caches must key on Origin to avoid serving a permissive ACAO header
        # generated for a trusted origin to a different, untrusted one
        # (Fetch spec requirement).
        "Vary": "Origin",
    }
    origin = get_cors_origin(request, allowed_origins)
    if origin:
        headers["Access-Control-Allow-Origin"] = origin
    return headers