To get Codex CLI to notify you when it is done, you often need no setup. The built-in [tui] notifications fire when a turn finishes and when an approval is waiting, but by default only while its terminal is in the background: a desktop notification in Ghostty, iTerm2, Kitty, Warp and WezTerm, and the terminal bell everywhere else, including Windows Terminal and VS Code. Set notification_condition = "always" to get them with the window in front too. For alerts you will not miss, add Stop and PermissionRequest hooks to ~/.codex/hooks.json, or run npx anotifier@latest setup to send both to your desktop and phone. Here is every option, then Codex on Windows, how to make Codex play a sound and how to turn the alerts off.
Rather skip the manual setup? One command wires every agent you have installed to desktop toasts, phone push, and Slack, Discord or Telegram:
Updated 2026-10-22 · also see the Codex CLI overview and the full docs
The Codex TUI notifies you out of the box when a turn ends, when it asks to run a command or edit files, and when a Plan mode prompt or a question is waiting. It sends an OSC 9 desktop notification in terminals that support it and rings the bell in the rest, and by default only while the terminal is unfocused. Tune it under [tui] in ~/.codex/config.toml:
[tui]
notifications = ["agent-turn-complete", "approval-requested"]
notification_method = "auto" # or "osc9", "bel"
notification_condition = "always" # default "unfocused"What you get: alerts in this machine's terminal only, and nothing on your phone. Whether you hear anything depends on the terminal; to make Codex ding when it needs approval, see the sound guide.
Codex CLI can run an external program through the notify setting in ~/.codex/config.toml. Codex currently sends it one event, agent-turn-complete, as a JSON argument with fields such as thread-id, last-assistant-message, and input-messages. Your script turns that into a toast, sound, or push. Codex ignores notify in a project's .codex/config.toml, so set it in your user config:
notify = ["python3", "/Users/you/codex-notify.py"]What you get: turn-complete alerts only, with whatever your script does. Approval prompts are not covered by notify, which is the moment you most need to hear about.
Codex CLI 0.144 and newer ship a hooks system modelled on Claude Code's. Hooks live in ~/.codex/hooks.json and are on by default in current releases (early ones needed hooks = true under [features] in config.toml). Stop fires when the turn ends. PermissionRequest fires when Codex is about to ask for approval, and only then. A hook entry looks like this:
{
"hooks": {
"Stop": [
{
"hooks": [
{ "type": "command", "command": "notify-send \"Codex\" \"Turn complete\"", "timeout": 10 }
]
}
],
"PermissionRequest": [
{
"hooks": [
{ "type": "command", "command": "notify-send -u critical \"Codex\" \"Needs approval\"", "timeout": 10 }
]
}
]
}
}npx anotifier@latest setupThe wizard detects ~/.codex, writes Stop, PermissionRequest, and SessionStart hooks into ~/.codex/hooks.json, enables the hooks feature flag, records the trust hashes in config.toml, and backs up hooks.json first. A finished turn arrives as my-app · Codex at default priority; an approval request arrives urgent, on your desktop and phone, so the run never sits blocked while you are in another window. The approval path is proven in CI by driving the real Codex TUI through a permission modal.
| Feature | Built-in | DIY hook | anotifier |
|---|---|---|---|
| Desktop toast | Terminal-dependent | Yes, fixed text | Yes, Windows · macOS · Linux · WSL |
| Phone push | No | With a curl to ntfy | Yes, ntfy, generic by default |
| Slack / Discord / Telegram | No | Write the JSON yourself | Yes, pick a format |
| Shows what the agent said | No | No | Yes for Claude Code (toast + webhook) |
| Names the project | No | Hard-code it | Yes, my-app · Claude Code in every title |
| Urgent for approvals, calm for done | No | Two hooks, two scripts | Yes, per-event priority |
| Click to focus the window | No | No | Yes (Windows) |
| Every agent, one config | No | Repeat per agent | Yes |
| Snooze / quiet hours | No | No | Yes |
| Setup time | 1 setting | 10–20 min per agent | One command |
anotifier is free, open source (AGPL-3.0), has zero dependencies, and uninstalls cleanly with anotifier uninstall. Full reference in the docs.
Codex CLI runs natively on Windows and keeps its settings in %USERPROFILE%\.codex: CODEX_HOME defaults to ~/.codex. The built-in notification works as described in Option 1, with one catch. With notification_method = "auto", Codex sends OSC 9 only to Ghostty, iTerm2, Kitty, Warp, and WezTerm. Windows Terminal and the VS Code terminal are not on that list, so Codex rings the bell (BEL) there and no desktop notification appears. That is how Codex CLI 0.163.0, the latest release at the time of writing, behaves.
bellStyle setting accepts audible (the default), window, taskbar, all, and none. Microsoft documents all as a sound plus a flashing taskbar icon, and says that when the terminal is not in focus only the taskbar icon flashes. Codex notifies only while the window is unfocused by default, so check what your bellStyle does in the background.accessibility.signals.terminalBell setting. If you hear nothing, check that setting.To change it for every profile, set bellStyle under profiles.defaults in Windows Terminal's settings.json:
{
"profiles": {
"defaults": { "bellStyle": "all" }
}
}For a real Windows notification, use a hook. Codex hooks accept commandWindows, an optional Windows-only replacement for command, and by default Codex starts a hook through cmd.exe /C. This version needs no module install. It reuses the Windows PowerShell 5.1 toast from the WSL toast guide. Save it as %USERPROFILE%\.codex\win-toast.ps1:
param(
[string]$Title = 'Codex',
[string]$Message = 'Done'
)
$ErrorActionPreference = 'Stop'
$null = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]
$null = [Windows.UI.Notifications.ToastNotification, Windows.UI.Notifications, ContentType = WindowsRuntime]
$AppId = '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe'
$xml = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02)
$texts = $xml.GetElementsByTagName('text')
$null = $texts.Item(0).AppendChild($xml.CreateTextNode($Title))
$null = $texts.Item(1).AppendChild($xml.CreateTextNode($Message))
$toast = [Windows.UI.Notifications.ToastNotification]::new($xml)
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($AppId).Show($toast)Then add this to %USERPROFILE%\.codex\hooks.json. The command entries are the Linux fallback and commandWindows runs on Windows; delete either one you don't need:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "notify-send \"Codex\" \"Turn complete\"",
"commandWindows": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"%USERPROFILE%\\.codex\\win-toast.ps1\" -Title Codex -Message \"Turn complete\"",
"async": true
}
]
}
],
"PermissionRequest": [
{
"hooks": [
{
"type": "command",
"command": "notify-send -u critical \"Codex\" \"Needs approval\"",
"commandWindows": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"%USERPROFILE%\\.codex\\win-toast.ps1\" -Title Codex -Message \"Needs approval\"",
"async": true
}
]
}
]
}
}/hooks in Codex and trust the two new hooks, or Codex skips them.commandWindows sound hook in the guide to making Codex ding when it needs approval.To skip the wiring, run npx anotifier@latest setup in PowerShell. On Windows it writes Stop, PermissionRequest, and SessionStart hooks into %USERPROFILE%\.codex\hooks.json, turns on the hooks feature flag, records the trust hashes in config.toml, and backs up hooks.json first. It then checks for PowerShell 7 (pwsh) and installs the BurntToast module for your user with Install-Module BurntToast -Scope CurrentUser; if pwsh is missing it prints winget install --id Microsoft.PowerShell --source winget. Toasts then arrive as my-app · Codex with the Codex icon and a Windows notification sound, and clicking one brings the terminal window forward. anotifier test toast confirms it works. The Windows and WSL guide has the details, including click-to-focus and a fix table for toasts that do not show.
Codex running inside WSL is the Linux build: it reads ~/.codex in the distribution, so run npx anotifier@latest setup inside WSL. The toast then goes through Windows interop. See how the WSL toast reaches Windows and Windows toast from WSL. Codex also runs in VS Code's terminal; the VS Code page covers what changes over Remote-SSH and in dev containers.
Codex has several independent alerts, so pick the switch that matches the one you hear. To silence Codex's built-in notifications, put this in ~/.codex/config.toml:
[tui]
notifications = false| To stop | Do this |
|---|---|
| All built-in TUI notifications | notifications = false under [tui] in ~/.codex/config.toml. The default is true, which allows every type |
| Only some of them | List the types you want, such as notifications = ["approval-requested"]. The type names are listed in the guide to making Codex ding when it needs approval |
| Alerts while you are looking at Codex | Leave notification_condition at its default, "unfocused". "always" notifies even when the window is in front |
| The bell in Windows Terminal | Set bellStyle to "none" in the profile (see the Windows section above) |
| The notify command | Delete the notify = [...] line from ~/.codex/config.toml |
| One hook | Open /hooks in Codex and disable it, or delete its entry from ~/.codex/hooks.json |
| anotifier for a while | anotifier snooze 2h silences every channel until it expires; anotifier snooze off cancels it. Quiet hours (set quietHours.enabled to true in ~/.anotifier/config.json; off by default) do the same every night |
| anotifier for good | npx anotifier@latest uninstall |
Codex already does when a turn finishes, as long as its terminal is in the background: set notification_condition = "always" under [tui] in ~/.codex/config.toml to get it even while the window is in front. To run your own script on every finished turn, set notify = ["python3", "/path/to/script.py"] at the top level of config.toml, above any [table] header; Codex calls it on agent-turn-complete with a JSON payload as the last argument. For a desktop toast and, if you set it up, a phone alert, run npx anotifier@latest setup.
Yes. The Codex TUI notifies when a turn ends and when an approval, Plan mode prompt, or question is waiting: an OSC 9 desktop notification in Ghostty, iTerm2, Kitty, Warp and WezTerm, the terminal bell elsewhere (including Windows Terminal and the VS Code terminal), and by default only while the terminal is unfocused. It doesn't reach your phone.
In Windows Terminal, Codex's built-in alert is the terminal bell, because Codex only sends OSC 9 desktop notifications to Ghostty, iTerm2, Kitty, Warp and WezTerm. For a Windows toast, add Stop and PermissionRequest hooks with a commandWindows entry to %USERPROFILE%\.codex\hooks.json, or run npx anotifier@latest setup, which wires the hooks and installs the BurntToast module (it needs PowerShell 7).
Set notifications = false under [tui] in ~/.codex/config.toml. That silences the built-in alerts only. To stop hook alerts, disable them with /hooks in Codex or remove them from hooks.json. To remove anotifier, run npx anotifier@latest uninstall; to pause it, run anotifier snooze 2h.
Codex's built-in approval-requested notification covers it on your machine. For an alert on your phone (ntfy), in Telegram, or on every channel, use the PermissionRequest hook (Codex CLI 0.144+); anotifier registers it during setup and delivers it as an urgent notification on every channel you enabled.
Not with anotifier today. It gets you back to the terminal fast (click-to-focus on Windows); the decision stays at the keyboard. Remote approval is on the roadmap behind a security review.
No. It only listens to events Codex already emits. It never wraps, proxies, or slows the agent, and hook errors are logged instead of surfacing in the session.
One command wires Codex CLI and every other agent you have installed.
npx anotifier@latest setup