Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
"icon": "stars",
"pages": [
"servers/tasks",
"servers/dependency-injection",
"servers/elicitation",
"servers/icons",
"servers/lifespan",
Expand Down
230 changes: 2 additions & 228 deletions docs/servers/context.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { VersionBadge } from '/snippets/version-badge.mdx'
When defining FastMCP [tools](/servers/tools), [resources](/servers/resources), resource templates, or [prompts](/servers/prompts), your functions might need to interact with the underlying MCP session or access advanced server capabilities. FastMCP provides the `Context` object for this purpose.

<Note>
FastMCP uses [Docket](https://github.com/chrisguidry/docket)'s dependency injection system for managing runtime dependencies. This page covers Context and the built-in dependencies; see [Custom Dependencies](#custom-dependencies) for creating your own.
You access Context through FastMCP's dependency injection system. For other injectable values like HTTP requests, access tokens, and custom dependencies, see [Dependency Injection](/servers/dependency-injection).
</Note>
Comment thread
coderabbitai[bot] marked this conversation as resolved.

## What Is Context?
Expand Down Expand Up @@ -388,7 +388,7 @@ async def session_info(ctx: Context) -> dict:
}
```

For HTTP request access that works regardless of MCP session availability (when using HTTP transports), use the [HTTP request helpers](#http-requests) like `get_http_request()` and `get_http_headers()`.
For HTTP request access that works regardless of MCP session availability (when using HTTP transports), use the [HTTP request helpers](/servers/dependency-injection#http-request) like `get_http_request()` and `get_http_headers()`.

#### Client Metadata

Expand Down Expand Up @@ -423,229 +423,3 @@ def send_email(to: str, subject: str, body: str, ctx: Context) -> str:
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>

## 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}",
}
```

## Custom Dependencies

<VersionBadge version="2.14" />

FastMCP's dependency injection is powered by [Docket](https://github.com/chrisguidry/docket), which provides a flexible system for injecting values into your functions. Beyond the built-in dependencies like `CurrentContext()`, you can create your own.

### Using `Depends()`

The simplest way to create a custom dependency is with `Depends()`. Pass any callable (sync or async function, or async context manager) and its return value will be injected:

```python
from contextlib import asynccontextmanager
from fastmcp import FastMCP
from fastmcp.dependencies import Depends

mcp = FastMCP(name="Custom Deps Demo")

# Simple function dependency
def get_config() -> dict:
return {"api_url": "https://api.example.com", "timeout": 30}

# Async function dependency
async def get_user_id() -> int:
return 42

@mcp.tool
async def fetch_data(
query: str,
config: dict = Depends(get_config),
user_id: int = Depends(get_user_id),
) -> str:
return f"User {user_id} fetching '{query}' from {config['api_url']}"
```

Dependencies using `Depends()` are automatically excluded from the MCP schema—clients never see them as parameters.

### Resource Management with Context Managers

For dependencies that need cleanup (database connections, file handles, etc.), use an async context manager:

```python
from contextlib import asynccontextmanager
from fastmcp import FastMCP
from fastmcp.dependencies import Depends

mcp = FastMCP(name="Resource Demo")

@asynccontextmanager
async def get_database():
db = await connect_to_database()
try:
yield db
finally:
await db.close()

@mcp.tool
async def query_users(sql: str, db = Depends(get_database)) -> list:
return await db.execute(sql)
```

The context manager's cleanup code runs after your function completes, even if an error occurs.

### Nested Dependencies

Dependencies can depend on other dependencies:

```python
from fastmcp import FastMCP
from fastmcp.dependencies import Depends

mcp = FastMCP(name="Nested Demo")

def get_base_url() -> str:
return "https://api.example.com"

def get_api_client(base_url: str = Depends(get_base_url)) -> dict:
return {"base_url": base_url, "version": "v1"}

@mcp.tool
async def call_api(endpoint: str, client: dict = Depends(get_api_client)) -> str:
return f"Calling {client['base_url']}/{client['version']}/{endpoint}"
```

### Advanced: Subclassing `Dependency`

For more complex dependency patterns—like dependencies that need access to Docket's execution context or require custom lifecycle management—you can subclass Docket's `Dependency` class. See the [Docket documentation on dependencies](https://chrisguidry.github.io/docket/dependencies/) for details.
Loading
Loading