Skip to content

Feature: enforce tool annotation hints (readOnlyHint/destructiveHint/idempotentHint) #2937

Closed as not planned

Description

@tcconnally

Feature Request: Enforce tool annotation hints (readOnlyHint/destructiveHint/idempotentHint)

Problem

The MCP spec defines three tool annotation hints (readOnlyHint, destructiveHint, idempotentHint) to help clients understand tool behavior. The python-sdk accepts these annotations on tool registration but does nothing with them — they're passed through to list_tools responses as metadata only.

This means:

  1. A tool marked destructiveHint=True can still be called without any confirmation or gating
  2. A tool marked readOnlyHint=True could modify state without the SDK detecting the mismatch
  3. There's no validation that annotations match actual tool behavior

Real-world Impact

I maintain two MCP servers (Perseus, 27+ tools; Mimir, 26+ tools) that extensively use these annotations. We mark tools that write to memory as destructiveHint=True and tools that only read as readOnlyHint=True. But the annotations are purely advisory — the python-sdk doesn't help us enforce them.

Proposed Solution

Add an optional configuration that enables annotation-based gating:

server = Server(
    "my-server",
    enforce_tool_hints=True  # opt-in
)

@server.tool(readOnlyHint=True, destructiveHint=False)
async def search_docs(query: str) -> list[str]:
    # SDK could validate this doesn't call any write operations
    ...

At minimum:

  1. Log a warning when a destructiveHint=True tool is called (security boundary)
  2. Option to require explicit client confirmation before destructive tool calls
  3. Optional validation hook: a callback that fires before destructive tool execution

Why This Matters

Without SDK-level enforcement, tool annotations are documentation — not security boundaries. Every MCP server implementor has to build their own enforcement layer, leading to inconsistent behavior across the ecosystem.

Happy to Contribute

I'm willing to submit a PR if the design direction is acceptable. Would propose starting with a simple destructive-tool logging warn + optional confirmation gate.

Activity

  1. maxisbey commented on Jun 22, 2026

    @maxisbey
    Contributor

    Hey! These annotations are hints only, as the spec says "all properties in ToolAnnotations are hints. They are not guaranteed to provide a faithful description of tool behavior".

    These annotations are for the server author to decide to use or not. If a server author decides to mark their tool as read only then it is their responsibility to make sure their tool actually is read only. It is also impossible for the SDK to actually know whether a tool is read only or destructive or not, server authors can write any code in there they want and there's no way for the SDK to know what side effects may occur.

    As for logging a warning, this would just be added noise that doesn't really add anything helpful.

    Thanks for the ticket, but closing this for now.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions