Auth Server
БесплатноНе проверенA proof-of-concept MCP server implementing OAuth 2.1 authorization with CIMD client registration and PKCE, demonstrating protected resource access and step-up a
Описание
A proof-of-concept MCP server implementing OAuth 2.1 authorization with CIMD client registration and PKCE, demonstrating protected resource access and step-up authentication.
README
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.
Quick start
uv venv && uv pip install -e ".[dev]" # one-time setup
./scripts/run.sh # or: uv run python -m mcp_auth.demo
run.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 /.well-known/oauth-protected-resource/mcp |
401 + WWW-Authenticate with resource_metadata |
FastMCP RequireAuthMiddleware |
RFC 8414 AS metadata incl. code_challenge_methods_supported, client_id_metadata_document_supported |
auth_server/app.py |
CIMD: fetch client doc, validate client_id == URL, validate redirect_uri |
auth_server/cimd.py |
Authorization code + PKCE S256 |
auth_server/app.py, client/flow.py |
RFC 8707 resource parameter in auth + token requests |
client/flow.py |
Audience-bound tokens; resource server validates aud |
auth_server/tokens.py, resource_server/verifier.py |
Scope enforcement + insufficient_scope + step-up |
resource_server/server.py, client/run.py |
Tests
uv run pytest
Covers 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.
Установить Auth Server в Claude Desktop, Claude Code, Cursor
unyly install mcp-auth-serverСтавит в Claude Desktop, Claude Code, Cursor и VS Code — сам разбирается с npx, uvx и сборкой из исходников.
Впервые? Поставь CLI: curl -fsSL https://unyly.org/install | sh
Или настроить вручную
Выполни в терминале:
claude mcp add mcp-auth-server -- uvx --from git+https://github.com/dawa/mcp_auth_server mcp-auth-serverFAQ
Auth Server MCP бесплатный?
Да, Auth Server MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Auth Server?
Нет, Auth Server работает без API-ключей и переменных окружения.
Auth Server — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Auth Server в Claude Desktop, Claude Code или Cursor?
Открой Auth Server на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
GitHub
PRs, issues, code search, CI status
автор: GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
автор: mcpdotdirectCompare Auth Server with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории development
