No description
Find a file
2026-06-05 17:32:33 +08:00
.codex-plugin Add Agent Notify Codex plugin 2026-06-05 15:24:06 +08:00
hooks Add Agent Notify Codex plugin 2026-06-05 15:24:06 +08:00
scripts Use shared app-server Unix socket 2026-06-05 17:32:33 +08:00
skills/agent-notify Add Agent Notify Codex plugin 2026-06-05 15:24:06 +08:00
tests Use shared app-server Unix socket 2026-06-05 17:32:33 +08:00
README.md Use shared app-server Unix socket 2026-06-05 17:32:33 +08:00

Agent Notify

Agent Notify is a local Codex plugin that bridges Codex app-server sessions to ntfy. It publishes session updates to a send topic and turns explicitly addressed replies from a poll topic into Codex turn/start, turn/steer, or approval responses.

ntfy Behavior

ntfy supports updating one visible client notification by publishing new messages with the same X-Sequence-ID. The ntfy server cache/history remains append-only, so Agent Notify guarantees one visible notification per session on clients that honor X-Sequence-ID, not one stored server record.

Required Environment

export AGENT_NOTIFY_NTFY_BASE_URL="https://ntfy.xiny.li"
export AGENT_NOTIFY_NTFY_SEND_TOPIC="<send>"
export AGENT_NOTIFY_NTFY_POLL_TOPIC="<poll>"
export AGENT_NOTIFY_NTFY_TOKEN="<token>"

Basic auth is also supported with AGENT_NOTIFY_NTFY_USER and AGENT_NOTIFY_NTFY_PASSWORD.

Production runs refuse to start without ntfy auth. Use --allow-anonymous-test only for throwaway test topics.

Optional:

export AGENT_NOTIFY_BRIDGE_LABEL="workstation-a"
export AGENT_NOTIFY_PLUGIN_ROOT="/absolute/path/to/agent-notify"

The Codex app-server Unix socket is created at $XDG_RUNTIME_DIR/agent-notify/codex-app-server.sock. The bridge requires $XDG_RUNTIME_DIR to be owned by the current user and inaccessible to group/other users. The runtime socket directory is forced to 0700, and the app-server socket is forced to 0600 after startup.

AGENT_NOTIFY_BRIDGE_ID is an advanced override. By default, the bridge generates and persists a random 128-bit ID in its state directory. If a duplicate bridge ID is observed on a shared poll topic, auto-generated IDs rotate before sessions start; manual overrides fail closed.

Run

Start the bridge and shared Codex app-server:

python3 scripts/agent_notify_bridge.py serve

Create Codex threads with local Codex CLI/TUI clients connected to the shared socket:

codex --remote "unix://$XDG_RUNTIME_DIR/agent-notify/codex-app-server.sock" --cd /path/to/project-a
codex --remote "unix://$XDG_RUNTIME_DIR/agent-notify/codex-app-server.sock" --cd /path/to/project-b

When the bridge observes a Codex thread, it registers a local session and publishes an ntfy notification with the reply target:

Reply target: @<bridge-id>/<session-id>

Reply Syntax

Replies must always be explicitly addressed:

@<bridge-id>/<session-id> continue with the next step
@<bridge-id>/<session-id> approve <request-id>
@<bridge-id>/<session-id> approve-session <request-id>
@<bridge-id>/<session-id> deny <request-id>
@<bridge-id>/<session-id> cancel <request-id>

Unaddressed plain text is ignored. Messages addressed to a different bridge are ignored so many app-servers can share the same ntfy topics.

Hooks

hooks/hooks.json forwards Codex lifecycle events to the local bridge socket. Set AGENT_NOTIFY_PLUGIN_ROOT to this plugin directory before relying on the bundled hook commands.

If AGENT_NOTIFY_PLUGIN_ROOT is unset, bundled hooks no-op instead of failing.

The hook client is best-effort. If the bridge is not running, it logs to stderr and exits successfully so it does not block Codex.