Notifications for Claude Code, Codex, OpenCode and omp compared
Updated 24 October 2026
If you run more than one coding agent, you find out quickly that each one handles “I need you” differently. One alerts you out of the box, two need a line of config, one only alerts in certain terminals, and each has its own hook or plugin system for anything custom. This page puts them side by side, says what each does by default, and shows how to get one consistent alert from all four.
Side by side
| Feature | Claude Code | Codex | OpenCode | omp |
|---|---|---|---|---|
| Built-in desktop alert | On by default in Ghostty, Kitty and iTerm2 | Off until you set [tui] notifications; uses OSC 9 | OpenCode 2: off until you set attention in cli.json. OpenCode 1: none | On by default: OSC 99 in Kitty; OSC 9 in Ghostty, WezTerm, iTerm2 and Warp |
| Bell or sound | preferredNotifChannel: "terminal_bell" | notification_method = "bel", and the fallback for auto | OpenCode 2: attention.sound, with your own sound files | Bell in other terminals; on a Linux desktop also a notify-send toast |
| Alerts you when | Permission prompt (after ~6 s idle), waiting for you (after ~60 s) | Turn complete, approval requested | OpenCode 2: when it needs attention, with separate sounds for permission, question, done, error and subagent done | Turn complete, a question (ask tool), error (off by default) |
| Run your own command | Hooks in settings.json | notify program; hooks in hooks.json | Plugins | TypeScript extensions |
| Event the moment it asks for approval | PermissionRequest hook | PermissionRequest hook | permission.asked plugin event (OpenCode 1); a plugin such as opencode-notifier (1 and 2) | tool_approval_requested extension event |
| Answer from Agent Pets | Allow, Always, Deny, reply | Allow, Deny, reply | Allow, Always, Deny, reply | See state and reply; approvals stay in the terminal |
None of the agents’ own alerts let you answer. They all tell you to go back to the terminal.
1. Claude Code
Claude Code sends a desktop notification by itself only in Ghostty, Kitty and iTerm2 (iTerm2 needs Notification Center Alerts turned on). Everywhere else, including Warp and the VS Code terminal, you get nothing until you turn on the bell or add a hook:
~/.claude/settings.json{
"preferredNotifChannel": "terminal_bell"
}
The gotcha is timing. In the terminal, Claude Code only notifies when you seem away: about six seconds without typing for a permission prompt, about 60 seconds after it finishes for “waiting for you”. For an alert the moment it asks, use a PermissionRequest hook instead of a Notification hook. Questions from the AskUserQuestion tool don’t trigger a notification at all; a PreToolUse hook on that tool covers it.
Full setup: How to get Claude Code notifications. Not firing? Claude Code notifications not working.
2. Codex
Codex’s terminal app has notifications built in, but they’re off until you list the events you want:
~/.codex/config.toml[tui]
notifications = ["agent-turn-complete", "approval-requested"]
notification_method = "auto"
notification_condition = "unfocused"
auto sends OSC 9, which terminals that support it turn into a desktop notification, and falls back to the bell. By default it only fires while the terminal isn’t focused. Beyond that, Codex has two ways to run your own command: notify, which runs a program after each finished turn and passes it JSON with the project folder and Codex’s last message, and hooks in ~/.codex/hooks.json, where a PermissionRequest hook fires the moment Codex asks for approval. Codex ignores new or changed hooks until you trust them with /hooks.
Full setup: How to get Codex notifications.
3. OpenCode
It depends on the version (opencode --version). OpenCode 2’s terminal app can send a system notification and play a sound when it needs attention, normally only while the terminal isn’t focused, once you turn it on. Each sound (permission, question, done, error, subagent done) can be swapped for your own file under attention.sounds.
~/.config/opencode/cli.json{
"attention": {
"notifications": true,
"sound": true
}
}
OpenCode 1 has nothing built in: you use a plugin, either one from npm or a few lines of your own listening for session.idle and permission.asked. Two things to know: OpenCode allows most actions by default, so you’ll see fewer permission alerts than with the others unless you add ask rules, and running a notification plugin on OpenCode 2 alongside the built-in alerts gets you every alert twice.
Full setup: How to get OpenCode notifications.
4. omp
omp notifies you out of the box, with no config. It sends a desktop notification when a turn completes and when its ask tool is waiting for your answer, titled with the session’s name. How it reaches you depends on the terminal it detects:
- Kitty: OSC 99.
- Ghostty, WezTerm, iTerm2, Warp: OSC 9.
- Everything else, such as the VS Code terminal, Alacritty, Apple Terminal and Windows Terminal: the terminal bell. On a Linux desktop session omp also sends a toast through
notify-send(orgdbusif that’s missing).
Three settings control it, all on or off:
| Setting | Default | Notifies when |
|---|---|---|
completion.notify | on | The agent finishes a turn |
ask.notify | on | The ask tool is waiting for input |
error.notify | off | The agent stops with an error |
Change them from the command line, which writes to ~/.omp/agent/config.yml:
Terminalomp config set error.notify on
omp config get completion.notify
To silence every desktop notification for one run, start omp with PI_NOTIFICATIONS=off.
What omp doesn’t have is an alert setting for approval prompts. By default it doesn’t need one: tools.approvalMode is yolo, which auto-approves every tool call. Switch to write (asks before running commands) or always-ask (asks before writes too) with omp config set tools.approvalMode write, and you’ll want an alert. omp extensions get a tool_approval_requested event right before the prompt appears. Save this as a file in ~/.omp/agent/extensions/ and restart omp:
~/.omp/agent/extensions/approval-alert.tsimport type { ExtensionAPI } from "@oh-my-pi/pi-coding-agent";
export default function (pi: ExtensionAPI) {
pi.on("tool_approval_requested", async (event) => {
const message = `omp wants to use ${event.toolName}`;
if (process.platform === "darwin") {
await pi.exec("osascript", ["-e", `display notification "${message}" with title "omp"`]);
} else {
await pi.exec("notify-send", ["omp", message]);
}
});
}
omp waits for the handler before it shows the prompt, so keep the command quick.
5. One alert setup for all of them
Four agents means four config formats. You can at least make the alerts look the same by putting the notification itself in one script and calling it from each agent. Save this as ~/bin/agent-notify and run chmod +x ~/bin/agent-notify:
~/bin/agent-notify#!/bin/bash
# usage: agent-notify "Title" "Message"
if [ "$(uname)" = "Darwin" ]; then
osascript - "$1" "$2" <<'EOF'
on run argv
display notification (item 2 of argv) with title (item 1 of argv)
end run
EOF
else
notify-send "$1" "$2"
fi
Then point each agent at it, replacing /Users/you with your home folder:
- Claude Code: a
PermissionRequesthook in~/.claude/settings.jsonwith the command/Users/you/bin/agent-notify 'Claude Code' 'Needs permission'. - Codex: the same command, with
'Codex'as the title, in aPermissionRequesthook in~/.codex/hooks.json. Trust it with/hooks. - OpenCode: on OpenCode 2 the built-in
attentionalerts are simplest. On OpenCode 1, call the script from the plugin in the OpenCode guide. - omp: in the extension above, replace the
ifblock withawait pi.exec("/Users/you/bin/agent-notify", ["omp", message]);
~/.codex/hooks.json{
"hooks": {
"PermissionRequest": [
{
"hooks": [
{
"type": "command",
"command": "/Users/you/bin/agent-notify 'Codex' 'Codex needs your approval'"
}
]
}
]
}
}
The macOS caveat applies to every agent: osascript notifications come from Script Editor, so allow Script Editor in System Settings → Notifications. On Linux, notify-send needs a desktop notification daemon, which SSH sessions and containers don’t have. On Windows, use the agents’ built-in alerts or the bell; this script is for macOS and Linux.
One place to see and answer all of them: Agent Pets
A shared script makes the alerts consistent, but each one still sends you hunting for the right terminal. Agent Pets puts every session in Chrome instead:
- Each Claude Code, Codex, OpenCode and omp session becomes a named pet that walks along the bottom of every page you visit.
- A capsule over each pet says Thinking, Allow Bash?, Your Turn or Done, and the toolbar badge counts the sessions waiting on you.
- When Claude Code or OpenCode asks permission, its pet bounces and you answer Allow, Always or Deny on the page; Codex gets Allow or Deny. omp approvals stay in the terminal.
- Read any session’s latest answer and send its next message from the tab you’re on.
- In another app, a desktop notification names the pet that needs you, with Allow and Deny on it.
npx getagentpets init connects all four agents, next to any hooks you already have. It runs entirely on your computer, and every terminal prompt keeps working as usual.
Get Agent Pets — was $25, now $6Get Agent Pets — $25
Questions
Which coding agents send desktop notifications by themselves?
omp does out of the box when a turn finishes or it asks you a question. Claude Code does in Ghostty, Kitty and iTerm2. Codex and OpenCode 2 do once you turn them on in config.toml and cli.json. OpenCode 1 needs a plugin.
Does omp notify me when it needs approval?
Not with a built-in setting. omp auto-approves every tool call by default (tools.approvalMode is yolo), so it rarely asks. If you switch to write or always-ask, a small extension that listens for tool_approval_requested can send the alert.
Can one notification script work for every agent?
Yes. Write one script that takes a title and a message, then call it from a Claude Code hook, a Codex hook, an OpenCode plugin and an omp extension. Each agent still needs its own wiring.
Can I approve a coding agent from a notification?
Not from the agents’ own notifications, the bell or a plain hook. Agent Pets puts Allow and Deny on a desktop notification and on a pet on every Chrome page for Claude Code, Codex and OpenCode. omp approvals stay in the terminal.
Sources: Claude Code’s documentation on terminal configuration and hooks; Codex documentation on advanced configuration and hooks; OpenCode’s documentation on CLI settings and OpenCode 1 plugins; omp’s documentation on settings, approval mode, extensions and environment variables, and its terminal detection source (omp 18.10).