Skip to content

fix: detect Context parameter in callable class instances#2178

Closed
giulio-leone wants to merge 2 commits intomodelcontextprotocol:mainfrom
giulio-leone:fix/find-context-parameter-callable-class
Closed

fix: detect Context parameter in callable class instances#2178
giulio-leone wants to merge 2 commits intomodelcontextprotocol:mainfrom
giulio-leone:fix/find-context-parameter-callable-class

Conversation

@giulio-leone
Copy link

Problem

When registering a callable class instance as an MCP tool via add_tool(), the ctx: Context parameter is incorrectly exposed as a visible tool parameter in the JSON schema, instead of being injected by the framework.

This happens because find_context_parameter() uses typing.get_type_hints(fn), which doesn't introspect the __call__ method of callable class instances.

class MyTool:
    def __init__(self, name: str):
        self.__name__ = name

    async def __call__(self, query: str, ctx: Context) -> str:
        return f"Result: {query}"

mcp.add_tool(MyTool(name="my_tool"), name="my_tool")
# Bug: 'ctx' appears as a required parameter in the schema

Fix

In find_context_parameter(), detect callable class instances (not functions or methods) and inspect fn.__call__ instead of fn directly.

Tests

Added two tests:

  • test_context_detection_callable_class: Verifies ctx is detected and excluded from schema
  • test_context_injection_callable_class: Verifies ctx is properly injected at runtime

Fixes #1974

g97iulio1609 added 2 commits February 28, 2026 15:41
find_context_parameter() uses typing.get_type_hints(fn) to find
Context-typed parameters. However, get_type_hints() doesn't introspect
the __call__ method of callable class instances, so ctx: Context is
exposed as a visible tool parameter instead of being injected by the
framework.

The fix checks if fn is a callable class instance (not a function or
method) and inspects fn.__call__ instead.

Fixes modelcontextprotocol#1974
Exercise the branch in context_injection.py where the input is
neither a function/method nor a callable class, ensuring 100%
branch coverage.
@giulio-leone
Copy link
Author

Closing to reduce noise — focusing on the most impactful PRs. Happy to reopen if there's interest.

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.

find_context_parameter() fails to detect Context parameter in callable class instances

1 participant