Developer guide · macOS

Play a sound when Codex finishes or needs your input

Prompt, walk away, and let Codex tap you on the shoulder — a sound when it finishes a task, and a different one when it's waiting on your approval. Here's the 2-minute setup, free, using a built-in macOS command and Codex's own hooks.

Last updated: June 2026 · ~2 minute setup · Works with Codex CLI on macOS

TL;DR

Add this to ~/.codex/hooks.json and restart Codex. You'll hear one sound when Codex finishes and a different one when it needs your approval:

{
  "hooks": {
    "Stop": [
      { "hooks": [ { "type": "command", "command": "afplay /System/Library/Sounds/Glass.aiff &" } ] }
    ],
    "PermissionRequest": [
      { "hooks": [ { "type": "command", "command": "afplay /System/Library/Sounds/Funk.aiff &" } ] }
    ]
  }
}

Why this works

Codex CLI fires hooks on lifecycle events, and a hook just runs a shell command — the same model as Claude Code, in a global ~/.codex/hooks.json. Two events matter here:

afplay is macOS's built-in audio player — nothing to install. Point the two events at two different sounds and you've got distinct "done" and "needs you" alerts. That's the entire trick.

Why hooks.json and not config.toml

Codex's config.toml has a single notify slot, and the Codex desktop app already claims it. hooks.json is a separate file with a list of hooks per event — so it never fights the app's notifications, and it gives you a real PermissionRequest "needs you" event, not just "done".

Step-by-step

  1. Open your hooks file. Edit ~/.codex/hooks.json (create it if it doesn't exist). It's global, so it applies to every project.
  2. Add the hooks. Paste the "hooks" block from the TL;DR. If you already have a "hooks" key, merge the Stop and PermissionRequest entries into it rather than replacing it.
  3. Pick two distinguishable sounds. The goal is that "done" and "needs you" are instantly tellable apart by ear.
  4. Restart Codex and trust the hook. Hooks load at session start, so restart Codex. On its next launch it'll ask you to trust the new hook — approve it once.

Use your own sounds

Swap the system sound for any .aiff, .mp3, .wav, or .m4a on disk:

"command": "afplay ~/Sounds/codex-done.mp3 &"

The built-in system sounds live in /System/Library/Sounds/ — Glass, Funk, Ping, Hero, Submarine, Blow, and more. List them with:

ls /System/Library/Sounds/

Which Codex version do you need?

Both events are recent additions to Codex CLI's hook system. Run a current Codex and you'll have all of them:

On older versions the unsupported event simply never fires — no errors, just no sound. Check your version with codex --version.

Troubleshooting

If you hear nothing

Run afplay /System/Library/Sounds/Glass.aiff directly in your terminal. If that's silent, it's your output device or volume — not the hook.

If the command works but the hook doesn't fire, make sure you restarted Codex after editing hooks.json and approved the trust prompt — hooks only load at session start, and Codex won't run an untrusted hook.

Linux & Windows

The hooks are identical everywhere Codex runs; only the sound command changes. Linux: paplay sound.wav or aplay sound.wav. Windows: powershell -c "(New-Object Media.SoundPlayer 'C:\path\sound.wav').PlaySync()".

Skip the setup: MacYaps

The hook is simple — living with it is the annoying part. A single afplay ding gets old fast, you're hand-editing JSON, every machine needs the same setup, and "done" and "needs you" end up sounding the same. MacYaps is the convenience layer on the exact mechanism above — and it already speaks for Claude Code, so one app covers both agents.

FAQ

How do I make Codex play a sound when it's done?

Add a Stop hook to ~/.codex/hooks.json that runs a sound command like afplay /System/Library/Sounds/Glass.aiff. Codex fires the Stop event when it finishes a turn, so the sound plays every time a task completes. Restart Codex afterward so it loads the hook.

Can I get a sound when Codex needs my approval?

Yes — add a PermissionRequest hook pointing at a different sound. Codex fires it when it asks to run a sensitive operation, so you hear a distinct alert the moment it's waiting on you. (Requires Codex CLI v0.122+.)

Where is the Codex hooks file?

It's ~/.codex/hooks.json — a global file that applies to every session, with the same JSON shape as Claude Code's settings.json hooks. It's separate from config.toml, so it doesn't conflict with the notify program the Codex desktop app uses.

Does this work without MacYaps?

Completely. The setup on this page is the whole mechanism and uses only afplay, which ships with macOS. MacYaps just automates it and adds voices and a UI.

Which Codex version do I need?

Stop works on Codex CLI v0.114+ and PermissionRequest on v0.122+. On older versions the unsupported event simply never fires.

Does this work on Linux or Windows?

Yes — the hooks are the same; only the sound command changes (paplay/aplay on Linux, PowerShell's Media.SoundPlayer on Windows).

Related guides