python-sdk
python-sdk copied to clipboard
feat: propagate session_id from transport to tool context
Summary
This PR enables tools to access the transport-level session ID via Context.session_id, supporting session-level tracing and observability use cases.
Changes
-
InitializationOptions: Add optional
session_idfield -
ServerSession: Store and expose
session_idvia property -
RequestContext: Add
session_idfield to dataclass -
StreamableHTTPSessionManager: Pass
session_idwhen creating initialization options -
FastMCP Context: Add
session_idproperty accessible in tools - Tests: Comprehensive test suite for session_id propagation
Usage
Tools can now access the session ID like this:
@mcp.tool()
async def my_tool(ctx: Context) -> dict:
session_id = ctx.session_id # Transport's session ID (streamable-http)
# Use for tracing, logging, correlation, etc.
return {"session_id": session_id}
Behavior
-
Streamable-HTTP (stateful):
ctx.session_idreturns the transport's session ID (UUID) -
Streamable-HTTP (stateless):
ctx.session_idreturnsNone(no session tracking) -
stdio/SSE transports:
ctx.session_idreturnsNone(session_id not set during initialization)
Use Cases
- Distributed Tracing: Add session_id as a span attribute in OpenTelemetry traces to correlate all tool calls within a session
- Session Analytics: Track per-session metrics and usage patterns
- Debugging: Correlate logs and errors across multiple requests in the same session
- Audit Trails: Associate all operations with a session identifier
Testing
- All 418 existing server tests pass ✓
- New test suite covers session_id propagation scenarios
- Verified no regressions in FastMCP, auth, resource tests
Fixes
- #485
- #942
Related
Related to #421 (OpenTelemetry tracing integration)
Breaking Changes
None. This is a backward-compatible addition:
- New optional field in
InitializationOptions - New property on
Context(returns None if not available) - Existing code continues to work without modifications