Update docs for context

This commit is contained in:
Jeremiah Lowin 2025-04-25 21:11:14 -04:00
commit eefaadee34
4 changed files with 146 additions and 90 deletions

View file

@ -1,16 +1,16 @@
---
title: MCP Context
sidebarTitle: Context
description: Access MCP capabilities like logging, progress, and resources within your tools.
description: Access MCP capabilities like logging, progress, and resources within your MCP objects.
icon: rectangle-code
---
import { VersionBadge } from '/snippets/version-badge.mdx'
When defining FastMCP [tools](/servers/tools), your functions might need to interact with the underlying MCP session or access server capabilities. FastMCP provides the `Context` object for this purpose.
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 server capabilities. FastMCP provides the `Context` object for this purpose.
## What Is Context?
The `Context` object provides a clean interface to access MCP features within your tool functions, including:
The `Context` object provides a clean interface to access MCP features within your functions, including:
- **Logging**: Send debug, info, warning, and error messages back to the client
- **Progress Reporting**: Update the client on the progress of long-running operations
@ -21,7 +21,7 @@ The `Context` object provides a clean interface to access MCP features within yo
## Accessing the Context
To use the context object within your tool function, simply add a parameter to your function signature and type-hint it as `Context`. FastMCP will automatically inject the context instance when your tool is called.
To use the context object within any of your functions, simply add a parameter to your function signature and type-hint it as `Context`. FastMCP will automatically inject the context instance when your function is called.
```python
from fastmcp import FastMCP, Context
@ -65,15 +65,15 @@ async def process_file(file_uri: str, ctx: Context) -> str:
- The parameter name (e.g., `ctx`, `context`) doesn't matter, only the type hint `Context` is important.
- The context parameter can be placed anywhere in your function's signature.
- The context is optional - tools that don't need it can omit the parameter.
- Context is only available within tool functions during a request; attempting to use context methods outside a request will raise errors.
- Context methods are async, so your tool function usually needs to be async as well.
- The context is optional - functions that don't need it can omit the parameter.
- Context is only available during a request; attempting to use context methods outside a request will raise errors.
- Context methods are async, so your function usually needs to be async as well.
## Context Capabilities
### Logging
Send log messages back to the MCP client. This is useful for debugging and providing visibility into tool execution during a request.
Send log messages back to the MCP client. This is useful for debugging and providing visibility into function execution during a request.
```python
@mcp.tool()
@ -97,14 +97,14 @@ async def analyze_data(data: list[float], ctx: Context) -> dict:
**Available Logging Methods:**
- **`ctx.debug(message: str)`**: Low-level details useful for debugging
- **`ctx.info(message: str)`**: General information about tool execution
- **`ctx.info(message: str)`**: General information about execution
- **`ctx.warning(message: str)`**: Potential issues that didn't prevent execution
- **`ctx.error(message: str)`**: Errors that occurred during execution
- **`ctx.log(level: Literal["debug", "info", "warning", "error"], message: str, logger_name: str | None = None)`**: Generic log method supporting custom logger names
### Progress Reporting
For long-running tools, notify the client about the progress of the operation. This allows clients to display progress indicators and provide a better user experience.
For long-running operations, notify the client about the progress. This allows clients to display progress indicators and provide a better user experience.
```python
@mcp.tool()
@ -137,7 +137,7 @@ Progress reporting requires the client to have sent a `progressToken` in the ini
### Resource Access
Read data from resources registered with your FastMCP server. This allows tools to access files, configuration, or dynamically generated content.
Read data from resources registered with your FastMCP server. This allows functions to access files, configuration, or dynamically generated content.
```python
@mcp.tool()
@ -177,7 +177,7 @@ The returned content is typically accessed via `content_list[0].content` and can
<VersionBadge version="2.0.0" />
Request the client's LLM to generate text based on provided messages. This is useful when your tool needs to leverage the LLM's capabilities to process data or generate responses.
Request the client's LLM to generate text based on provided messages. This is useful when your function needs to leverage the LLM's capabilities to process data or generate responses.
```python
@mcp.tool()
@ -279,6 +279,60 @@ async def advanced_tool(ctx: Context) -> str:
Direct use of `session` or `request_context` requires understanding the low-level MCP Python SDK and may be less stable than using the methods provided directly on the `Context` object.
</Warning>
## Using Context in Other Components
## Using Context in Different Components
Currently, Context is primarily designed for use within tool functions. Support for Context in other components like resources and prompts is planned for future releases.
All FastMCP components (tools, resources, templates, and prompts) can use the Context object following the same pattern - simply add a parameter with the `Context` type annotation.
### Context in Resources and Templates
Resources and resource templates can access context to customize their behavior:
```python
@mcp.resource("resource://user-data")
async def get_user_data(ctx: Context) -> dict:
"""Fetch personalized user data based on the request context."""
user_id = ctx.client_id or "anonymous"
await ctx.info(f"Fetching data for user {user_id}")
# Example of using context for dynamic resource generation
return {
"user_id": user_id,
"last_access": datetime.now().isoformat(),
"request_id": ctx.request_id
}
@mcp.resource("resource://users/{user_id}/profile")
async def get_user_profile(user_id: str, ctx: Context) -> dict:
"""Fetch user profile from database with context-aware logging."""
await ctx.info(f"Fetching profile for user {user_id}")
# Example of using context in a template resource
# In a real implementation, you might query a database
return {
"id": user_id,
"name": f"User {user_id}",
"request_id": ctx.request_id
}
```
### Context in Prompts
Prompts can use context to generate more dynamic templates:
```python
@mcp.prompt()
async def data_analysis_request(dataset: str, ctx: Context) -> str:
"""Generate a request to analyze data with contextual information."""
await ctx.info(f"Generating data analysis prompt for {dataset}")
# Could use context to read configuration or personalize the prompt
return f"""Please analyze the following dataset: {dataset}
Request initiated at: {datetime.now().isoformat()}
Request ID: {ctx.request_id}
"""
```
<VersionBadge version="2.3.0" />
All FastMCP objects now support context injection using the same consistent pattern, making it easy to add session-aware capabilities to all aspects of your MCP server.

View file

@ -171,33 +171,24 @@ async def data_based_prompt(data_id: str) -> str:
Use `async def` when your prompt function performs I/O operations like network requests, database queries, file I/O, or external service calls.
### The MCP Session
### Accessing MCP Context
Prompts can access the MCP features via the `Context` object, just like tools.
<VersionBadge version="2.2.5" />
```python
from fastmcp import Context
Prompts can access additional MCP information and features through the `Context` object. To access it, add a parameter to your prompt function with a type annotation of `Context`:
```python {6}
from fastmcp import FastMCP, Context
mcp = FastMCP(name="PromptServer")
@mcp.prompt()
async def generate_report_request(report_type: str, ctx: Context) -> str:
"""Generates a request for a report based on available data."""
# Log the request
await ctx.info(f"Generating prompt for report type: {report_type}")
# Could potentially use ctx.read_resource to fetch data
# Or ctx.sample to get additional input from the LLM
return f"Please create a {report_type} report based on the available data."
"""Generates a request for a report."""
return f"Please create a {report_type} report. Request ID: {ctx.request_id}"
```
Using the `ctx` parameter (based on its `Context` type hint), you can access:
- **Logging:** `ctx.debug()`, `ctx.info()`, etc.
- **Resource Access:** `ctx.read_resource(uri)`
- **LLM Sampling:** `ctx.sample(...)`
- **Request Info:** `ctx.request_id`, `ctx.client_id`
Refer to the [Context documentation](/servers/context) for more details on these capabilities.
For full documentation on the Context object and all its capabilities, see the [Context documentation](/servers/context).
## Server Behavior

View file

@ -95,6 +95,36 @@ def get_application_status() -> dict:
- **`mime_type`**: Specifies the content type (FastMCP often infers a default like `text/plain` or `application/json`, but explicit is better for non-text types).
- **`tags`**: A set of strings for categorization, potentially used by clients for filtering.
### Accessing MCP Context
<VersionBadge version="2.2.5" />
Resources and resource templates can access additional MCP information and features through the `Context` object. To access it, add a parameter to your resource function with a type annotation of `Context`:
```python {6, 14}
from fastmcp import FastMCP, Context
mcp = FastMCP(name="DataServer")
@mcp.resource("resource://system-status")
async def get_system_status(ctx: Context) -> dict:
"""Provides system status information."""
return {
"status": "operational",
"request_id": ctx.request_id
}
@mcp.resource("resource://{name}/details")
async def get_details(name: str, ctx: Context) -> dict:
"""Get details for a specific name."""
return {
"name": name,
"accessed_at": ctx.request_id
}
```
For full documentation on the Context object and all its capabilities, see the [Context documentation](/servers/context).
### Asynchronous Resources
@ -205,6 +235,8 @@ Note that this parameter is only available when using `add_resource()` directly
Resource Templates allow clients to request resources whose content depends on parameters embedded in the URI. Define a template using the **same `@mcp.resource` decorator**, but include `{parameter_name}` placeholders in the URI string and add corresponding arguments to your function signature.
Resource templates share most configuration options with regular resources (name, description, mime_type, tags), but add the ability to define URI parameters that map to function parameters.
Resource templates generate a new resource for each unique set of parameters, which means that resources can be dynamically created on-demand. For example, if the resource template `"user://profile/{name}"` is registered, MCP clients could request `"user://profile/ford"` or `"user://profile/marvin"` to retrieve either of those two user profiles as resources, without having to register each resource individually.
Here is a complete example that shows how to define two resource templates:
@ -379,28 +411,6 @@ In this stacked decorator pattern:
Templates provide a powerful way to expose parameterized data access points following REST-like principles.
### Custom Template Keys
<VersionBadge version="2.2.0" />
Similar to resources, you can provide custom keys when directly adding templates:
```python
from fastmcp.resources import ResourceTemplate
# Create a template with a function
template = ResourceTemplate.from_function(
my_function,
uri_template="data://{id}/details",
name="Data Details"
)
# Register with a custom key
mcp._resource_manager.add_template(template, key="custom://{id}/view")
```
This allows accessing the same template implementation through different URI patterns.
## Server Behavior
### Duplicate Resources

View file

@ -263,7 +263,8 @@ FastMCP automatically catches exceptions raised within your tool function:
Using informative exceptions helps the LLM understand failures and react appropriately.
### Accessing MCP Context
## MCP Context
Tools can access MCP features like logging, reading resources, or reporting progress through the `Context` object. To use it, add a parameter to your tool function with the type hint `Context`.
@ -304,39 +305,6 @@ The Context object provides access to:
For full documentation on the Context object and all its capabilities, see the [Context documentation](/servers/context).
## Server Behavior
### Duplicate Tools
<VersionBadge version="2.1.0" />
You can control how the FastMCP server behaves if you try to register multiple tools with the same name. This is configured using the `on_duplicate_tools` argument when creating the `FastMCP` instance.
```python
from fastmcp import FastMCP
mcp = FastMCP(
name="StrictServer",
# Configure behavior for duplicate tool names
on_duplicate_tools="error"
)
@mcp.tool()
def my_tool(): return "Version 1"
# This will now raise a ValueError because 'my_tool' already exists
# and on_duplicate_tools is set to "error".
# @mcp.tool()
# def my_tool(): return "Version 2"
```
The duplicate behavior options are:
- `"warn"` (default): Logs a warning and the new tool replaces the old one.
- `"error"`: Raises a `ValueError`, preventing the duplicate registration.
- `"replace"`: Silently replaces the existing tool with the new one.
- `"ignore"`: Keeps the original tool and ignores the new registration attempt.
## Parameter Types
FastMCP supports a wide variety of parameter types to give you flexibility when designing your tools.
@ -663,3 +631,36 @@ Common validation options include:
| `description` | Any | Human-readable description (appears in schema) |
When a client sends invalid data, FastMCP will return a validation error explaining why the parameter failed validation.
## Server Behavior
### Duplicate Tools
<VersionBadge version="2.1.0" />
You can control how the FastMCP server behaves if you try to register multiple tools with the same name. This is configured using the `on_duplicate_tools` argument when creating the `FastMCP` instance.
```python
from fastmcp import FastMCP
mcp = FastMCP(
name="StrictServer",
# Configure behavior for duplicate tool names
on_duplicate_tools="error"
)
@mcp.tool()
def my_tool(): return "Version 1"
# This will now raise a ValueError because 'my_tool' already exists
# and on_duplicate_tools is set to "error".
# @mcp.tool()
# def my_tool(): return "Version 2"
```
The duplicate behavior options are:
- `"warn"` (default): Logs a warning and the new tool replaces the old one.
- `"error"`: Raises a `ValueError`, preventing the duplicate registration.
- `"replace"`: Silently replaces the existing tool with the new one.
- `"ignore"`: Keeps the original tool and ignores the new registration attempt.