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:
- A tool marked
destructiveHint=True can still be called without any confirmation or gating
- A tool marked
readOnlyHint=True could modify state without the SDK detecting the mismatch
- 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:
- Log a warning when a
destructiveHint=True tool is called (security boundary)
- Option to require explicit client confirmation before destructive tool calls
- 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.
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 tolist_toolsresponses as metadata only.This means:
destructiveHint=Truecan still be called without any confirmation or gatingreadOnlyHint=Truecould modify state without the SDK detecting the mismatchReal-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=Trueand tools that only read asreadOnlyHint=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:
At minimum:
destructiveHint=Truetool is called (security boundary)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.