Skip to content

MCP: ToolAnnotations silently accepts misspelled hints #142

Description

@LukasGold

ToolAnnotations in the MCP Python SDK is configured with extra="allow":

# mcp/types/_types.py:1033
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True, extra="allow")

So a misspelled hint is accepted, stored as an extra field, and silently does nothing:

ToolAnnotations(readOnlyHnt=True)   # no error, no effect

The valid fields are readOnlyHint, destructiveHint, idempotentHint, openWorldHint (_types.py:1365-1400). A wrong name produces a tool whose annotations are missing, with no warning at build time, no test failure, and no runtime symptom. The visible consequence is client-side: a read-only tool that is not marked read-only gets treated as mutating.

Our mitigation (in the shared-core refactor for #133): Operation carries four explicitly typed Optional[bool] fields rather than an open dict, and the adapter constructs ToolAnnotations by keyword, not **dict, so a wrong name is a TypeError. A test asserts every hint maps to a declared field.

Remaining action: report upstream at https://github.com/modelcontextprotocol/python-sdk, since extra="allow" on a fixed, spec-defined set of boolean hints trades a useful error for nothing. Keep our guard test regardless.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions