Skip to content

Dataclass structured outputs mishandle slots and InitVar fields #3711

Open

Description

@inanna-malick

Initial Checks

Release line

2.x (current stable)

Description

Two standard dataclass configurations fail when used as structured tool outputs. With @dataclass(slots=True), schema derivation silently falls back to unstructured output: func_metadata(produce).output_schema is None. With an InitVar[str] constructor parameter, metadata construction instead raises PydanticForbiddenQualifier because the constructor-only annotation is treated as a model field.

I expected the schema and structured result to contain the dataclass's instance fields. A constructor-only InitVar should not become an output property. The ordinary dataclass control passes, and Pydantic's own TypeAdapter serializes both variants to {"value": "ok"} in the same environments. These cases matter when an existing dataclass is reused as a tool return value.

Example Code

from dataclasses import InitVar, dataclass
from mcp.server.mcpserver.utilities.func_metadata import func_metadata

@dataclass(slots=True)
class Slotted:
    value: str

def slotted() -> Slotted:
    return Slotted("ok")

print(func_metadata(slotted).output_schema)  # None

@dataclass
class ConstructorOnly:
    value: str
    token: InitVar[str]

def constructor_only() -> ConstructorOnly:
    return ConstructorOnly("ok", "constructor-only")

func_metadata(constructor_only)  # PydanticForbiddenQualifier

Two deterministic, intentionally failing tests are on this test-only branch; no production changes. Run either case independently, for example:

uv run --frozen pytest tests/server/mcpserver/test_func_metadata.py::test_slotted_dataclass_structured_output_has_instance_fields -q

Python & MCP Python SDK

Python 3.14.7; Pydantic 2.12.5; MCP 2.3.0 (tag v2.3.0, 2118f14f8a19bc158d8a1cf90af58d85d187f849). Also reproduced using main source at 754254c08fe1c3eda18b69da3d336106fe8d72d6.

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