Free browser tool

Claude Code hooks generator

Generate a Claude Code hooks settings.json block by choosing an event, an optional matcher and a shell command. The JSON updates in your browser, ready to copy into user, project or local settings. No account, cookies or network connection is needed.

Leave blank to match every occurrence. Tool events use names such as Bash or Edit|Write. Events without matcher support ignore this field.

Claude Code runs this shell command and sends the event JSON to its standard input.

Your settings.json block

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude finished responding\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

Where this file lives

  • User settings: ~/.claude/settings.json applies to all your projects on this computer.
  • Project settings: .claude/settings.json applies to one project and can be committed to share with the team.
  • Local settings: .claude/settings.local.json applies only to your local copy of one project and should stay out of git.

Merge this block with your existing settings instead of replacing other configuration. Hook entries from user, project and local settings are additive. Check the official Claude Code hooks reference for matcher values, event input and command output.

Ready-made Claude Code hooks examples

Notify when Claude stops

Show a macOS notification after Claude Code finishes responding.

osascript -e 'display notification "Claude finished responding" with title "Claude Code"'

Play a sound on Notification

Play the macOS Ping sound when Claude Code sends a notification.

afplay /System/Library/Sounds/Ping.aiff

Block rm -rf in PreToolUse

Exit with code 2 when a Bash command contains rm -rf. Review and extend this simple check for your own safety rules.

python3 -c 'import json,sys; command=json.load(sys.stdin).get("tool_input",{}).get("command",""); blocked="rm -rf" in command; print("Blocked a command containing rm -rf",file=sys.stderr) if blocked else None; sys.exit(2 if blocked else 0)'

Format after Edit

Pass the edited file path to prettier. This example requires jq and prettier on PATH.

sh -c 'file=$(jq -r .tool_input.file_path); prettier --write "$file"'

Examples are starting points. Review every command before enabling it, and adjust paths or programs for your operating system.