Surface MCP tool annotations (readOnlyHint/destructiveHint) in PreToolUse hook input

Status Open
Maintainer reply None cached
Activity 1 comment · opened Aug 4, 2026

Feature request

Surface MCP tool annotations (readOnlyHint, destructiveHint, openWorldHint) in PreToolUse hook input.

Problem

PreToolUse hooks receive tool_name and tool_input for MCP tools, but not the tool's declared MCP annotations. A hook that wants to gate writes cannot tell a read-only MCP tool from a destructive one without maintaining a name-based deny list, which breaks as servers are added or renamed.

The MCP spec already defines these hints on the tool object (annotations.readOnlyHint, annotations.destructiveHint), and Claude Code has them at dispatch time — they just aren't forwarded to the hook.

Concrete use case

We maintain a workflow-enforcement plugin whose PreToolUse hooks block file writes during planning/review phases. The hooks match built-in tool names (Write|Edit|MultiEdit|NotebookEdit, Bash). Any write-capable MCP tool bypasses the gates entirely, because:

  • a blanket mcp__.* deny would break read-only research tools the planning phases depend on;
  • guessing write-ness from tool names is unreliable;
  • a hand-maintained deny list rots as MCP servers change.

With annotations in the hook input, the hook could allow readOnlyHint: true tools everywhere and gate the rest — capability-based instead of name-based.

Proposed shape

Add an optional field to PreToolUse (and PostToolUse) hook input for MCP tools, e.g.:

{
  "tool_name": "mcp__server__tool",
  "tool_input": { ... },
  "tool_annotations": {
    "readOnlyHint": true,
    "destructiveHint": false
  }
}

Annotations are optional in the MCP spec, so the field would be absent or partial when a server doesn't declare them — hooks can then fall back to their own policy for unannotated tools.

Environment

  • Claude Code CLI on macOS (darwin)
  • Verified against the hooks documentation, 2026-08-04: hook input for tool events carries tool_name/tool_input only, no annotation metadata.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗