DEV Community

Marlon Barcarol
Marlon Barcarol

Posted on

Making Claude Code beep when it needs you

While Claude Code works, I switch to other things. Too often I came back to find it had finished long ago, or had been sitting on a permission prompt for ten minutes waiting for a yes.

I wanted two sounds:

  1. A gentle one when Claude finishes a reply.
  2. A different one when Claude needs me.

This setup is for macOS.

How to do it

Add this to ~/.claude/settings.json. That's the user-level file, so it applies to every project. If the file already has settings, merge the hooks key in rather than replacing the file.

{
  "hooks": {
    "Notification": [
      {
        "matcher": "permission_prompt|idle_prompt|elicitation_dialog",
        "hooks": [
          {
            "type": "command",
            "command": "afplay -v 0.05 /System/Library/Sounds/Hero.aiff 2>/dev/null || true",
            "async": true
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "afplay -v 0.05 /System/Library/Sounds/Blow.aiff 2>/dev/null || true",
            "async": true
          }
        ]
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

That's it. Claude Code picks up the change without a restart.

What it does

Stop runs every time Claude finishes a reply. It plays the Blow sound.

Notification runs when Claude needs you, and plays the Hero sound. The matcher limits it to three cases:

  • permission_prompt: Claude is waiting for you to approve a tool, and the prompt has waited about six seconds.
  • idle_prompt: Claude finished about 60 seconds ago and you haven't typed since.
  • elicitation_dialog: Claude is asking you a question.

afplay is the command-line audio player built into macOS. -v sets the volume from 0 to 1. The built-in sounds live in /System/Library/Sounds/, so you can swap Blow and Hero for Glass, Tink, Pop, Purr and others.

"async": true plays the sound in the background, so it never slows Claude down. 2>/dev/null || true stops a failed sound from showing up as a hook error.

Gotchas

  • The sounds are loud. I started at 0.4 and ended up at 0.05.
  • The idle sound waits about a minute. It only plays if you haven't typed since Claude finished. Typing in the terminal resets the timer.
  • In auto mode, you'll get few permission prompts. Most of your Hero sounds will come from the idle timer.
  • Test a sound on its own with afplay -v 0.05 /System/Library/Sounds/Hero.aiff, before putting it in a hook.
  • Use /hooks in Claude Code to review your hooks or turn one off.

To explore further

To get notified on your phone too, add a command to the Notification hook that sends a push through a service like ntfy, Pushover or a Telegram bot.

Top comments (0)