Issue: Decorator type signatures lose parameter types
Summary
The MCP server decorators (@server.call_tool(), @server.list_tools(), etc.) use Callable[..., Awaitable[...]] which discards parameter type information, preventing static type checkers from validating decorated functions.
Current Behavior
# In mcp/server/lowlevel/server.py
def call_tool(self, *, validate_input: bool = True):
def decorator(
func: Callable[
..., # <-- Ellipsis loses parameter types!
Awaitable[UnstructuredContent | StructuredContent | ...],
],
):
# ...
When decorating a function:
@server.call_tool() # type: ignore # <-- Required!
async def call_tool(name: str, arguments: dict[str, object]) -> list[TextContent]:
...
Mypy cannot verify:
- Parameter names/types are correct
- Arguments are passed correctly to decorated function
- Return type matches decorator constraints
Expected Behavior
Decorators should preserve parameter types using ParamSpec:
from typing import ParamSpec, TypeVar, Callable, Awaitable
P = ParamSpec('P')
R = TypeVar('R')
def call_tool(self, *, validate_input: bool = True):
def decorator(
func: Callable[P, Awaitable[R]]
) -> Callable[P, Awaitable[R]]:
# ... wrapper implementation
return func # Type signature preserved
This would:
- ✅ Preserve parameter types through decoration
- ✅ Enable static type checking
- ✅ Eliminate need for
# type: ignore
- ✅ Improve IDE autocomplete/hints
Environment
- mcp version: 1.24.0
- Python version: 3.14 (but affects 3.10+)
- Type checker: mypy (strict mode)
Impact
The package includes py.typed marker claiming type support, but decorators break type checking. Projects using strict mypy must either:
- Disable type checking for entire MCP server modules
- Add
# type: ignore to every decorated function
- Create local type stubs to work around the issue
Workaround
Currently using broad mypy overrides:
[[tool.mypy.overrides]]
module = "myproject.mcp_server"
disable_error_code = ["misc", "no-untyped-call", "explicit-any"]
This defeats the purpose of having py.typed.
Related
Issue: Decorator type signatures lose parameter types
Summary
The MCP server decorators (
@server.call_tool(),@server.list_tools(), etc.) useCallable[..., Awaitable[...]]which discards parameter type information, preventing static type checkers from validating decorated functions.Current Behavior
When decorating a function:
Mypy cannot verify:
Expected Behavior
Decorators should preserve parameter types using
ParamSpec:This would:
# type: ignoreEnvironment
Impact
The package includes
py.typedmarker claiming type support, but decorators break type checking. Projects using strict mypy must either:# type: ignoreto every decorated functionWorkaround
Currently using broad mypy overrides:
This defeats the purpose of having
py.typed.Related