mcp_auth_server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp_auth_serverrun the OAuth 2.1 + CIMD demo"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp_auth_server
A local, runnable proof of concept of the MCP Authorization spec (2025-11-25).
It demonstrates, end to end:
an MCP server acting as a proper OAuth 2.1 resource server — publishes RFC 9728 Protected Resource Metadata, validates audience-bound access tokens, and enforces scope on a protected tool;
a one-command MCP client that discovers the authorization server, registers via Client ID Metadata Documents (CIMD), runs the full OAuth 2.1 + PKCE handshake (including a step-up re-authorization), and calls the protected tool;
a minimal custom OAuth 2.1 authorization server behind the MCP server.
Why a custom authorization server?
CIMD is draft-ietf-oauth-client-id-metadata-document-00. No off-the-shelf OSS or SaaS
authorization server supports it yet, so using one would still require writing a CIMD shim.
A small custom AS gives full, correct CIMD support and lets the whole thing run locally as a
single command.
Related MCP server: MCP Server OAuth Toy
Quick start
uv venv && uv pip install -e ".[dev]" # one-time setup
./scripts/run.sh # or: uv run python -m mcp_auth.demorun.sh starts the authorization server and the resource server, then runs the client, which
prints a step-by-step trace of the handshake and the protected tool's result, e.g.:
[1] Discovery
401 challenge -> resource_metadata=...
PRM: resource=http://localhost:8001/mcp as=['http://localhost:9000/'] scopes=['mcp:connect']
AS metadata discovered at http://localhost:9000/.well-known/oauth-authorization-server
[2] Authorization (CIMD + PKCE) for base scope
[3] Call unprotected tool 'whoami'
[4] Call protected tool 'get_weather' (expect insufficient scope)
[5] Step-up re-authorization for the extra scope
[6] Retry 'get_weather' with stepped-up token
=== Success: full CIMD + OAuth 2.1 + step-up flow completed ===Architecture
src/mcp_auth/
config.py shared ports, URLs, scopes, token TTL
keys.py authorization-server RSA signing key + JWKS export
auth_server/ custom OAuth 2.1 authorization server (Starlette)
app.py AS metadata, /authorize, /token, /jwks
cimd.py fetch + validate Client ID Metadata Documents
store.py single-use authorization-code store
tokens.py RS256 JWT minting (aud=resource) + PKCE S256 verify
resource_server/ FastMCP server as an OAuth 2.1 resource server
server.py FastMCP app + whoami + protected get_weather tool
verifier.py JWT verifier: signature, issuer, expiry, audience
client/ one-command CIMD-driven MCP client
metadata.py the client's CIMD document + a server that hosts it
flow.py 401 -> PRM -> AS discovery -> PKCE authorize -> token
run.py full journey incl. step-up
demo.py orchestrator (single command)Default ports: authorization server :9000, resource server :8001, client CIMD host
:3000. The canonical resource URI (the token audience) is http://localhost:8001/mcp.
How the flow maps to the spec
Spec requirement | Where |
RFC 9728 Protected Resource Metadata | FastMCP, auto-served at |
| FastMCP |
RFC 8414 AS metadata incl. |
|
CIMD: fetch client doc, validate |
|
Authorization code + PKCE |
|
RFC 8707 |
|
Audience-bound tokens; resource server validates |
|
Scope enforcement + |
|
Tests
uv run pytestCovers AS/PRM metadata shape, CIMD validation (mismatched client_id, unlisted redirect URI,
missing fields, SSRF host), PKCE and token claims, audience/expiry rejection in the verifier,
and a full single-command end-to-end run.
Deliberate deviations from the spec (because this is a local PoC)
These are the conscious trade-offs that let the PoC run fully locally with one command. Each would be tightened for a real deployment:
HTTP on
localhostinstead of HTTPS. The spec mandates HTTPS for AS endpoints and the CIMDclient_idURL; localhost redirect URIs are already spec-permitted. The MCP SDK'sAnyHttpUrlacceptshttp, so no patching is needed.Headless auto-approved consent. The AS authenticates a fixed demo subject and issues a code without a browser prompt, so the client reads the redirect directly (no callback listener). A real AS would authenticate the user and show a consent screen.
In-memory, process-local state (signing key, authorization codes). No persistence, no refresh-token rotation.
SSRF guard is a localhost allowlist for CIMD fetches, sufficient for local use; a real AS needs a stricter trust policy per the CIMD draft's security considerations.
Out of scope
infra/terraform/(anticipated by.gitignore) — a local PoC needs no cloud infra.Multi-user login UI, Dynamic Client Registration (CIMD is used instead), persistent storage.
This server cannot be deployed
Maintenance
Related MCP Connectors
- StytchOAuthdev.stytch.mcp
The Stytch MCP server is a reference implementation that demonstrates remote MCP server authentication and authorization using Stytch Connected Apps. It provides OAuth 2.1-compliant authorization (including PKCE), Dynamic Client Registration, and validates Stytch-issued access tokens to enable AI agents to securely interact with external services through permissioned access, supporting scopes like openid, email, profile, and manage:project_data.
Self-hosted federated MCP gateway: one OAuth 2.1 MCP server in front of N apps, user-level scopes.
MCP server for verifying EUDI/Talao wallet data via OIDC4VP (pull) for AI agents.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA remote MCP server implementation that demonstrates authentication and authorization capabilities using OAuth 2.1. This is a workshop project for learning how to build secure MCP servers with user authentication.18,182 npmMIT
- FlicenseNot gradedqualityDmaintenanceA simple MCP server with OAuth 2.0 authentication for testing OAuth support in mcp-cli.-
- AlicenseNot gradedqualityCmaintenanceA demo MCP server protected by OAuth (DCR), enabling hands-on exploration of OAuth flow for local MCP servers.MIT
- FlicenseNot gradedqualityCmaintenanceAn MCP authorization server implementing OAuth2/OIDC flows, supporting dynamic client registration, PKCE, consent screens, and client ID metadata documents for MCP authorization.-