SaaSsassin
ReplacementsCustom Build
How-to Guides
Step-by-step tutorials and tips
Blog
News, insights, and updates
Suggest TargetGet Quote
Claude Code beginner 5 min read

Get Voice Notifications When Claude Code Needs Your Attention

Learn how to configure Claude Code to speak audio alerts when it needs input or completes a task. Works on macOS, Windows, and Linux with simple settings.json hooks.

Ever walked away from your terminal while Claude Code was working, only to come back and find it’s been waiting for your input for ages? Or maybe you’re working on something else and want to know when Claude finishes a long task?

This guide shows you how to make Claude Code speak to you when it needs attention or completes work—using built-in OS speech synthesis and Claude Code’s powerful hooks system.

What Are Claude Code Hooks?

Hooks are custom shell commands that Claude Code executes at specific lifecycle events. You can trigger actions when:

  • Notification — When Claude needs your attention
  • Stop — When Claude finishes or pauses
  • SubagentStop — When a background sub-agent completes
  • PreToolUse — Before Claude uses a tool
  • PostToolUse — After Claude uses a tool

We’ll use Notification, Stop, and SubagentStop hooks to play voice alerts.

Quick Start: The Settings File

Claude Code stores its configuration in settings.json. The location varies by OS:

OSPath
macOS~/.claude/settings.json
Linux~/.claude/settings.json
Windows%USERPROFILE%\.claude\settings.json

If the file doesn’t exist, create it. Here’s how to find/create it:

# macOS/Linux - Open or create the settings file
mkdir -p ~/.claude && nano ~/.claude/settings.json

# Windows PowerShell - Open or create the settings file
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.claude"
notepad "$env:USERPROFILE\.claude\settings.json"

Windows: Complete Working Configuration

Here’s a tested, working configuration for Windows using the SAPI COM object:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "powershell -Command \"(New-Object -ComObject SAPI.SpVoice).Speak('Claude has finished')\"",
            "timeout": 10
          }
        ]
      }
    ],
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "powershell -Command \"(New-Object -ComObject SAPI.SpVoice).Speak('Claude needs your attention')\"",
            "timeout": 10
          }
        ]
      }
    ],
    "SubagentStop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "powershell -Command \"(New-Object -ComObject SAPI.SpVoice).Speak('Sub agent has completed')\"",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Key Points

  • timeout — Prevents hooks from hanging; 10 seconds is usually plenty
  • SAPI.SpVoice — Windows Speech API COM object; works out of the box
  • SubagentStop — Fires when background agents (launched via Task tool) complete

Customizing Windows Voices

List available voices in PowerShell:

# List all installed voices
$voice = New-Object -ComObject SAPI.SpVoice
$voice.GetVoices() | ForEach-Object { $_.GetDescription() }

Use a specific voice:

{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "powershell -Command \"$v = New-Object -ComObject SAPI.SpVoice; $v.Voice = $v.GetVoices() | Where-Object { $_.GetDescription() -like '*Zira*' } | Select-Object -First 1; $v.Speak('Claude needs your attention')\"",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Common Windows Voices

VoiceDescription
Microsoft DavidAmerican male
Microsoft ZiraAmerican female
Microsoft MarkAmerican male
Microsoft HazelBritish female

Tip: Install additional voices via Settings → Time & Language → Speech → Add voices.

macOS: Using the say Command

macOS has a built-in say command that converts text to speech.

Basic Configuration

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "say 'Claude has finished'",
            "timeout": 10
          }
        ]
      }
    ],
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "say 'Claude needs your attention'",
            "timeout": 10
          }
        ]
      }
    ],
    "SubagentStop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "say 'Sub agent has completed'",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Customizing the Voice

macOS has dozens of voices. List them with:

say -v '?'

Use a specific voice by adding the -v flag:

{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "say -v 'Samantha' 'Hey! Claude needs your input'",
            "timeout": 10
          }
        ]
      }
    ]
  }
}
VoiceDescription
SamanthaClear American female (default)
AlexAmerican male, very natural
DanielBritish male
KarenAustralian female
MoiraIrish female
TessaSouth African female
WhisperWhispering voice

Adjusting Speech Rate

Speed up or slow down with the -r flag (words per minute):

# Faster (250 wpm)
say -r 250 'Claude needs attention'

# Slower (150 wpm)
say -r 150 'Claude has completed'

Linux: Using espeak or festival

Linux doesn’t have built-in speech, but you can install lightweight TTS tools.

Using espeak

Install espeak:

# Ubuntu/Debian
sudo apt install espeak

# Fedora
sudo dnf install espeak

# Arch
sudo pacman -S espeak

Configure Claude Code:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "espeak 'Claude has finished'",
            "timeout": 10
          }
        ]
      }
    ],
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "espeak 'Claude needs your attention'",
            "timeout": 10
          }
        ]
      }
    ],
    "SubagentStop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "espeak 'Sub agent has completed'",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Using festival

Festival sounds more natural than espeak:

# Ubuntu/Debian
sudo apt install festival

# Usage
echo "Claude needs your attention" | festival --tts
{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Claude needs your attention' | festival --tts",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Advanced: Conditional Notifications with Matchers

Use the matcher field to trigger hooks only for specific tools or conditions.

Only Notify on Specific Tools

Play a sound only when Claude wants to use the Bash tool:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "say 'Claude wants to run a command'",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Combining Multiple Hook Types

{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "say -v 'Samantha' 'Hey! I need your help'",
            "timeout": 10
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "say -v 'Samantha' 'All done!'",
            "timeout": 10
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "say -v 'Whisper' 'Running command'",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

Playing Sound Effects Instead

Don’t want voice? Play an audio file instead.

macOS

{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "afplay /System/Library/Sounds/Glass.aiff",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

Built-in macOS sounds are in /System/Library/Sounds/:

  • Glass.aiff
  • Ping.aiff
  • Pop.aiff
  • Submarine.aiff
  • Hero.aiff

Windows

{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "powershell -Command \"(New-Object Media.SoundPlayer 'C:\\Windows\\Media\\chimes.wav').PlaySync()\"",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

Linux

{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "aplay /usr/share/sounds/alsa/Front_Center.wav",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

Install aplay if needed: sudo apt install alsa-utils

Troubleshooting

Hook Not Firing?

  1. Check JSON syntax — Use a JSON validator (jsonlint.com)
  2. Check file location — Must be in ~/.claude/settings.json (or Windows equivalent)
  3. Restart Claude Code — Changes require restart
  4. Test command manually — Run the command in terminal first
  5. Check timeout — If command takes too long, it may be killed

Voice Not Playing?

macOS:

# Test say command
say "test"

# Check audio output
system_profiler SPAudioDataType

Windows:

# Test SAPI speech
(New-Object -ComObject SAPI.SpVoice).Speak("test")

Linux:

# Test espeak
espeak "test"

# Check audio
aplay -l

Common Issues

IssueSolution
No sound on WindowsCheck volume, run (New-Object -ComObject SAPI.SpVoice).Speak("test") in PowerShell
Hook times outIncrease timeout value or use async playback
JSON parse errorValidate JSON syntax, escape backslashes on Windows
Command not foundUse full path to executable

Complete Cross-Platform Configuration

Here’s a complete configuration that works well in practice:

Windows

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "powershell -Command \"(New-Object -ComObject SAPI.SpVoice).Speak('Claude has finished')\"",
            "timeout": 10
          }
        ]
      }
    ],
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "powershell -Command \"(New-Object -ComObject SAPI.SpVoice).Speak('Claude needs your attention')\"",
            "timeout": 10
          }
        ]
      }
    ],
    "SubagentStop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "powershell -Command \"(New-Object -ComObject SAPI.SpVoice).Speak('Sub agent has completed')\"",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

macOS

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "say 'Claude has finished'",
            "timeout": 10
          }
        ]
      }
    ],
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "say 'Claude needs your attention'",
            "timeout": 10
          }
        ]
      }
    ],
    "SubagentStop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "say 'Sub agent has completed'",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Conclusion

With a few lines of configuration, you can turn Claude Code into a vocal assistant that keeps you informed without constant terminal monitoring. The timeout field ensures hooks never hang, and SubagentStop catches those background agent completions you might otherwise miss.

Now you’ll never miss when Claude needs your input—or when it’s finished working its magic.


Next steps: