claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[DOCS] Missing documentation for modifying tool inputs in PreToolUse hooks

Open coygeek opened this issue 2 months ago • 4 comments

Documentation Type

Missing documentation (feature not documented)

Documentation Location

https://docs.claude.com/en/docs/claude-code/hooks-guide https://docs.claude.com/en/docs/claude-code/hooks

Section/Topic

The "Hook Output" and "PreToolUse Decision Control" sections in the Hooks reference documentation.

Current Documentation

The current documentation for PreToolUse hooks explains that they can return a JSON object to control the permission decision (allow, deny, or ask), but does not mention any mechanism for modifying the tool's input parameters.

The relevant section in en/docs/claude-code/hooks states:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow" | "deny" | "ask",
    "permissionDecisionReason": "My reason here"
  }
}

This structure only allows for approving or denying the original tool call, not altering it before execution.

What's Wrong or Missing?

A recent changelog mentions a new feature: "PreToolUse hooks can now modify tool inputs".

This powerful feature is completely missing from the documentation. The current docs only describe how to inspect the tool input and then allow or deny the action. There is no mention of a field or mechanism (e.g., an updatedInput key) that would allow a hook to transparently modify the parameters of a tool call before it executes.

This leaves users unaware of a key capability for building more sophisticated and efficient hooks that can correct, redirect, or enhance tool calls on the fly.

Suggested Improvement

The "PreToolUse Decision Control" section should be updated to include a new optional field in the JSON output, likely named updatedInput.

Suggested Text Update:

In addition to controlling permissions, PreToolUse hooks can modify the input parameters of a tool call before it is executed. To do this, return a JSON object with permissionDecision: "allow" and include the updatedInput key containing the modified tool parameters. This allows for transparent redirection, correction, or enforcement of conventions without requiring an extra conversational turn.

Example JSON Output with Input Modification:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow",
    "updatedInput": {
      "file_path": "./sandbox/report.txt",
      "content": "This is the original content."
    },
    "permissionDecisionReason": "Redirected write operation to the sandbox directory."
  }
}

Suggested Code Example:

A clear code example is crucial. Here is a Python example for a hook that transparently redirects all file writes to a sandbox/ directory.

File: .claude/hooks/redirect_writes.py

#!/usr/bin/env python3
import json
import sys
import os

# Load the hook input from stdin
input_data = json.load(sys.stdin)

tool_name = input_data.get("tool_name")
tool_input = input_data.get("tool_input")
output = {} # Default: an empty JSON object allows the tool to proceed

# Only act on file writing tools
if tool_name in ["Write", "Edit", "MultiEdit"]:
    file_path = tool_input.get("file_path")

    # If a path is provided and it's not already in the sandbox...
    if file_path and not file_path.startswith("sandbox/"):
        # ...transparently redirect it.
        new_path = os.path.join("sandbox", os.path.basename(file_path))
        
        updated_input = tool_input.copy()
        updated_input["file_path"] = new_path

        # Return a JSON object to modify the input and allow the call.
        output = {
            "hookSpecificOutput": {
                "hookEventName": "PreToolUse",
                "permissionDecision": "allow",
                "updatedInput": updated_input, 
                "permissionDecisionReason": f"Redirected write from '{file_path}' to '{new_path}'"
            }
        }

# Print the JSON output to stdout for Claude Code to process
print(json.dumps(output))
sys.exit(0)

Corresponding settings.json configuration:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/redirect_writes.py"
          }
        ]
      }
    ]
  }
}

Impact

High - Prevents users from using a feature

Additional Context

This new hook functionality would bring it in line with the capabilities of the SDK's canUseTool callback, which already supports input modification via an updatedInput field in its PermissionResult.

From en/api/agent-sdk/typescript:

type PermissionResult = 
  | {
      behavior: 'allow';
      updatedInput: ToolInput;
      updatedPermissions?: PermissionUpdate[];
    }
  | {
      behavior: 'deny';
      message: string;
      interrupt?: boolean;
    }

Aligning the PreToolUse hook's capabilities with the SDK's callback would create a more consistent and predictable developer experience across the Claude Code ecosystem.

coygeek avatar Oct 08 '25 22:10 coygeek

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/4368
  2. https://github.com/anthropics/claude-code/issues/2991
  3. https://github.com/anthropics/claude-code/issues/6966

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

github-actions[bot] avatar Oct 08 '25 22:10 github-actions[bot]

thx.

Adamcf123 avatar Oct 09 '25 08:10 Adamcf123

Updated typescript code with this. Thanks!

Pentadome avatar Oct 13 '25 12:10 Pentadome

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

github-actions[bot] avatar Dec 07 '25 10:12 github-actions[bot]