Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
d9d76cf
feat(auth): multi-protocol auth stage 1 — models, protocol interfaces…
nypdmax Jan 27, 2026
1334eef
Add AuthProtocolRegistry for multi-protocol auth selection
nypdmax Jan 28, 2026
d49e295
Add discover_authorization_servers with PRM fallback and type fixes
nypdmax Jan 28, 2026
d068465
Add MultiProtocolAuthProvider core for multi-protocol auth
nypdmax Jan 28, 2026
2574853
Add 401/403 handling skeleton to MultiProtocolAuthProvider
nypdmax Jan 28, 2026
5d80e84
Add _discover_and_authenticate full logic and storage adapter to Mult…
nypdmax Jan 28, 2026
6d5b6e2
Add CredentialVerifier and OAuthTokenVerifier with unit tests
nypdmax Jan 28, 2026
ce2deee
API Key verifier: prefer X-API-Key, optional Bearer; drop ApiKey scheme
nypdmax Jan 29, 2026
e6893a4
Extend create_protected_resource_routes with auth_protocols, default_…
nypdmax Jan 29, 2026
b7b04d9
Add AuthorizationServersDiscoveryHandler and create_authorization_ser…
nypdmax Jan 29, 2026
ed8a520
Add Phase 2 auth integration test and client auth protocol module
nypdmax Jan 29, 2026
995a1b1
Add Phase 1 OAuth2 integration test script and regression test plan
nypdmax Jan 29, 2026
1a37dd8
Add simple-auth-multiprotocol server example (OAuth, API Key, mTLS pl…
nypdmax Jan 29, 2026
139d652
feat(examples): add simple-auth-multiprotocol-client and Pyright conf…
nypdmax Jan 29, 2026
3d22414
fix(auth): API Key scope for RequireAuthMiddleware; add phase2 multip…
nypdmax Jan 29, 2026
9f3c7c3
feat(auth): add OAuth2Protocol thin adapter and run_authentication, a…
nypdmax Jan 29, 2026
d87e8cc
feat(auth): implement OAuth2Protocol.discover_metadata (RFC 8414), ad…
nypdmax Jan 29, 2026
dae53d7
test(auth): add run_authentication unit tests with mock HTTP
nypdmax Jan 29, 2026
f84fe64
feat(auth): implement DPoP client (RFC 9449) with key pair, proof gen…
nypdmax Jan 31, 2026
e83e975
feat(auth): implement DPoP server-side verification (RFC 9449)
nypdmax Jan 31, 2026
44901e1
feat(auth): integrate DPoP into OAuth2Protocol and credential verifiers
nypdmax Jan 31, 2026
07ac1f8
feat(auth): add DPoP support to simple-auth-multiprotocol example
nypdmax Jan 31, 2026
3a3d914
Add DPoP integration test script and multiprotocol example updates
nypdmax Feb 1, 2026
cb5f638
Refactor OAuth 401/403 flow with shared generator to fix deadlock
nypdmax Feb 1, 2026
283a84e
chore(tests): move integration scripts to client example dir.
nypdmax Feb 2, 2026
4589cad
fix(server): handle session termination race in streamable HTTP
nypdmax Feb 2, 2026
e9338fc
fix(auth): fallback to injected protocols on 401
nypdmax Feb 4, 2026
571edfe
test(auth): cover protocol fallback and discovery leakage
nypdmax Feb 4, 2026
5d38e4b
chore(examples): harden multiprotocol client/script flows
nypdmax Feb 4, 2026
fbf9ad9
docs(auth): document TokenStorage dual contract, add OAuthTokenStorag…
nypdmax Jan 29, 2026
5129578
chore(repo): ignore local plans and cursorrules
nypdmax Feb 4, 2026
53b11f9
feat(auth): OAuth2 client_credentials grant and fixed_client_info
nypdmax Feb 5, 2026
1dda3cd
feat(examples): client_credentials in simple-auth, multiprotocol disc…
nypdmax Feb 5, 2026
8c1b060
refactor(auth): reduce async_auth_flow complexity, remove noqa
nypdmax Feb 6, 2026
de25956
fix(auth): restore multiprotocol provider after refactor
nypdmax Feb 6, 2026
24bd45b
fix(auth): pad EC P-256 JWK coordinates to fixed 32 bytes
nypdmax Feb 6, 2026
5cabe19
mcp supporting multi-authentication schemas DD
nypdmax Jan 29, 2026
6aa7e77
docs(auth): update auth-analysis and multi-protocol-refactoring-plan
nypdmax Jan 29, 2026
b68a193
Add API Key, DPoP, and Mutual TLS running instructions to multiprotoc…
nypdmax Feb 1, 2026
4445b51
Add authorization design docs (multi-protocol)
nypdmax Feb 1, 2026
b5e3172
Fix multi authentication schema design doc
nypdmax Feb 1, 2026
3159ef0
docs(auth): protocol discovery order and auth discovery logging
nypdmax Feb 4, 2026
9179e8f
docs(examples): rename MCP_AUTH_PROTOCOL and update guides
nypdmax Feb 4, 2026
01236d4
docs(auth): refresh multiprotocol and client_credentials documentation
nypdmax Feb 5, 2026
c3ca87c
chore(repo): align gitignore with main
nypdmax Feb 6, 2026
bcda500
chore(auth): drop internal design docs from src
nypdmax Feb 6, 2026
a3c84c4
refactor(server): simplify streamable HTTP request handling
nypdmax Feb 6, 2026
4b1846e
refactor(auth-server): tighten token handling and verifiers
nypdmax Feb 6, 2026
c51a103
chore(auth): translate comments and docstrings to English
nypdmax Feb 6, 2026
187c433
chore(dpop): tidy client implementation and tests
nypdmax Feb 6, 2026
de0241c
test(auth): tidy multiprotocol client test docs
nypdmax Feb 6, 2026
4348a2c
feat(server): add FastMCP compatibility wrapper for examples
nypdmax Feb 6, 2026
8855822
chore(examples): update multiprotocol auth examples
nypdmax Feb 6, 2026
1ad8c89
test(auth): wrap long oauth2 protocol docstring
nypdmax Feb 6, 2026
76b1d1e
docs: fix markdownlint in auth multiprotocol docs
nypdmax Feb 6, 2026
310d939
test(auth): add coverage tests to satisfy 100% gate
nypdmax Feb 6, 2026
ea5910d
fix(auth): remove unnecessary pragma no cover annotations
nypdmax Feb 6, 2026
87288eb
fix(auth): add lax no cover to Protocol stubs for Python 3.14 coverage
nypdmax Feb 6, 2026
9e1a9ab
docs: fix script cmds and unnecessary content
nypdmax Feb 6, 2026
ea9074c
chore: clean up legacy env var and echo in scripts
nypdmax Feb 6, 2026
4747253
refactor(examples): merge multiprotocol server variants into shared m…
nypdmax Feb 7, 2026
278752a
fix(auth): correct path-relative discovery URL and enforce strict dis…
nypdmax Feb 7, 2026
49da5e9
test(auth): update tests for strict discovery and path-relative URL fix
nypdmax Feb 7, 2026
27ce1a7
chore(examples): fix py.typed eof
nypdmax Feb 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
561 changes: 561 additions & 0 deletions docs/authorization-multiprotocol.md

Large diffs are not rendered by default.

15 changes: 13 additions & 2 deletions docs/authorization.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Authorization

!!! warning "Under Construction"
The MCP Python SDK supports **multi-protocol authorization**: OAuth 2.0, API Key, DPoP (Demonstrating Proof-of-Possession), and a Mutual TLS placeholder. Servers declare supported protocols via PRM (Protected Resource Metadata) and WWW-Authenticate; clients discover and select a protocol automatically.

This page is currently being written. Check back soon for complete documentation.
## Overview

- **OAuth 2.0**: Authorization code flow with PKCE; 401 → discovery → OAuth → token → MCP. Fully supported with `OAuthClientProvider` / `OAuth2Protocol`.
- **API Key**: Send `X-API-Key` (or `Authorization: Bearer <key>` when configured). No AS required. Use `MCP_API_KEY` on the client and `--api-keys` on the server.
- **DPoP** (RFC 9449): Binds the access token to a client-held key. Use with OAuth: client sets `MCP_USE_OAUTH=1` and `MCP_DPOP_ENABLED=1`; server starts with `--dpop-enabled`.
- **Mutual TLS**: Placeholder in the examples (no client certificate validation).

Examples: [simple-auth-multiprotocol](../examples/servers/simple-auth-multiprotocol/) (server), [simple-auth-multiprotocol-client](../examples/clients/simple-auth-multiprotocol-client/) (client). See [examples/README.md](../examples/README.md) for API Key, DPoP, and mTLS running instructions.

---

For protocol implementation, migration from OAuth-only to multi-protocol, DPoP usage, and API reference, see **[Authorization: Multi-Protocol Extension](authorization-multiprotocol.md)**.
22 changes: 21 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# Python SDK Examples

This folders aims to provide simple examples of using the Python SDK. Please refer to the
This folder aims to provide simple examples of using the Python SDK. Please refer to the
[servers repository](https://github.com/modelcontextprotocol/servers)
for real-world servers.

## Multi-protocol auth

- **Server**: [simple-auth-multiprotocol](servers/simple-auth-multiprotocol/) — RS with OAuth, API Key, DPoP, and Mutual TLS (placeholder).

### API Key

- Use `MCP_API_KEY` on the client; start RS with `--api-keys=...` (no AS required).
- One-command test (from repo root): `./examples/clients/simple-auth-multiprotocol-client/run_multiprotocol_test.sh`

### OAuth + DPoP

- Start AS and RS with `--dpop-enabled`; client: `MCP_USE_OAUTH=1 MCP_DPOP_ENABLED=1`.
- One-command test (from repo root): `./examples/clients/simple-auth-multiprotocol-client/run_dpop_test.sh` (use `MCP_SKIP_OAUTH=1` to skip manual OAuth step).

### Mutual TLS (placeholder)

- mTLS is a placeholder (no client cert validation). Script: `MCP_AUTH_PROTOCOL=mutual_tls ./examples/clients/simple-auth-multiprotocol-client/run_multiprotocol_test.sh`

**Client**: [simple-auth-multiprotocol-client](clients/simple-auth-multiprotocol-client/) — supports API Key (`MCP_API_KEY`), OAuth+DPoP (`MCP_USE_OAUTH=1`, `MCP_DPOP_ENABLED=1`), and mTLS placeholder.
63 changes: 63 additions & 0 deletions examples/clients/simple-auth-multiprotocol-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Simple Auth Multiprotocol Client

MCP client example using **MultiProtocolAuthProvider** with **API Key** and **Mutual TLS (placeholder)**.

- Uses `MultiProtocolAuthProvider` and protocol selection from server discovery (PRM / WWW-Authenticate).
- **API Key**: reads key from env `MCP_API_KEY` (default `demo-api-key-12345`), sends `X-API-Key` header.
- **Mutual TLS**: placeholder only; when selected, prints a message and exits (no client cert in this example).

## Run

1. Start the multi-protocol resource server (e.g. `simple-auth-multiprotocol` on port 8002).
2. From this directory: `uv run mcp-simple-auth-multiprotocol-client` or `uv run python -m mcp_simple_auth_multiprotocol_client`.
3. Optional: `MCP_SERVER_URL=http://localhost:8002/mcp` to override server URL.

## Running with API Key

When the server supports API Key (e.g. `simple-auth-multiprotocol` with `--api-keys`), set:

- **`MCP_API_KEY`** – your API key (e.g. `demo-api-key-12345`). The client sends it as `X-API-Key`.
- **`MCP_SERVER_URL`** – optional; default is `http://localhost:8002/mcp` when using the default client config.

Example (server on port 8002, no OAuth/AS required):

```bash
MCP_SERVER_URL=http://localhost:8002/mcp MCP_API_KEY=demo-api-key-12345 uv run mcp-simple-auth-multiprotocol-client
```

**One-command test** from repo root:
`./examples/clients/simple-auth-multiprotocol-client/run_multiprotocol_test.sh`
starts the resource server and this client with API Key; at `mcp>` run `list`, `call get_time {}`, `quit`.

## Running with OAuth + DPoP

When the server has DPoP enabled (`--dpop-enabled`), use OAuth and DPoP together:

- **`MCP_USE_OAUTH=1`** – enable OAuth (required for DPoP).
- **`MCP_DPOP_ENABLED=1`** – send DPoP-bound access tokens (DPoP proof in each request).

Example (server on port 8002 with DPoP, AS on 9000):

```bash
MCP_SERVER_URL=http://localhost:8002/mcp MCP_USE_OAUTH=1 MCP_DPOP_ENABLED=1 uv run mcp-simple-auth-multiprotocol-client
```

Complete OAuth in the browser; then at `mcp>` run `list`, `call get_time {}`, `quit`. Server logs should show "Authentication successful with DPoP".

**One-command test** from repo root:
`./examples/clients/simple-auth-multiprotocol-client/run_dpop_test.sh` — starts AS and RS with DPoP, then runs this client (OAuth+DPoP). Use `MCP_SKIP_OAUTH=1` to run only the automated curl tests and skip the manual client step.

## Running with Mutual TLS (placeholder)

Mutual TLS is a **placeholder** in this example: the client registers the `mutual_tls` protocol but does **not** perform client certificate authentication. Selecting mTLS will show a "not implemented" style message.

- **`MCP_AUTH_PROTOCOL=mutual_tls`** runs this client in mTLS mode; the client will start but mTLS auth is not implemented.

**One-command test** from repo root:
`MCP_AUTH_PROTOCOL=mutual_tls ./examples/clients/simple-auth-multiprotocol-client/run_multiprotocol_test.sh`

## Commands

- `list` – list tools
- `call get_time` – call `get_time`
- `quit` – exit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Multi-protocol auth client example (API Key + mTLS placeholder)."""
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"""Run as python -m mcp_simple_auth_multiprotocol_client."""

from mcp_simple_auth_multiprotocol_client.main import cli

if __name__ == "__main__":
cli()
Loading
Loading