AC Bridge

Notifications for AI coding agents: Claude Code and Codex side by side

Last updated · Last verified against the Claude Code and Codex docs on

The short answer Claude Code and Codex both alert you through two hook events of the same name: Stop when a turn ends and PermissionRequest when approval is needed. After that they differ. Claude Code adds a Notification event with an idle reminder, which Codex does not have. Codex adds a one-line notify setting and a built-in alert that falls back to the terminal bell, where Claude Code stays silent in most terminals. Their hook files share a shape, so one small script can serve both.

Or let a light show it

Alerts tell you about one moment on one screen. With two agents running, the harder question is what each is doing now, and that is where a light fits: it shows the current state of both from across the room and adds no ping.

What it does

AC Bridge turns the smart lights and plugs you already own (Hue, LIFX, Govee, WiZ, Home Assistant and more) into a status light for Claude Code and Codex, in the same app and on the same lamps. In the example colours from our homepage, the lamp breathes blue while the agent works, flashes red when it needs permission and turns green when it has finished; you pick the colours, and give each project its own lamp or let one lamp follow several.

What it follows

  • Claude Code: can trigger all 29 states, through hooks that come with its plugin, so there is nothing to paste into your settings files. Needs permission comes from the Notification hook.
  • Codex: drives 19 of the 29 states. Setup adds its entries to ~/.codex/hooks.json and keeps the ones already there; type /hooks once to trust them. Needs permission comes from PermissionRequest.
  • Both at once: a folder can hold one Claude profile and one Codex profile, and each names its own devices, so the two can use different lamps. On a shared lamp, the most recent session wins by default.
  • Hooks you wrote yourself keep running alongside it.

What it costs

One plan: a 7-day free trial with no card needed, then £2.99 a month if you add a card to keep going; without one the trial just ends and nothing is charged. Cancel any time from your account. It works with the Claude Code or Codex you already run, on Windows, macOS or Linux. There is no API key to buy.

What it collects

LAN devices are driven straight from your machine and their keys never leave it; your account, settings, device list, usage counts and session states sync through our servers. Your prompts, code and session transcripts are never collected. Privacy policy.

Try it on your own lights Start the 7-day free trial, or read the setup docs and the status light guide first.

What can Claude Code and Codex notify you about?

For every method on one agent, sound and phone included, read the Claude Code notifications guide or the Codex notifications guide. This is the side-by-side, as the Claude Code hooks reference and terminal guide, the Codex hooks page and advanced configuration stood on the date above.

You want to knowClaude CodeCodex
A turn finishedStopStop, or notify on agent-turn-complete
It wants approvalPermissionRequest, when the prompt appearsPermissionRequest, when Codex is about to ask
Approval is waiting and you look awayNotification with permission_prompt, after about six seconds without typingNo hook; the built-in alert's approval-requested
It has gone quiet and waits for youNotification with idle_prompt, about 60 seconds after it finishesNo event
A turn failed on an API errorStopFailure, which runs instead of StopNo event
You interrupted a turnNo event; Stop does not runInterrupt
The session endedSessionEndSessionEnd, which never runs in the background
Run a program with no hookNo setting; use a Stop hooknotify in ~/.codex/config.toml

Built in: Claude Code

  • A desktop notification by default in Ghostty, Kitty and iTerm2; iTerm2 needs its alert settings turned on first.
  • Nothing by default in most other terminals, until you set "preferredNotifChannel": "terminal_bell" in ~/.claude/settings.json.
  • It fires when you appear to be away from the terminal.

Built in: Codex

  • tui.notifications is on by default and fires while the terminal is unfocused; notification_condition set to always changes that.
  • In its default auto mode it sends OSC 9 where the terminal seems to support it, and rings the bell elsewhere.
  • Going by the Codex source, it also fires when Codex asks you a question, which no hook covers.

Set up one alert for Claude Code and Codex

Both hook files nest the same way: an event, a matcher group, then a list of handlers. Both also run a handler in the session's working directory. So one script can do the work, and each agent's file only passes in its name and what happened.

The script, for macOS and Linux

Save it as ~/.local/bin/agent-notify. It sends all its output to /dev/null on purpose: a Codex Stop hook must print JSON or nothing.

~/.local/bin/agent-notify

#!/bin/sh
# One alert for Claude Code and Codex. Usage: agent-notify AGENT WHAT
agent="${1}"
what="${2}"
text="$what in $(basename "$PWD")"
case "$(uname -s)" in
  Darwin) osascript -e 'on run argv' \
    -e 'display notification (item 1 of argv) with title (item 2 of argv)' \
    -e 'end run' "$text" "$agent" ;;
  *) notify-send "$agent" "$text" ;;
esac >/dev/null 2>&1
exit 0

Claude Code: three entries

Merge this into ~/.claude/settings.json. It uses PermissionRequest rather than the permission_prompt matcher, which would alert you twice for one prompt.

~/.claude/settings.json

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.local/bin/agent-notify 'Claude Code' 'Finished'",
            "async": true
          }
        ]
      }
    ],
    "PermissionRequest": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.local/bin/agent-notify 'Claude Code' 'Needs approval'",
            "async": true
          }
        ]
      }
    ],
    "Notification": [
      {
        "matcher": "idle_prompt",
        "hooks": [
          {
            "type": "command",
            "command": "~/.local/bin/agent-notify 'Claude Code' 'Waiting for you'",
            "async": true
          }
        ]
      }
    ]
  }
}

Codex: two entries

Merge this into ~/.codex/hooks.json. There is no third entry, because Codex has no event for it. Codex skips both entries until you trust them.

~/.codex/hooks.json

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.local/bin/agent-notify 'Codex' 'Finished'",
            "async": true
          }
        ]
      }
    ],
    "PermissionRequest": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.local/bin/agent-notify 'Codex' 'Needs approval'",
            "async": true
          }
        ]
      }
    ]
  }
}

On Windows

The script above is for macOS and Linux, but the same plan holds. Write one PowerShell script that takes the same two arguments, set "shell": "powershell" on each Claude Code entry, and add commandWindows beside command in each Codex entry.

  1. Make it runnable

    Run mkdir -p ~/.local/bin before you save the file, and chmod +x ~/.local/bin/agent-notify after.

  2. Try it by hand

    Run ~/.local/bin/agent-notify 'Codex' 'Finished' in a project folder. No alert here means the script is at fault, not the hooks.

  3. Trust it in Codex

    Type /hooks inside Codex and trust the two new entries.

  4. Accept the folder in Claude Code

    It holds back every settings-file hook, your own included, until you accept the workspace trust dialog for that folder.

Notifications when you run two coding agents at once

With one agent, an alert means that agent. With two, the alert also has to say which one, and the number of alerts doubles.

Which one wants you

A bell only says that something happened. The script puts the agent in the title and the folder in the text, so "Needs approval in api" under Codex tells you where to go before you switch windows.

Both in one folder

Nothing stops the two agents working in the same project, and the title is what separates them there. Keep the entries in your home folder files, as above, and they cover every project; the project-level .claude/settings.json and .codex/hooks.json are for hooks a single repo needs.

The same alert twice

Hooks run alongside the built-in alerts. To keep only the script, set notifications = false under [tui] in ~/.codex/config.toml, and set preferredNotifChannel to notifications_disabled in Claude Code.

Too many alerts

Stop fires on every finished turn, in both agents. If two busy sessions turn that into noise, delete the Stop entries and keep PermissionRequest, so you only hear about work that is stuck.