Skip to main content
Version: main 🚧

Contract: mcp_agent_auth Package

MCPAuthMiddleware

Package: mcp_agent_auth.middleware
Base class: starlette.middleware.base.BaseHTTPMiddleware

Constructor

MCPAuthMiddleware(app, public_paths: list[str] | None = None)
ParameterTypeDefaultDescription
appASGI apprequiredWrapped application
public_pathslist[str] | NoneNonePaths that bypass auth

Behavior by MCP_AUTH_MODE

ModeAuth checkOn successOn failure
noneNonePass throughN/A
shared_keyConstant-time compare Bearer <token> vs MCP_SHARED_KEYPass through401 JSON
oauth2Verify JWT via JWKS (iss, aud, exp, nbf, optional cid)Pass through401 JSON

Always bypass (all modes)

  • OPTIONS requests (CORS preflight)
  • Paths in public_paths

Error responses

// 401
{"error": "unauthorized", "reason": "<reason>"}

// For SSE clients (Accept: text/event-stream)
"error unauthorized: <reason>" // text/event-stream, 401

get_request_token

Package: mcp_agent_auth.token

def get_request_token(env_var_name: str) -> str | None:
ParameterTypeDescription
env_var_namestrFallback env var name (e.g., "ARGOCD_API_TOKEN")

Returns: Bearer token from current HTTP request's Authorization header if available, else os.getenv(env_var_name).

Raises: Nothing. Catches all exceptions from get_http_request() (STDIO mode, no context).

Token resolution order

  1. Authorization: Bearer <token> header of the current HTTP request
  2. os.getenv(env_var_name)
  3. None

Environment Variables

VariableRequiredModeDefaultDescription
MCP_AUTH_MODENoAllnoneAuth mode: none, shared_key, oauth2
MCP_SHARED_KEYYes (if shared_key)shared_keySecret for bearer token comparison
JWKS_URIYes (if oauth2)oauth2JWKS endpoint URL
AUDIENCEYes (if oauth2)oauth2Expected JWT aud claim
ISSUERYes (if oauth2)oauth2Expected JWT iss claim
OAUTH2_CLIENT_IDNooauth2Comma-separated allowed cid values
ALLOWED_ALGORITHMSNooauth2RS256,ES256Comma-separated JWT algorithms