Skip to content

Tool parameters model_dump and field_model_dump collide in the generated input schema #3710

Open

Description

@inanna-malick

Initial Checks

  • Reproduced with the newest 2.x release, 2.3.0.
  • Searched the issue tracker for an existing report.

Release line

2.x (current stable)

Description

Registering a function with two ordinary parameters, model_dump and field_model_dump, succeeds. However, Client.list_tools() advertises only field_model_dump; the required Python parameter model_dump disappears from the generated input schema. I expected both parameters to remain available to clients and schema-valid inputs to bind to their original Python parameter names.

The SDK protects reserved Pydantic names by internally prefixing model_dump as field_model_dump. A real parameter already named field_model_dump collides with that generated name. The test stops at the missing schema property, before its follow-up invocation assertion.

This is adjacent to #3099 and closed PR #3416, but no user-defined Field(alias=...) is involved: the collision is between an internal generated name and a literal second parameter. Merely mapping an existing model field back to its Python name does not recover a field already overwritten during model construction.

Test: standalone failing reproduction, branch repro/tool-reserved-name-collision (diff).

From that branch, after installing its development dependencies:

uv run --frozen pytest tests/server/mcpserver/tools/test_base.py::test_tool_reserved_parameter_does_not_collide_with_prefixed_field_name -q

Observed pytest failure:

AssertionError: assert {'field_model_dump', 'model_dump'} <= dict_keys(['field_model_dump'])

Example Code

import anyio

from mcp import Client
from mcp.server.mcpserver import MCPServer


async def main() -> None:
    server = MCPServer()

    @server.tool()
    def inspect(model_dump: int, field_model_dump: int) -> str:
        return f"seen:{model_dump}:{field_model_dump}"

    async with Client(server) as client:
        (tool,) = (await client.list_tools()).tools
        assert {"model_dump", "field_model_dump"} <= tool.input_schema["properties"].keys()


anyio.run(main)

Python & MCP Python SDK

Python 3.14.7 / Pydantic 2.12.5. Fails on latest stable mcp/mcp-types 2.3.0 (2118f14) and current main 754254c. Each targeted run: 1 intentional failure, 2 passing existing controls. The same test runs against each version’s source.

AI-assisted investigation and test reproduction, with a human in the loop.

Activity

  1. added
    bugSomething isn't working
    v2Affects the v2 line (2.x on main)
    v1Affects the v1.x maintenance line
    on Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingv1Affects the v1.x maintenance linev2Affects the v2 line (2.x on main)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions