Skip to content

Conversation

@cbcoutinho
Copy link
Contributor

@cbcoutinho cbcoutinho commented Nov 10, 2025

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_id field
  • ServerSession: Store and expose session_id via property
  • RequestContext: Add session_id field to dataclass
  • StreamableHTTPSessionManager: Pass session_id when creating initialization options
  • FastMCP Context: Add session_id property 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_id returns the transport's session ID (UUID)
  • Streamable-HTTP (stateless): ctx.session_id returns None (no session tracking)
  • stdio/SSE transports: ctx.session_id returns None (session_id not set during initialization)

Use Cases

  1. Distributed Tracing: Add session_id as a span attribute in OpenTelemetry traces to correlate all tool calls within a session
  2. Session Analytics: Track per-session metrics and usage patterns
  3. Debugging: Correlate logs and errors across multiple requests in the same session
  4. 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

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

Enables tools to access the transport-level session ID (e.g., from
streamable-http) via Context.session_id property. This supports
session-level tracing and addresses user requests in modelcontextprotocol#485 and modelcontextprotocol#942.

Changes:
- Add session_id field to InitializationOptions
- Store session_id in ServerSession and expose via property
- Add session_id field to RequestContext dataclass
- Pass session_id when creating RequestContext
- Update StreamableHTTPSessionManager to pass session_id at init
- Add session_id property to FastMCP Context class
- Add comprehensive tests for session_id propagation

The session_id is available for streamable-http transport and None
for stdio/stateless modes. Tools can now correlate all requests
within a session for observability and tracing purposes.

Fixes modelcontextprotocol#485
Fixes modelcontextprotocol#942
Related to modelcontextprotocol#421 (OpenTelemetry tracing)
- Add ServerSession type arguments to Context in test tools
- Switch to JSON response mode for easier testing (avoids SSE streaming complexity)
- Update accept headers to match JSON response mode
- All tests now pass locally

Pyright errors in src/mcp/cli/*.py and src/mcp/client/websocket.py are
pre-existing and not introduced by this change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant