Summary
The MCP server currently has no authentication or authorization when using streamable-http transport. The README explicitly warns against using it for this reason. The MCP Python SDK (v1.23+) now includes built-in OAuth 2.1 Resource Server support following the MCP authorization specification and RFC 9728 (Protected Resource Metadata). We should leverage this to secure the HTTP transport.
Motivation
- The
streamable-http transport exposes the server over the network but has zero access control today
- Remote/multi-user deployments (e.g., behind an API gateway, in a container, via AgentCore) need authentication
- The MCP spec recommends OAuth 2.1 for HTTP transports, and the SDK we already depend on provides the plumbing
Proposed Approach
The MCP Python SDK provides a TokenVerifier protocol and AuthSettings configuration that integrate directly with FastMCP. The server would act as an OAuth 2.1 Resource Server (RS), validating bearer tokens issued by an external Authorization Server (AS).
Core changes:
- Implement
TokenVerifier (from mcp.server.auth.provider) to validate incoming bearer tokens — either via JWT signature verification or token introspection
- Add
AuthSettings (from mcp.server.auth.settings) to configure issuer URL, resource server URL, and required scopes
- Add configuration options to
Config class:
OSCAL_AUTH_ISSUER_URL — Authorization Server issuer URL
OSCAL_AUTH_RESOURCE_SERVER_URL — this server's public URL
OSCAL_AUTH_REQUIRED_SCOPES — comma-separated list of required OAuth scopes
- CLI args:
--auth-issuer-url, --auth-resource-server-url, --auth-required-scopes
- Conditionally enable auth only when transport is
streamable-http and an issuer URL is configured (stdio remains unaffected)
- Add a dependency for JWT validation (e.g.,
authlib or python-jose[cryptography])
Example integration in main.py:
from mcp.server.auth.provider import AccessToken, TokenVerifier
from mcp.server.auth.settings import AuthSettings
mcp = FastMCP(
config.server_name,
token_verifier=OscalTokenVerifier(...),
auth=AuthSettings(
issuer_url=config.auth_issuer_url,
resource_server_url=config.auth_resource_server_url,
required_scopes=config.auth_required_scopes,
),
)
Scope
Out of Scope (for now)
- Built-in Authorization Server — users bring their own AS (Cognito, Auth0, Keycloak, etc.)
- Per-tool authorization / fine-grained scopes
- TLS termination (assumed to be handled by a reverse proxy or load balancer)
References
Summary
The MCP server currently has no authentication or authorization when using
streamable-httptransport. The README explicitly warns against using it for this reason. The MCP Python SDK (v1.23+) now includes built-in OAuth 2.1 Resource Server support following the MCP authorization specification and RFC 9728 (Protected Resource Metadata). We should leverage this to secure the HTTP transport.Motivation
streamable-httptransport exposes the server over the network but has zero access control todayProposed Approach
The MCP Python SDK provides a
TokenVerifierprotocol andAuthSettingsconfiguration that integrate directly withFastMCP. The server would act as an OAuth 2.1 Resource Server (RS), validating bearer tokens issued by an external Authorization Server (AS).Core changes:
TokenVerifier(frommcp.server.auth.provider) to validate incoming bearer tokens — either via JWT signature verification or token introspectionAuthSettings(frommcp.server.auth.settings) to configure issuer URL, resource server URL, and required scopesConfigclass:OSCAL_AUTH_ISSUER_URL— Authorization Server issuer URLOSCAL_AUTH_RESOURCE_SERVER_URL— this server's public URLOSCAL_AUTH_REQUIRED_SCOPES— comma-separated list of required OAuth scopes--auth-issuer-url,--auth-resource-server-url,--auth-required-scopesstreamable-httpand an issuer URL is configured (stdio remains unaffected)authliborpython-jose[cryptography])Example integration in
main.py:Scope
TokenVerifierimplementation with JWT validationstreamable-httpwith issuer configured)dotenv.examplewith new env varsOut of Scope (for now)
References