You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A tool with a *args or **kwargs parameter is registered with a schema it can never satisfy #3514
I confirm that I'm using the newest release of my line (2.x, main at 6affe5c)
I confirm that I searched for my issue in the issue tracker before opening this issue
Release line
2.x (current stable)
Description
Registering a tool whose function signature has a *args or **kwargs
parameter succeeds, and the tool shows up in list_tools, but it can never
actually be called: the generated JSON schema lists args/kwargs as a
required parameter of a plain scalar type, which doesn't match how the
function actually receives those values.
Expected: either the decorator rejects a signature it can't turn into a
schema (it already does this for a leading underscore in a parameter name),
or the schema reflects what the function accepts.
Actual: the tool is silently registered and permanently uncallable. Calling
it with only the named parameters filled in fails schema validation because args/kwargs is "missing"; there's no way to actually supply it, since a
JSON object has no way to express "and then also a variable number of
positional values" for a single scalar field.
I have a patch that raises InvalidSignature for a *args/**kwargs tool
parameter at registration time, scoped so it doesn't affect resource
templates (which legitimately use **kwargs for runtime-determined URI
variables); happy to open a PR against this issue if that's the direction
you'd want.
One additional signature shape reproduces the same registration/invocation mismatch: def inspect(value: str, /) -> str. On latest stable 2.3.0 (2118f14) and current main 754254c, registration succeeds and the published schema advertises value, but schema-valid {"value": "ok"} returns is_error=True.
The captured cause is got some positional-only arguments passed as keyword arguments: 'value'. This extends the evidence beyond the *args/**kwargs examples already reported. Whether to reject unsupported signatures at registration or support positional binding is a maintainer policy decision; the failing test demonstrates that the currently advertised schema is not callable.
From that branch, after installing its development dependencies:
uv run --frozen pytest tests/server/mcpserver/tools/test_base.py::test_positional_only_tool_parameter_has_a_callable_schema -q
Python 3.14.7 / Pydantic 2.12.5; both source versions report 1 intentional failure and 2 passing existing controls. No production changes are included.
AI-assisted investigation and test reproduction, with a human in the loop.
Activity
Mohammedib24 commentedon Sep 19, 2026
I reproduced this issue on the current
mainbranch and prepared a fix in PR #3538.The fix rejects
*argsand**kwargsfor tool signatures withInvalidSignature, while preserving**kwargssupport for resource templates.I also added regression tests and verified the relevant test suite passes.
inanna-malick commentedon Oct 14, 2026
One additional signature shape reproduces the same registration/invocation mismatch:
def inspect(value: str, /) -> str. On latest stable 2.3.0 (2118f14) and current main 754254c, registration succeeds and the published schema advertisesvalue, but schema-valid{"value": "ok"}returnsis_error=True.The captured cause is
got some positional-only arguments passed as keyword arguments: 'value'. This extends the evidence beyond the*args/**kwargsexamples already reported. Whether to reject unsupported signatures at registration or support positional binding is a maintainer policy decision; the failing test demonstrates that the currently advertised schema is not callable.Test: standalone failing reproduction, branch
repro/tool-positional-only(diff).From that branch, after installing its development dependencies:
Python 3.14.7 / Pydantic 2.12.5; both source versions report 1 intentional failure and 2 passing existing controls. No production changes are included.
AI-assisted investigation and test reproduction, with a human in the loop.