[FEATURE] PreToolUse hooks should be able to replace the default tool call rendering

Resolved 💬 4 comments Opened Feb 16, 2026 by m-wells Closed Mar 17, 2026

Problem

When a PreToolUse hook returns a permissionDecisionReason, the formatted output is shown alongside the default raw tool parameters — not instead of them. For MCP tools with large inputs (e.g., an edit_file tool with old_string/new_string parameters), this means the user sees:

  1. The raw escaped parameters (often hundreds of lines of unreadable \n and \" text)
  2. The hook's formatted output (e.g., a clean unified diff)

This duplication floods the scroll buffer and defeats the purpose of the hook formatting the output in the first place.

Use Case

I maintain Catenary, an MCP server that bridges LSP and MCP. Its edit_file tool takes old_string and new_string parameters that are displayed as raw escaped JSON in the approval prompt — completely unreadable for code review.

I wrote a PreToolUse hook that formats these as a colorized unified diff, which works well, but the raw parameters still render above it. The hook output is additive rather than a replacement.

Proposal

Add a field to hookSpecificOutput (e.g., replaceToolDisplay: true or renderedOutput: "...") that lets a PreToolUse hook replace the default tool call rendering in the approval prompt rather than appending alongside it.

This would let MCP tool authors and plugin developers provide first-class rendering for their tools — putting them on par with built-in tools like Edit and Write that already have clean diff displays.

Alternatives Considered

  • updatedInput: modifies the actual tool input, not just the display — can't use this for formatting
  • Writing to stderr: only visible in verbose mode on exit 0
  • Accepting the duplication: workable but the scroll buffer bloat is significant for large edits

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗