Skip to content

Commit 2e298fe

Browse files
committed
Improve README around the Context object
Enhanced Context and Tools sections with documentation of Context object injection, properties, and methods.
1 parent 959d4e3 commit 2e298fe

File tree

1 file changed

+169
-1
lines changed

1 file changed

+169
-1
lines changed

README.md

Lines changed: 169 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,35 @@ def get_weather(city: str, unit: str = "celsius") -> str:
303303
_Full example: [examples/snippets/servers/basic_tool.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_tool.py)_
304304
<!-- /snippet-source -->
305305

306+
Tools can optionally receive a Context object by including a parameter with the `Context` type annotation. This context is automatically injected by the FastMCP framework and provides access to MCP capabilities:
307+
308+
<!-- snippet-source examples/snippets/servers/tool_progress.py -->
309+
```python
310+
from mcp.server.fastmcp import Context, FastMCP
311+
312+
mcp = FastMCP(name="Progress Example")
313+
314+
315+
@mcp.tool()
316+
async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str:
317+
"""Execute a task with progress updates."""
318+
await ctx.info(f"Starting: {task_name}")
319+
320+
for i in range(steps):
321+
progress = (i + 1) / steps
322+
await ctx.report_progress(
323+
progress=progress,
324+
total=1.0,
325+
message=f"Step {i + 1}/{steps}",
326+
)
327+
await ctx.debug(f"Completed step {i + 1}")
328+
329+
return f"Task '{task_name}' completed"
330+
```
331+
332+
_Full example: [examples/snippets/servers/tool_progress.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/tool_progress.py)_
333+
<!-- /snippet-source -->
334+
306335
#### Structured Output
307336

308337
Tools will return structured results by default, if their return type
@@ -496,7 +525,47 @@ _Full example: [examples/snippets/servers/images.py](https://github.com/modelcon
496525

497526
### Context
498527

499-
The Context object gives your tools and resources access to MCP capabilities:
528+
The Context object is automatically injected into tool and resource functions that request it via type hints. It provides access to MCP capabilities like logging, progress reporting, resource reading, user interaction, and request metadata.
529+
530+
#### Getting Context in Functions
531+
532+
To use context in a tool or resource function, add a parameter with the `Context` type annotation:
533+
534+
```python
535+
from mcp.server.fastmcp import Context, FastMCP
536+
537+
mcp = FastMCP(name="Context Example")
538+
539+
540+
@mcp.tool()
541+
async def my_tool(x: int, ctx: Context) -> str:
542+
"""Tool that uses context capabilities."""
543+
# The context parameter can have any name as long as it's type-annotated
544+
return await process_with_context(x, ctx)
545+
```
546+
547+
#### Context Properties and Methods
548+
549+
The Context object provides the following capabilities:
550+
551+
##### Properties
552+
553+
- `ctx.request_id` - Unique ID for the current request
554+
- `ctx.client_id` - Client ID if available
555+
- `ctx.fastmcp` - Access to the FastMCP server instance (see [FastMCP Properties](#fastmcp-properties))
556+
- `ctx.session` - Access to the underlying session for advanced communication (see [Session Properties](#session-properties))
557+
- `ctx.request_context` - Access to request-specific data and lifespan resources (see [Request Context Properties](#request-context-properties))
558+
559+
##### Methods
560+
561+
- `await ctx.debug(message)` - Send debug log message
562+
- `await ctx.info(message)` - Send info log message
563+
- `await ctx.warning(message)` - Send warning log message
564+
- `await ctx.error(message)` - Send error log message
565+
- `await ctx.log(level, message, logger_name=None)` - Send log with custom level
566+
- `await ctx.report_progress(progress, total=None, message=None)` - Report operation progress
567+
- `await ctx.read_resource(uri)` - Read a resource by URI
568+
- `await ctx.elicit(message, schema)` - Request additional information from user with validation
500569

501570
<!-- snippet-source examples/snippets/servers/tool_progress.py -->
502571
```python
@@ -808,6 +877,105 @@ For a complete example with separate Authorization Server and Resource Server im
808877

809878
See [TokenVerifier](src/mcp/server/auth/provider.py) for more details on implementing token validation.
810879

880+
### FastMCP Properties
881+
882+
The FastMCP server instance accessible via `ctx.fastmcp` provides access to server configuration and metadata:
883+
884+
- `ctx.fastmcp.name` - The server's name as defined during initialization
885+
- `ctx.fastmcp.instructions` - Server instructions/description provided to clients
886+
- `ctx.fastmcp.settings` - Complete server configuration object containing:
887+
- `debug` - Debug mode flag
888+
- `log_level` - Current logging level
889+
- `host` and `port` - Server network configuration
890+
- `mount_path`, `sse_path`, `streamable_http_path` - Transport paths
891+
- `stateless_http` - Whether the server operates in stateless mode
892+
- And other configuration options
893+
894+
```python
895+
@mcp.tool()
896+
def server_info(ctx: Context) -> dict:
897+
"""Get information about the current server."""
898+
return {
899+
"name": ctx.fastmcp.name,
900+
"instructions": ctx.fastmcp.instructions,
901+
"debug_mode": ctx.fastmcp.settings.debug,
902+
"log_level": ctx.fastmcp.settings.log_level,
903+
"host": ctx.fastmcp.settings.host,
904+
"port": ctx.fastmcp.settings.port,
905+
}
906+
```
907+
908+
### Session Properties and Methods
909+
910+
The session object accessible via `ctx.session` provides advanced control over client communication:
911+
912+
#### Properties
913+
914+
- `ctx.session.client_params` - Client initialization parameters and declared capabilities
915+
916+
917+
#### Methods
918+
- `await ctx.session.send_log_message(level, data, logger)` - Send log messages with full control
919+
- `await ctx.session.create_message(messages, max_tokens)` - Request LLM sampling/completion
920+
- `await ctx.session.send_progress_notification(token, progress, total, message)` - Direct progress updates
921+
- `await ctx.session.send_resource_updated(uri)` - Notify clients that a specific resource changed
922+
- `await ctx.session.send_resource_list_changed()` - Notify clients that the resource list changed
923+
- `await ctx.session.send_tool_list_changed()` - Notify clients that the tool list changed
924+
- `await ctx.session.send_prompt_list_changed()` - Notify clients that the prompt list changed
925+
926+
927+
```python
928+
@mcp.tool()
929+
async def notify_data_update(resource_uri: str, ctx: Context) -> str:
930+
"""Update data and notify clients of the change."""
931+
# Perform data update logic here
932+
933+
# Notify clients that this specific resource changed
934+
await ctx.session.send_resource_updated(AnyUrl(resource_uri))
935+
936+
# If this affects the overall resource list, notify about that too
937+
await ctx.session.send_resource_list_changed()
938+
939+
return f"Updated {resource_uri} and notified clients"
940+
```
941+
942+
### Request Context Properties
943+
944+
The request context accessible via `ctx.request_context` contains request-specific information and resources:
945+
946+
- `ctx.request_context.lifespan_context` - Access to resources initialized during server startup
947+
- Database connections, configuration objects, shared services
948+
- Type-safe access to resources defined in your server's lifespan function
949+
- `ctx.request_context.meta` - Request metadata from the client including:
950+
- `progressToken` - Token for progress notifications
951+
- Other client-provided metadata
952+
- `ctx.request_context.request` - The original MCP request object for advanced processing
953+
- `ctx.request_context.request_id` - Unique identifier for this request
954+
955+
```python
956+
# Example with typed lifespan context
957+
@dataclass
958+
class AppContext:
959+
db: Database
960+
config: AppConfig
961+
962+
@mcp.tool()
963+
def query_with_config(query: str, ctx: Context) -> str:
964+
"""Execute a query using shared database and configuration."""
965+
# Access typed lifespan context
966+
app_ctx: AppContext = ctx.request_context.lifespan_context
967+
968+
# Use shared resources
969+
connection = app_ctx.db
970+
settings = app_ctx.config
971+
972+
# Execute query with configuration
973+
result = connection.execute(query, timeout=settings.query_timeout)
974+
return str(result)
975+
```
976+
977+
_Full lifespan example: [examples/snippets/servers/lifespan_example.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/lifespan_example.py)_
978+
811979
## Running Your Server
812980

813981
### Development Mode

0 commit comments

Comments
 (0)