# OpenAI Codex CLI

> Get notified when OpenAI Codex CLI finishes a turn or needs approval. Codex hooks (Stop, PermissionRequest) and the notify setting, sending to Slack or SMS.

Source: https://docs.alphorn.dev/ai-agents/codex/

Codex CLI can run a command on agent events. There are two ways to set it up:

- **Hooks** (recommended) - `Stop` when a turn finishes and `PermissionRequest` when Codex needs your approval. The event arrives as JSON on stdin.
- **`notify`** (older) - runs a program after each turn. It has no event for approval requests.

## Hooks

### 1. Create the hook script

```bash title="~/.codex/hooks/alphorn-notify.sh"
#!/usr/bin/env bash
# Forwards Codex Stop and PermissionRequest hook events to Alphorn.
jq -c '{
  title: ("Codex - " + (.cwd | split("/") | last)),
  message: (if .hook_event_name == "PermissionRequest"
            then ("Approval needed: " + (.tool_input.description // .tool_input.command // .tool_name // "tool call"))
            else (.last_assistant_message // "Turn complete") end),
  priority: (if .hook_event_name == "PermissionRequest" then 4 else 2 end),
  tags: ["ai-agent", "codex",
         (if .hook_event_name == "PermissionRequest" then "permission" else "completed" end)]
}' | curl -fsS --max-time 5 -X POST https://app.alphorn.dev/n/V1StGXR8_Z5jdHi6B-myT \
  -H "Authorization: Bearer $ALPHORN_API_KEY" \
  -H "Content-Type: application/json" \
  -d @- > /dev/null
exit 0
```

```bash
chmod +x ~/.codex/hooks/alphorn-notify.sh
```

The script always exits `0`: on a `Stop` hook, exit code `2` makes Codex continue the turn.

### 2. Register the hooks

```json title="~/.codex/hooks.json"
{
  "hooks": {
    "Stop": [
      { "hooks": [{ "type": "command", "command": "~/.codex/hooks/alphorn-notify.sh", "timeout": 30 }] }
    ],
    "PermissionRequest": [
      { "hooks": [{ "type": "command", "command": "~/.codex/hooks/alphorn-notify.sh", "timeout": 30 }] }
    ]
  }
}
```

Hooks can also live in a project's `.codex/hooks.json`; project hooks only load when the project is trusted. `ALPHORN_API_KEY` must be set in the environment Codex runs in. Codex only runs a hook after you have reviewed and trusted it: run `/hooks` in Codex and trust the new hook - and again after every change to it. Otherwise hooks silently never fire. If they still don't run, make sure hooks aren't disabled in `config.toml` (`[features] hooks = false`).

| Event | Useful fields |
|---|---|
| All | `session_id`, `cwd`, `hook_event_name`, `model` |
| `Stop` | `last_assistant_message` |
| `PermissionRequest` | `tool_name`, `tool_input.command`, `tool_input.description` |

## Legacy `notify` setting

`notify` runs a program after each turn and passes the event as a JSON string in the **last argument** (not on stdin). Its field names use hyphens, for example `last-assistant-message`. Put it at the top level of `~/.codex/config.toml`, before any `[table]` section:

```toml title="~/.codex/config.toml"
notify = ["bash", "-c", "jq -n --argjson e \"$1\" '{title: (\"Codex - \" + ($e.cwd | split(\"/\") | last)), message: ($e[\"last-assistant-message\"] // \"Turn complete\"), priority: 2, tags: [\"ai-agent\", \"codex\", \"completed\"]}' | curl -fsS --max-time 5 -X POST https://app.alphorn.dev/n/V1StGXR8_Z5jdHi6B-myT -H \"Authorization: Bearer $ALPHORN_API_KEY\" -H 'Content-Type: application/json' -d @-", "codex-notify"]
```

The only event `notify` sends is `agent-turn-complete`. For approval requests, use the `PermissionRequest` hook above.

## Notify when a Codex run exits

To get one notification when a whole `codex` run ends, including its exit code, wrap the command:

```bash title="codex-notify.sh"
#!/bin/bash
WEBHOOK="https://app.alphorn.dev/n/V1StGXR8_Z5jdHi6B-myT"
ALPHORN_API_KEY="${ALPHORN_API_KEY:-alp_...}"  # or export it in the environment
PROJECT=$(basename "$PWD")

codex "$@"
EXIT_CODE=$?

if [ $EXIT_CODE -eq 0 ]; then
  BODY="{\"title\": \"Codex - $PROJECT\", \"message\": \"Task completed\", \"priority\": 2, \"tags\": [\"ai-agent\", \"codex\", \"completed\"]}"
else
  BODY="{\"title\": \"Codex - $PROJECT\", \"message\": \"Exited with code $EXIT_CODE\", \"priority\": 4, \"tags\": [\"ai-agent\", \"codex\", \"error\"]}"
fi

curl -fsS --max-time 5 -X POST "$WEBHOOK" \
  -H "Authorization: Bearer $ALPHORN_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$BODY"
exit $EXIT_CODE
```

Use it as a drop-in replacement:

```bash
alias codex="/path/to/codex-notify.sh"
```

See [AI Agent Notifications](/ai-agents) for routing conventions and an `AGENTS.md` snippet that lets Codex send notifications on its own.
