0
# OAuth Authentication
1
2
Complete OAuth 2.0 authentication system designed for MCP compliance. FastAPI-MCP integrates seamlessly with FastAPI's dependency injection system while providing MCP-specific OAuth flows, proxy configurations, and dynamic client registration.
3
4
## Capabilities
5
6
### Authentication Configuration
7
8
Configure OAuth 2.0 authentication for MCP clients with extensive customization options.
9
10
```python { .api }
11
class AuthConfig:
12
version: Literal["2025-03-26"] = "2025-03-26"
13
dependencies: Sequence[params.Depends] = None
14
issuer: str = None
15
oauth_metadata_url: StrHttpUrl = None
16
authorize_url: StrHttpUrl = None
17
audience: str = None
18
default_scope: str = "openid profile email"
19
client_id: str = None
20
client_secret: str = None
21
custom_oauth_metadata: OAuthMetadataDict = None
22
setup_proxies: bool = False
23
setup_fake_dynamic_registration: bool = True
24
metadata_path: str = "/.well-known/oauth-authorization-server"
25
26
def __init__(self, **data):
27
"""
28
Configure OAuth 2.0 authentication for MCP.
29
30
Parameters:
31
- version: MCP spec version (currently only "2025-03-26" supported)
32
- dependencies: FastAPI dependencies for authentication/authorization checks
33
- issuer: OAuth 2.0 server issuer (required if custom_oauth_metadata not provided)
34
- oauth_metadata_url: Full URL of OAuth provider's metadata endpoint
35
- authorize_url: OAuth authorization endpoint URL
36
- audience: Default audience for OAuth requests (fallback when client doesn't specify)
37
- default_scope: Default OAuth scope (fallback when client doesn't specify)
38
- client_id: OAuth client ID (required if setup_proxies is True)
39
- client_secret: OAuth client secret (required if setup_fake_dynamic_registration is True)
40
- custom_oauth_metadata: Custom OAuth metadata to register
41
- setup_proxies: Whether to setup MCP-compliant OAuth proxies
42
- setup_fake_dynamic_registration: Whether to setup fake dynamic client registration
43
- metadata_path: Path to mount OAuth metadata endpoint
44
"""
45
```
46
47
#### Example Usage
48
49
```python
50
from fastapi import Depends, HTTPException, Request
51
from fastapi.security import HTTPBearer
52
from fastapi_mcp import FastApiMCP, AuthConfig
53
54
# Authentication dependency
55
security = HTTPBearer()
56
57
async def authenticate_request(request: Request, token: str = Depends(security)):
58
# Verify token logic here
59
if not verify_token(token.credentials):
60
raise HTTPException(status_code=401, detail="Unauthorized")
61
return {"user_id": "extracted_from_token"}
62
63
# Configure authentication
64
auth_config = AuthConfig(
65
dependencies=[Depends(authenticate_request)],
66
issuer="https://your-auth-provider.com",
67
client_id="your-client-id",
68
setup_proxies=True
69
)
70
71
mcp_server = FastApiMCP(
72
fastapi=app,
73
auth_config=auth_config
74
)
75
```
76
77
### OAuth Metadata
78
79
Define OAuth 2.0 server metadata according to RFC 8414 for MCP clients.
80
81
```python { .api }
82
class OAuthMetadata:
83
issuer: StrHttpUrl
84
authorization_endpoint: StrHttpUrl = None
85
token_endpoint: StrHttpUrl
86
scopes_supported: List[str] = ["openid", "profile", "email"]
87
response_types_supported: List[str] = ["code"]
88
grant_types_supported: List[str] = ["authorization_code", "client_credentials"]
89
token_endpoint_auth_methods_supported: List[str] = ["none"]
90
code_challenge_methods_supported: List[str] = ["S256"]
91
registration_endpoint: StrHttpUrl = None
92
93
def __init__(self, **data):
94
"""
95
OAuth 2.0 Server Metadata according to RFC 8414.
96
97
Parameters:
98
- issuer: Authorization server's issuer identifier (required)
99
- authorization_endpoint: Authorization endpoint URL (required for authorization_code grant)
100
- token_endpoint: Token endpoint URL (required)
101
- scopes_supported: List of supported OAuth scopes
102
- response_types_supported: List of supported response types
103
- grant_types_supported: List of supported grant types
104
- token_endpoint_auth_methods_supported: List of supported token endpoint auth methods
105
- code_challenge_methods_supported: List of supported PKCE code challenge methods
106
- registration_endpoint: Client registration endpoint URL (optional)
107
"""
108
109
def model_dump(self, **kwargs) -> Dict[str, Any]:
110
"""
111
Serialize to dictionary with OAuth-specific defaults.
112
Always excludes unset and None fields for client compatibility.
113
"""
114
```
115
116
#### Example Usage
117
118
```python
119
from fastapi_mcp import AuthConfig, OAuthMetadata
120
121
# Custom OAuth metadata
122
oauth_metadata = OAuthMetadata(
123
issuer="https://api.example.com",
124
authorization_endpoint="https://auth.example.com/oauth/authorize",
125
token_endpoint="https://auth.example.com/oauth/token",
126
scopes_supported=["read", "write", "admin"],
127
grant_types_supported=["authorization_code", "client_credentials"],
128
registration_endpoint="https://auth.example.com/oauth/register"
129
)
130
131
auth_config = AuthConfig(
132
custom_oauth_metadata=oauth_metadata,
133
dependencies=[Depends(authenticate_request)]
134
)
135
```
136
137
### Client Registration Models
138
139
Models for OAuth 2.0 dynamic client registration (RFC 7591).
140
141
```python { .api }
142
class ClientRegistrationRequest:
143
redirect_uris: List[str]
144
client_name: Optional[str] = None
145
grant_types: Optional[List[str]] = ["authorization_code"]
146
token_endpoint_auth_method: Optional[str] = "none"
147
148
def __init__(self, **data):
149
"""
150
OAuth 2.0 dynamic client registration request.
151
152
Parameters:
153
- redirect_uris: List of redirect URIs for the client
154
- client_name: Human-readable client name
155
- grant_types: List of OAuth grant types the client will use
156
- token_endpoint_auth_method: Authentication method for token endpoint
157
"""
158
159
class ClientRegistrationResponse:
160
client_id: str
161
client_id_issued_at: int
162
client_secret: Optional[str] = None
163
client_secret_expires_at: int = 0
164
redirect_uris: List[str]
165
grant_types: List[str]
166
token_endpoint_auth_method: str
167
client_name: str
168
169
def __init__(self, **data):
170
"""
171
OAuth 2.0 dynamic client registration response.
172
173
Parameters:
174
- client_id: Generated client identifier
175
- client_id_issued_at: Time when client_id was issued (Unix timestamp)
176
- client_secret: Client secret (if applicable)
177
- client_secret_expires_at: Client secret expiration time (0 = never expires)
178
- redirect_uris: Registered redirect URIs
179
- grant_types: Registered grant types
180
- token_endpoint_auth_method: Token endpoint authentication method
181
- client_name: Human-readable client name
182
"""
183
```
184
185
## Authentication Patterns
186
187
### FastAPI Dependencies Integration
188
189
Seamlessly integrate with existing FastAPI authentication systems:
190
191
```python
192
from fastapi import Depends, HTTPException
193
from fastapi.security import OAuth2PasswordBearer
194
from jose import JWTError, jwt
195
196
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
197
198
async def get_current_user(token: str = Depends(oauth2_scheme)):
199
try:
200
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
201
username: str = payload.get("sub")
202
if username is None:
203
raise HTTPException(status_code=401, detail="Invalid token")
204
return {"username": username}
205
except JWTError:
206
raise HTTPException(status_code=401, detail="Invalid token")
207
208
# Use with MCP
209
auth_config = AuthConfig(
210
dependencies=[Depends(get_current_user)],
211
issuer="https://your-app.com",
212
client_id="mcp-client"
213
)
214
```
215
216
### Custom OAuth Provider
217
218
Configure for external OAuth providers like Auth0, Okta, or custom solutions:
219
220
```python
221
# Auth0 configuration
222
auth_config = AuthConfig(
223
issuer="https://your-tenant.auth0.com",
224
oauth_metadata_url="https://your-tenant.auth0.com/.well-known/openid_configuration",
225
authorize_url="https://your-tenant.auth0.com/authorize",
226
client_id="your-auth0-client-id",
227
audience="https://your-api.com",
228
setup_proxies=True
229
)
230
231
# Okta configuration
232
auth_config = AuthConfig(
233
issuer="https://your-org.okta.com/oauth2/default",
234
client_id="your-okta-client-id",
235
setup_proxies=True,
236
default_scope="openid profile email api:read"
237
)
238
```
239
240
### MCP-Compliant Proxies
241
242
Automatically setup MCP-compliant proxy endpoints around existing OAuth providers:
243
244
```python
245
auth_config = AuthConfig(
246
issuer="https://external-oauth-provider.com",
247
client_id="your-client-id",
248
client_secret="your-client-secret",
249
setup_proxies=True, # Creates MCP-compliant proxy endpoints
250
setup_fake_dynamic_registration=True # Adds dynamic client registration
251
)
252
253
# This automatically creates:
254
# GET /.well-known/oauth-authorization-server - OAuth metadata
255
# GET /oauth/authorize - Authorization proxy
256
# POST /oauth/register - Dynamic client registration (fake)
257
```
258
259
### No Authentication Setup
260
261
For development or internal use without authentication:
262
263
```python
264
# No authentication required
265
mcp_server = FastApiMCP(fastapi=app) # No auth_config
266
267
# Or with custom metadata but no auth checks
268
auth_config = AuthConfig(
269
custom_oauth_metadata=OAuthMetadata(
270
issuer="https://api.example.com",
271
token_endpoint="https://api.example.com/token"
272
)
273
# No dependencies specified
274
)
275
```
276
277
## Advanced Authentication
278
279
### Multi-Provider Support
280
281
Support multiple OAuth providers by configuring different auth configs for different routes:
282
283
```python
284
# Different auth configs for different API versions
285
v1_auth = AuthConfig(
286
issuer="https://legacy-auth.com",
287
client_id="legacy-client"
288
)
289
290
v2_auth = AuthConfig(
291
issuer="https://new-auth.com",
292
client_id="new-client",
293
setup_proxies=True
294
)
295
296
# Mount different MCP servers with different auth
297
v1_mcp = FastApiMCP(app, auth_config=v1_auth)
298
v1_mcp.mount_http(mount_path="/mcp/v1")
299
300
v2_mcp = FastApiMCP(app, auth_config=v2_auth)
301
v2_mcp.mount_http(mount_path="/mcp/v2")
302
```
303
304
### Custom Header Forwarding
305
306
Forward specific authentication headers from MCP clients to API endpoints:
307
308
```python
309
auth_config = AuthConfig(
310
dependencies=[Depends(api_key_auth)],
311
# ... other config
312
)
313
314
mcp_server = FastApiMCP(
315
fastapi=app,
316
auth_config=auth_config,
317
headers=["authorization", "x-api-key", "x-tenant-id"] # Forward these headers
318
)
319
```