Add documentation for get_access_token() dependency function (#1446)

Co-authored-by: Jeremiah Lowin <jlowin@users.noreply.github.com>
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
This commit is contained in:
Jeremiah Lowin 2025-08-11 13:01:44 -04:00 committed by GitHub
commit c6768dad5f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 159 additions and 100 deletions

View file

@ -162,7 +162,6 @@
"pages": [
"patterns/tool-transformation",
"patterns/decorating-methods",
"patterns/http-requests",
"patterns/testing",
"patterns/cli",
"patterns/contrib"

View file

@ -1,87 +0,0 @@
---
title: HTTP Requests
sidebarTitle: HTTP Requests
description: Accessing and using HTTP requests in FastMCP servers
icon: network-wired
---
import { VersionBadge } from '/snippets/version-badge.mdx'
<VersionBadge version="2.2.11" />
## Overview
When running FastMCP as a web server, your MCP tools, resources, and prompts might need to access the underlying HTTP request information, such as headers, client IP, or query parameters.
FastMCP provides a clean way to access HTTP request information through a dependency function.
## Accessing HTTP Requests
The recommended way to access the current HTTP request is through the `get_http_request()` dependency function:
```python {2, 3, 11}
from fastmcp import FastMCP
from fastmcp.server.dependencies import get_http_request
from starlette.requests import Request
mcp = FastMCP(name="HTTP Request Demo")
@mcp.tool
async def user_agent_info() -> dict:
"""Return information about the user agent."""
# Get the HTTP request
request: Request = get_http_request()
# Access request data
user_agent = request.headers.get("user-agent", "Unknown")
client_ip = request.client.host if request.client else "Unknown"
return {
"user_agent": user_agent,
"client_ip": client_ip,
"path": request.url.path,
}
```
This approach works anywhere within a request's execution flow, not just within your MCP function. It's useful when:
1. You need access to HTTP information in helper functions
2. You're calling nested functions that need HTTP request data
3. You're working with middleware or other request processing code
## Accessing HTTP Headers Only
If you only need request headers and want to avoid potential errors, you can use the `get_http_headers()` helper:
```python {2}
from fastmcp import FastMCP
from fastmcp.server.dependencies import get_http_headers
mcp = FastMCP(name="Headers Demo")
@mcp.tool
async def safe_header_info() -> dict:
"""Safely get header information without raising errors."""
# Get headers (returns empty dict if no request context)
headers = get_http_headers()
# Get authorization header
auth_header = headers.get("authorization", "")
is_bearer = auth_header.startswith("Bearer ")
return {
"user_agent": headers.get("user-agent", "Unknown"),
"content_type": headers.get("content-type", "Unknown"),
"has_auth": bool(auth_header),
"auth_type": "Bearer" if is_bearer else "Other" if auth_header else "None",
"headers_count": len(headers)
}
```
By default, `get_http_headers()` excludes problematic headers like `host` and `content-length`. To include all headers, use `get_http_headers(include_all=True)`.
## Important Notes
- HTTP requests are only available when FastMCP is running as part of a web application
- Accessing the HTTP request with `get_http_request()` outside of a web request context will raise a `RuntimeError`
- The `get_http_headers()` function **never raises errors** - it returns an empty dict when no request context is available
- The `get_http_request()` function returns a standard [Starlette Request](https://www.starlette.io/requests/) object

View file

@ -89,7 +89,7 @@ async def data_analysis_request(dataset: str, ctx: Context) -> str:
```
### Via Dependency Function
### Via Runtime Dependency Function
<VersionBadge version="2.2.11" />
@ -285,4 +285,144 @@ async def request_info(ctx: Context) -> dict:
<Warning>
The MCP request is part of the low-level MCP SDK and intended for advanced use cases. Most users will not need to use it directly.
</Warning>
</Warning>
## Runtime Dependencies
### HTTP Requests
<VersionBadge version="2.2.11" />
The recommended way to access the current HTTP request is through the `get_http_request()` dependency function:
```python {2, 3, 11}
from fastmcp import FastMCP
from fastmcp.server.dependencies import get_http_request
from starlette.requests import Request
mcp = FastMCP(name="HTTP Request Demo")
@mcp.tool
async def user_agent_info() -> dict:
"""Return information about the user agent."""
# Get the HTTP request
request: Request = get_http_request()
# Access request data
user_agent = request.headers.get("user-agent", "Unknown")
client_ip = request.client.host if request.client else "Unknown"
return {
"user_agent": user_agent,
"client_ip": client_ip,
"path": request.url.path,
}
```
This approach works anywhere within a request's execution flow, not just within your MCP function. It's useful when:
1. You need access to HTTP information in helper functions
2. You're calling nested functions that need HTTP request data
3. You're working with middleware or other request processing code
### HTTP Headers
<VersionBadge version="2.2.11" />
If you only need request headers and want to avoid potential errors, you can use the `get_http_headers()` helper:
```python {2, 10}
from fastmcp import FastMCP
from fastmcp.server.dependencies import get_http_headers
mcp = FastMCP(name="Headers Demo")
@mcp.tool
async def safe_header_info() -> dict:
"""Safely get header information without raising errors."""
# Get headers (returns empty dict if no request context)
headers = get_http_headers()
# Get authorization header
auth_header = headers.get("authorization", "")
is_bearer = auth_header.startswith("Bearer ")
return {
"user_agent": headers.get("user-agent", "Unknown"),
"content_type": headers.get("content-type", "Unknown"),
"has_auth": bool(auth_header),
"auth_type": "Bearer" if is_bearer else "Other" if auth_header else "None",
"headers_count": len(headers)
}
```
By default, `get_http_headers()` excludes problematic headers like `host` and `content-length`. To include all headers, use `get_http_headers(include_all=True)`.
### Access Tokens
<VersionBadge version="2.11.0" />
When using authentication with your FastMCP server, you can access the authenticated user's access token information using the `get_access_token()` dependency function:
```python {2, 10}
from fastmcp import FastMCP
from fastmcp.server.dependencies import get_access_token, AccessToken
mcp = FastMCP(name="Auth Token Demo")
@mcp.tool
async def get_user_info() -> dict:
"""Get information about the authenticated user."""
# Get the access token (None if not authenticated)
token: AccessToken | None = get_access_token()
if token is None:
return {"authenticated": False}
return {
"authenticated": True,
"client_id": token.client_id,
"scopes": token.scopes,
"expires_at": token.expires_at,
"token_claims": token.claims, # JWT claims or custom token data
}
```
This is particularly useful when you need to:
1. **Access user identification** - Get the `client_id` or subject from token claims
2. **Check permissions** - Verify scopes or custom claims before performing operations
3. **Multi-tenant applications** - Extract tenant information from token claims
4. **Audit logging** - Track which user performed which actions
#### Working with Token Claims
The `claims` field contains all the data from the original token (JWT claims for JWT tokens, or custom data for other token types):
```python {2, 3, 9, 12, 15}
from fastmcp import FastMCP
from fastmcp.server.dependencies import get_access_token
mcp = FastMCP(name="Multi-tenant Demo")
@mcp.tool
async def get_tenant_data(resource_id: str) -> dict:
"""Get tenant-specific data using token claims."""
token: AccessToken | None = get_access_token()
# Extract tenant ID from token claims
tenant_id = token.claims.get("tenant_id") if token else None
# Extract user ID from standard JWT subject claim
user_id = token.claims.get("sub") if token else None
# Use tenant and user info to authorize and filter data
if not tenant_id:
raise ValueError("No tenant information in token")
return {
"resource_id": resource_id,
"tenant_id": tenant_id,
"user_id": user_id,
"data": f"Tenant-specific data for {tenant_id}",
}
```

View file

@ -1,13 +1,21 @@
from .auth import OAuthProvider, TokenVerifier, RemoteAuthProvider
from .auth import (
OAuthProvider,
TokenVerifier,
RemoteAuthProvider,
AccessToken,
AuthProvider,
)
from .providers.jwt import JWTVerifier, StaticTokenVerifier
__all__ = [
"AuthProvider",
"OAuthProvider",
"TokenVerifier",
"JWTVerifier",
"StaticTokenVerifier",
"RemoteAuthProvider",
"AccessToken",
]

View file

@ -15,8 +15,7 @@ from pydantic import AnyHttpUrl, SecretStr
from pydantic_settings import BaseSettings, SettingsConfigDict
from typing_extensions import TypedDict
from fastmcp.server.auth import TokenVerifier
from fastmcp.server.auth.auth import AccessToken
from fastmcp.server.auth import AccessToken, TokenVerifier
from fastmcp.server.auth.registry import register_provider
from fastmcp.utilities.logging import get_logger
from fastmcp.utilities.types import NotSet, NotSetT

View file

@ -6,7 +6,7 @@ from collections.abc import Callable
from typing import TYPE_CHECKING, TypeVar
if TYPE_CHECKING:
from fastmcp.server.auth.auth import AuthProvider
from fastmcp.server.auth import AuthProvider
# Type variable for auth providers
T = TypeVar("T", bound="AuthProvider")

View file

@ -7,7 +7,7 @@ from mcp.server.auth.middleware.auth_context import (
)
from starlette.requests import Request
from fastmcp.server.auth.auth import AccessToken
from fastmcp.server.auth import AccessToken
if TYPE_CHECKING:
from fastmcp.server.context import Context

View file

@ -23,7 +23,7 @@ from starlette.responses import Response
from starlette.routing import BaseRoute, Mount, Route
from starlette.types import Lifespan, Receive, Scope, Send
from fastmcp.server.auth.auth import AuthProvider
from fastmcp.server.auth import AuthProvider
from fastmcp.utilities.logging import get_logger
if TYPE_CHECKING:

View file

@ -49,7 +49,7 @@ from fastmcp.prompts import Prompt, PromptManager
from fastmcp.prompts.prompt import FunctionPrompt
from fastmcp.resources import Resource, ResourceManager
from fastmcp.resources.template import ResourceTemplate
from fastmcp.server.auth.auth import AuthProvider
from fastmcp.server.auth import AuthProvider
from fastmcp.server.auth.registry import get_registered_provider
from fastmcp.server.http import (
StarletteWithLifespan,

View file

@ -3,7 +3,7 @@ import pytest
from pydantic import AnyHttpUrl
from fastmcp import FastMCP
from fastmcp.server.auth.auth import AccessToken, RemoteAuthProvider, TokenVerifier
from fastmcp.server.auth import AccessToken, RemoteAuthProvider, TokenVerifier
class SimpleTokenVerifier(TokenVerifier):

View file

@ -3,7 +3,7 @@
import httpx
from fastmcp.server import FastMCP
from fastmcp.server.auth.auth import AccessToken
from fastmcp.server.auth import AccessToken
from fastmcp.server.auth.providers.jwt import StaticTokenVerifier

View file

@ -4,7 +4,7 @@ import pytest
from mcp.server.auth.middleware.bearer_auth import BearerAuthBackend
from starlette.requests import HTTPConnection
from fastmcp.server.auth.auth import AccessToken
from fastmcp.server.auth import AccessToken
from fastmcp.server.auth.providers.jwt import JWTVerifier, RSAKeyPair