PreToolUse hooks: allow changing tool type (updatedToolName)

Resolved 💬 3 comments Opened Mar 17, 2026 by 0ui-labs Closed May 1, 2026

Feature Request

Problem

The PreToolUse hook currently supports updatedInput to modify a tool call's parameters, but there is no way to change the tool type itself. This means a hook cannot redirect a Read call to a Bash call, or a Grep call to a Bash call.

Use Case: CLI Token Optimization (RTK)

RTK is a CLI proxy that intercepts Bash commands and compresses their output by 60-90%, significantly reducing token consumption. It works via a PreToolUse hook that rewrites Bash commands:

Bash("cat file.ts") → Bash("rtk read file.ts")  ✅ works
Bash("rg pattern")  → Bash("rtk grep pattern")  ✅ works

However, Claude Code's system prompt instructs the model to prefer native tools (Read, Grep, Glob) over Bash equivalents. When the model uses native tools, RTK never sees the call and can't compress the output:

Read("file.ts")     → ??? cannot redirect to Bash  ❌
Grep("pattern")     → ??? cannot redirect to Bash  ❌

Current workarounds and their limitations:

| Approach | Reliability | Problem |
|----------|------------|---------|
| CLAUDE.md instructions | ~70% | Overridden by system prompt's "use dedicated tools" |
| --append-system-prompt | ~80-85% | Doesn't propagate to subagents |
| deny hook + retry | ~100% | Wastes a round-trip (more tokens than RTK saves) |
| tweakcc (unofficial) | ~100% | Fragile, breaks on updates |

Proposed Solution

Add an optional updatedToolName field to the PreToolUse hook output:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow",
    "updatedToolName": "Bash",
    "updatedInput": { "command": "rtk read file.ts" }
  }
}

This would allow a hook to transparently redirect:

  • Read({file_path: "src/foo.ts"})Bash({command: "cat src/foo.ts"})
  • Grep({pattern: "TODO", path: "src/"})Bash({command: "rg TODO src/"})
  • Glob({pattern: "**/*.ts"})Bash({command: "find . -name '*.ts'"})

Why This Matters

Token optimization proxies like RTK can save 60-90% on read operations, but only if they can intercept the calls. The current hook API makes it impossible to fully leverage these tools without unreliable prompt engineering or unofficial patches.

Alternatives Considered

  • Separate ToolRedirect hook event: More complex API surface for the same outcome
  • Making updatedInput accept a tool name field: Overloading existing field semantics
  • Adding a model-level tool preference setting: Less flexible than hooks, doesn't cover all use cases

View original on GitHub ↗

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