fix(mcpserver): ignore the return annotation when finding the context parameter - #3301
Open
hishammoizuddin wants to merge 1 commit into
Open
Conversation
… parameter `find_context_parameter` iterated every entry from `typing.get_type_hints`, which includes the return annotation under the special `"return"` key. A tool, prompt, or resource function annotated `-> Context` (or a union containing it) was therefore recorded as having a context parameter named `"return"`, and the handler failed at invocation with `got an unexpected keyword argument 'return'`. Drop the `"return"` key before scanning, so only real parameters are considered. Fixes modelcontextprotocol#3298 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3298
What's wrong
find_context_parameter()loops over everythingtyping.get_type_hints()returns. Thatmapping includes the function's return annotation under the special
"return"key, whichisn't a parameter.
So a handler annotated
-> Context(or a union containing it) gets recorded as having acontext parameter named
"return", and the context is injected under that name when thehandler is called.
returnis a keyword and can't be declared as a parameter, so the callalways fails — registration succeeds and the breakage only shows up at invocation time.
It isn't only tools: prompts and resource templates resolve their context through the same
function. Reverting just
context_injection.pyand exercising one of each:The fix
Drop the
"return"key before scanning the hints, so only real parameters are considered.Why this should be safe
Every path that previously resolved to
"return"failed at invocation, so nothing couldhave been depending on it — this only turns a guaranteed failure into working behaviour.
Handlers that have both a real
Contextparameter and aContextreturn annotation werealready fine, because
get_type_hints()yields parameters beforereturn(you get['a', 'ctx', 'b', 'return']fordef f(a, ctx, b) -> Context). I've pinned that orderingin a test so a later refactor can't quietly break it.
Tests
New
tests/server/mcpserver/test_context_injection.py:Contextis found)-> Contextisn't reported as a parameter-> Context | Noneisn't reported as a parameterContextparameter still wins when the return annotation is alsoContextClient(server)for a tool, a prompt and a resource templateFive of the seven fail without the
src/change../scripts/testpasses (100% branch coverage,strict-no-coverclean), ruff and pyrightare clean on the changed files, and the new tests pass on 3.10 and 3.14.
Related PRs
No overlap with #3236 or #2623, which touch the same module for unrelated reasons. I
test-merged both against this branch and neither conflicts.
Disclosure: I used AI assistance (Claude Code) for this change. I've reviewed it myself
and can explain it.