Skip to content

Revisit FastMCP context injection to reduce “magic” and improve type-safety #1695

@dgenio

Description

@dgenio

Description

Summary

FastMCP currently uses introspection to automatically inject a Context parameter into tools/resources when it detects a parameter with the right name/type. This is convenient but “magic”:

  • it relies on parameter naming/type hints,
  • it’s invisible in function signatures (from a caller’s perspective),
  • it can break silently after refactors.

This issue proposes making context injection more explicit and type-safe, while preserving ergonomics.

Problems

  • Brittle conventions: Renaming the parameter or changing the import path of Context can silently break injection.
  • Type checker mismatch: Type hints show a required parameter, but at runtime the SDK auto-populates it, which can confuse static analysis and IDEs.
  • New user confusion: It’s not obvious from examples why a parameter is populated or how to opt into/opt out of it.

Proposal

  1. Introduce explicit opt-in for context injection

    For example:

    • Via decorator argument:

      @mcp.tool(inject_context=True)
      async def my_tool(ctx: Context, ...) -> ...:
          ...
    • Or via a dedicated “injected” marker type, e.g. ctx: Injected[Context].

  2. Document a single, clear convention

    • If conventions are used (e.g., _mcp_context parameter name), make them explicit and heavily documented:
      • “If you define a parameter named _mcp_context with type Context, FastMCP will inject it.”
  3. Migration path

    • Support both the old introspection behavior and the new explicit pattern for at least one minor release.
    • Add warnings or docs guiding users towards the explicit pattern.

Why this matters

  • Predictability: Less “magic” makes it easier to reason about what the SDK is doing.
  • Tooling: IDEs and static analyzers can more accurately represent what parameters are expected.
  • Refactoring safety: Users are less likely to accidentally break context injection when renaming parameters or types.

Acceptance criteria

  • There is an explicit, documented way to opt into context injection (decorator flag or marker type).
  • The existing introspection mechanism is either deprecated or clearly described as legacy.
  • Examples and docs use the explicit pattern as the recommended approach.
  • Type checkers can understand the pattern without special configuration.

References

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions