python-sdk icon indicating copy to clipboard operation
python-sdk copied to clipboard

Refactor global contextvars request context into explicit parameters

Open dgenio opened this issue 1 month ago • 0 comments

Description

Summary

The Python SDK currently uses a global contextvars.ContextVar (e.g. request_ctx) to hold per-request state for the server. This enables convenience helpers like get_request_context(), but it also introduces implicit dependencies and makes testing, debugging, and refactoring harder.

This proposal suggests moving towards explicit context passing in handlers and eventually deprecating global request context access, with a migration path.

Background

Today, the low-level server and FastMCP rely on a global ContextVar that holds a RequestContext. Handler code can implicitly call get_request_context() without any indication in the function signature that it depends on request-local state.

This has several drawbacks:

  • Hidden dependencies: Functions depend on ambient state, not their parameters.
  • Debugging complexity: Stack traces do not show where the context came from.
  • Testability: Unit tests must set up ContextVar state or fall back to full integration tests.
  • Refactoring risk: Moving code between modules can silently break if context assumptions change.

Proposal

Phase 1 – Explicit context in handler signatures

  1. Make RequestContext (or a higher-level Context) an explicit parameter for all tool/resource handlers at the low-level server boundary.
  2. At the FastMCP layer, inject the context explicitly into handler callsites instead of relying on global ContextVar lookups.
  3. Keep get_request_context() for now, but document it as deprecated and implemented in terms of the explicit parameter passing.

Phase 2 – Internal-only use (or removal) of ContextVar

  1. Refactor internal call chains so that the RequestContext is always passed as an argument rather than read from a global.
  2. Limit any remaining ContextVar usage to:
    • bridging with external frameworks (if needed), or
    • cross-cutting concerns like tracing where explicit parameter threading is impossible.
  3. Remove get_request_context() (or keep only as a thin, clearly discouraged compatibility helper).

Migration and compatibility

  • Provide an explicit, documented pattern for handlers that need context:
    • e.g. async def tool(ctx: Context, ...) -> ...
  • Keep the current behavior working for at least one minor release, with deprecation warnings where appropriate.
  • Update examples and docs to promote explicit context usage.

Why this matters

  • Testability: Handlers become pure-ish functions with explicit dependencies.
  • Debugging: It’s easier to follow how context flows through the system.
  • Robustness: Less risk of accidental context leakage across concurrent requests.
  • API clarity: Users see, in signatures, that a handler depends on request context.

Acceptance criteria

  • [ ] All public handler registration paths can accept an explicit context parameter.
  • [ ] Core server internals pass RequestContext explicitly rather than relying on ContextVar.
  • [ ] get_request_context() is either deprecated or clearly documented as a compatibility shim.
  • [ ] Tests no longer need to directly manipulate global request ContextVar state.
  • [ ] Documentation updated to show explicit context patterns as the recommended approach.

References

No response

dgenio avatar Nov 28 '25 11:11 dgenio