AlphornAlphorn Docs

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.

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

~/.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
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

~/.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).

EventUseful fields
Allsession_id, cwd, hook_event_name, model
Stoplast_assistant_message
PermissionRequesttool_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:

~/.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:

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:

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

See AI Agent Notifications for routing conventions and an AGENTS.md snippet that lets Codex send notifications on its own.

On this page