Skip to content

Commit d475928

Browse files
authored
Improve README around the Context object (#1203)
1 parent 34e3664 commit d475928

File tree

1 file changed

+164
-1
lines changed

1 file changed

+164
-1
lines changed

README.md

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,20 @@
3636
- [Sampling](#sampling)
3737
- [Logging and Notifications](#logging-and-notifications)
3838
- [Authentication](#authentication)
39+
- [FastMCP Properties](#fastmcp-properties)
40+
- [Session Properties](#session-properties-and-methods)
41+
- [Request Context Properties](#request-context-properties)
3942
- [Running Your Server](#running-your-server)
4043
- [Development Mode](#development-mode)
4144
- [Claude Desktop Integration](#claude-desktop-integration)
4245
- [Direct Execution](#direct-execution)
46+
- [Streamable HTTP Transport](#streamable-http-transport)
4347
- [Mounting to an Existing ASGI Server](#mounting-to-an-existing-asgi-server)
4448
- [Advanced Usage](#advanced-usage)
4549
- [Low-Level Server](#low-level-server)
4650
- [Writing MCP Clients](#writing-mcp-clients)
51+
- [Client Display Utilities](#client-display-utilities)
52+
- [OAuth Authentication for Clients](#oauth-authentication-for-clients)
4753
- [Parsing Tool Results](#parsing-tool-results)
4854
- [MCP Primitives](#mcp-primitives)
4955
- [Server Capabilities](#server-capabilities)
@@ -303,6 +309,35 @@ def get_weather(city: str, unit: str = "celsius") -> str:
303309
_Full example: [examples/snippets/servers/basic_tool.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_tool.py)_
304310
<!-- /snippet-source -->
305311

312+
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:
313+
314+
<!-- snippet-source examples/snippets/servers/tool_progress.py -->
315+
```python
316+
from mcp.server.fastmcp import Context, FastMCP
317+
318+
mcp = FastMCP(name="Progress Example")
319+
320+
321+
@mcp.tool()
322+
async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str:
323+
"""Execute a task with progress updates."""
324+
await ctx.info(f"Starting: {task_name}")
325+
326+
for i in range(steps):
327+
progress = (i + 1) / steps
328+
await ctx.report_progress(
329+
progress=progress,
330+
total=1.0,
331+
message=f"Step {i + 1}/{steps}",
332+
)
333+
await ctx.debug(f"Completed step {i + 1}")
334+
335+
return f"Task '{task_name}' completed"
336+
```
337+
338+
_Full example: [examples/snippets/servers/tool_progress.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/tool_progress.py)_
339+
<!-- /snippet-source -->
340+
306341
#### Structured Output
307342

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

497532
### Context
498533

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

501571
<!-- snippet-source examples/snippets/servers/tool_progress.py -->
502572
```python
@@ -808,6 +878,99 @@ For a complete example with separate Authorization Server and Resource Server im
808878

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

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

813976
### Development Mode

0 commit comments

Comments
 (0)