Feature Request: Expose Active Permission Mode to `PreToolUse` Hook

Status Fixed / completed
Maintainer reply ✓ Yes — dicksontsai
Activity 4 comments · opened Jul 29, 2025 · closed Oct 24, 2025
💡 Likely answer: A maintainer (dicksontsai, collaborator) responded on this thread — see the highlighted reply below.

Currently, the PreToolUse hook in Claude Code provides information such as tool_name and tool_input. However, it does not expose the active permission mode that Claude is operating under (e.g., "default", "acceptEdits", "plan", "bypassPermissions"). This limits the ability of external systems, such as the Serena MCP server mentioned, to implement more granular and context-aware approval workflows for tool execution.

As a user of Serena MCP server with Claude Code, I am consistently prompted for approval for file editing tools. The only alternative is to permanently approve them, which is not ideal for security and control. If the PreToolUse hook could expose the active permission mode, I could potentially configure the approval system to behave differently based on the current mode, allowing for more intelligent and less intrusive prompts.

Describe the solution you'd like
I propose adding a new field, for example, active_permission_mode, to the JSON data passed to the PreToolUse hook. This field would indicate the permission mode Claude Code is currently operating in.

Example of desired PreToolUse input:

{
  "session_id": "abc123",
  "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
  "cwd": "/Users/...",
  "hook_event_name": "PreToolUse",
  "tool_name": "Write",
  "tool_input": {
    "file_path": "/path/to/file.txt",
    "content": "file content"
  },
  "active_permission_mode": "default" // New field
}

Describe alternatives you've considered
Currently, to manage different behaviors, I am using an edit_mode variable defined inside my PreToolUse hook definition, which I manually set to reflect the desired behavior. This approach is prone to manual error and requires constant manual adjustment, making it less efficient and scalable.

Other alternatives include:

  • Constantly approving tool uses, which leads to "approval fatigue" and reduced security.
  • Keeping tools always approved, which is not ideal for secure environments.

None of these provide the desired flexibility or control compared to having the active permission mode directly available.

Additional context
Exposing the active permission mode would allow developers to create more sophisticated and user-friendly PreToolUse hook implementations, enabling conditional approval logic based on the session's permission context. This would enhance security and improve the user experience, especially in environments where fine-grained control over tool execution is critical.

View original on GitHub ↗

4 Comments

coygeek · 1 year ago

Hey, this is a great feature request. I've been wrestling with a similar issue myself when trying to build more intelligent hooks. Having to either manually approve every edit or just blanket-approve them isn't ideal, especially when you want different security postures for different tasks.

I took a look through the documentation to see if there was a way to figure this out, and it looks like you're right. The PreToolUse hook input schema in the Hooks reference doc doesn't include the permission mode. The hook runs before the permission system kicks in, so it seems like that context isn't passed down.

While we wait for a feature like this to hopefully get implemented, I've been experimenting with a workaround that's a little more dynamic than a hardcoded variable. It's not perfect, but it might help.

Since the hook's input JSON includes the cwd, the hook script can actually read the project's .claude/settings.json file to check the configured defaultMode.

Here's a rough idea of how you could do it in a bash script using jq:

#!/bin/bash

# Read the JSON input from Claude Code
input_json=$(cat)

# Get the current working directory from the input
cwd=$(echo "$input_json" | jq -r '.cwd')
project_settings_file="$cwd/.claude/settings.json"
user_settings_file="$HOME/.claude/settings.json"

# Default to 'default' mode
active_mode="default"

# Check for the mode in project settings, then user settings
if [ -f "$project_settings_file" ]; then
    mode_from_file=$(jq -r '.permissions.defaultMode // "default"' "$project_settings_file")
    if [ "$mode_from_file" != "default" ]; then
        active_mode="$mode_from_file"
    fi
elif [ -f "$user_settings_file" ]; then
    mode_from_file=$(jq -r '.permissions.defaultMode // "default"' "$user_settings_file")
    if [ "$mode_from_file" != "default" ]; then
        active_mode="$mode_from_file"
    fi
fi

# Now you can use the $active_mode variable in your logic
if [ "$active_mode" == "acceptEdits" ]; then
    # Your logic to auto-approve file edits
    echo "Auto-approving based on acceptEdits mode." >> /tmp/serena_mcp.log
    # Return JSON to approve the tool use
    echo '{"hookSpecificOutput": {"hookEventName": "PreToolUse", "permissionDecision": "allow"}}'
    exit 0
else
    # Your logic to prompt for approval
    echo "Prompting for approval in mode: $active_mode" >> /tmp/serena_mcp.log
    # Fall through to default behavior or your custom prompt logic
    exit 0 # Exit 0 to let the standard permission prompt happen
fi

The main limitation here, as mentioned in the IAM docs, is that this only gets the default mode from the settings files. It won't know if a user started a session with a temporary override like claude --permission-mode plan.

So, I completely agree that your proposed solution of adding active_permission_mode directly to the hook payload is the right way to go. It would be much cleaner, more reliable, and would cover all cases.

Thanks for writing this up. Fingers crossed the team sees this

gus-costa · 1 year ago

That's a really good solution @coygeek. I will give it a try later. Thanks!

dicksontsai collaborator · 11 months ago

This was added over a month ago. I will close this but also update the Hooks Reference documentation.

github-actions[bot] · 11 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.