Summary
MCPServer._handle_call_tool in src/mcp/server/mcpserver/server.py
contains a dead isinstance(result, dict) branch, with an inline TODO
that already documents both the dead-code issue and the related
incorrect return-type annotation on MCPServer.call_tool.
I'd like to clean this up. Posting the diagnosis here first per
CONTRIBUTING.md.
Diagnosis
FuncMetadata.convert_result in
src/mcp/server/mcpserver/utilities/func_metadata.py can return exactly
three shapes (lines 105-123):
CallToolResult (when the tool function returned one directly)
Sequence[ContentBlock] (no output schema — via _convert_to_content)
(unstructured_content, structured_content) tuple (with output schema)
Never a raw dict. So:
- The
isinstance(result, dict) branch in _handle_call_tool (lines
325-332 on main) is unreachable. It's marked # pragma: no cover
because tests cannot reach it.
MCPServer.call_tool's return-type annotation
Sequence[ContentBlock] | dict[str, Any] (line 402 on main) is wrong:
it advertises a dict return that cannot happen, and is missing the
CallToolResult and tuple shapes that can happen.
Proposed fix
- Remove the dead
isinstance(result, dict) branch.
- Drop the now-unused
import json.
- Change
call_tool's return type to
CallToolResult | Sequence[ContentBlock] | tuple[Sequence[ContentBlock], dict[str, Any]]
and document all three shapes in the docstring.
The return-type change is a breaking type-signature change for
subclasses, so this targets main (v2) per CONTRIBUTING.md.
I have the patch ready and CI-clean locally (pytest + ruff + pyright).
Happy to open the PR once this is acknowledged.
AI assistance disclosure
I used an AI assistant to help trace the call path and draft the diff.
I've reviewed every changed line, validated the diagnosis against the
source, and run the local checks myself.
Summary
MCPServer._handle_call_toolinsrc/mcp/server/mcpserver/server.pycontains a dead
isinstance(result, dict)branch, with an inline TODOthat already documents both the dead-code issue and the related
incorrect return-type annotation on
MCPServer.call_tool.I'd like to clean this up. Posting the diagnosis here first per
CONTRIBUTING.md.
Diagnosis
FuncMetadata.convert_resultinsrc/mcp/server/mcpserver/utilities/func_metadata.pycan return exactlythree shapes (lines 105-123):
CallToolResult(when the tool function returned one directly)Sequence[ContentBlock](no output schema — via_convert_to_content)(unstructured_content, structured_content)tuple (with output schema)Never a raw
dict. So:isinstance(result, dict)branch in_handle_call_tool(lines325-332 on main) is unreachable. It's marked
# pragma: no coverbecause tests cannot reach it.
MCPServer.call_tool's return-type annotationSequence[ContentBlock] | dict[str, Any](line 402 on main) is wrong:it advertises a dict return that cannot happen, and is missing the
CallToolResultand tuple shapes that can happen.Proposed fix
isinstance(result, dict)branch.import json.call_tool's return type toCallToolResult | Sequence[ContentBlock] | tuple[Sequence[ContentBlock], dict[str, Any]]and document all three shapes in the docstring.
The return-type change is a breaking type-signature change for
subclasses, so this targets
main(v2) per CONTRIBUTING.md.I have the patch ready and CI-clean locally (pytest + ruff + pyright).
Happy to open the PR once this is acknowledged.
AI assistance disclosure
I used an AI assistant to help trace the call path and draft the diff.
I've reviewed every changed line, validated the diagnosis against the
source, and run the local checks myself.