Codex CLI Integration

June 5, 2026 · View on GitHub

Parallax integrates with Codex CLI through Codex's hook system. It wires three hooks into ~/.codex/config.toml: the notify program (agent-turn-complete) plus PreToolUse and PostToolUse lifecycle hooks. Each forwards its event to the Parallax evaluation server, which applies the configured rule chain.

The PreToolUse and PostToolUse hooks require a Codex version with the hooks engine (stable since Codex CLI v0.124.0).

The integration is a native Rust binary — no Node.js or Python runtime required.

Setup

parallax serve
parallax setup codex

parallax setup codex writes the hooks into ~/.codex/config.toml (honoring CODEX_HOME if set), making them active for all Codex sessions on this machine.

The generated config looks like this:

notify = ["/path/to/parallax", "codex", "hook", "notification"]

[[hooks.PreToolUse]]
matcher = ".*"

[[hooks.PreToolUse.hooks]]
type = "command"
command = '"/path/to/parallax" codex hook pre-tool-use'
timeout = 30
statusMessage = "Parallax pre-tool-use check"

[[hooks.PostToolUse]]
matcher = ".*"

[[hooks.PostToolUse.hooks]]
type = "command"
command = '"/path/to/parallax" codex hook post-tool-use'
timeout = 30
statusMessage = "Parallax post-tool-use review"

Setup is idempotent and preserves any user-defined hooks: re-running it replaces only Parallax's own entries. parallax revert codex removes them, dropping empty hook arrays and the notify key.

For a non-default host or port, pass --host / --port to the setup command. Codex spawns notify directly (not via a shell), so its URL is injected through an env wrapper; the PreToolUse/PostToolUse commands run through a shell, so their URL is injected as a PARALLAX_URL=... prefix:

parallax setup codex --host 0.0.0.0 --port 9999
# notify: ["env", "PARALLAX_URL=http://0.0.0.0:9999/evaluate", "/path/to/parallax", "codex", "hook", "notification"]
# hook command: PARALLAX_URL=http://0.0.0.0:9999/evaluate "/path/to/parallax" codex hook pre-tool-use
VariableDefaultDescription
PARALLAX_URLhttp://127.0.0.1:9920/evaluateEvaluation endpoint
PARALLAX_TIMEOUT3000Request timeout in ms
CODEX_HOME~/.codexCodex config directory

What the integration evaluates

The setup wires all three hooks:

HookCommandStageBehavior
notificationparallax codex hook notificationmessage.beforeFire-and-forget — Codex's notify cannot block a turn
pre-tool-useparallax codex hook pre-tool-usetool.beforeDenies the tool call if the verdict is block
post-tool-useparallax codex hook post-tool-usetool.afterFire-and-forget — logs but doesn't block

The PreToolUse hook reads the Codex event from stdin (tool_name, tool_input, session_id, turn_id). On a block verdict it prints Codex's deny decision to stdout and exits 0:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "<rule reasons>"
  }
}

Codex treats a non-zero exit with stdout output as a hook error and lets the call through, so the deny must be delivered as stdout JSON with exit 0 (not via exit 2). The standalone binary supports the same commands for wrappers that feed tool events manually.

A Codex notify payload is mapped as follows:

Codex fieldParallax field
turn-idsession_id
last-assistant-message (or joined input-messages)message_text
typeevent_type

Event input

Codex passes the event JSON as a trailing argument to the notify program:

parallax codex hook notification '{"type":"agent-turn-complete","turn-id":"t-1","last-assistant-message":"Done!"}'

When no argument is supplied, the hook reads the event from stdin instead — useful for testing and for callers that pipe events.

Fails open

If Parallax is unreachable or returns an error, all hooks exit 0 and allow the turn to proceed. This matches the behavior of the Claude Code and OpenClaw integrations.

Standalone binary

The integrations/codex crate also produces a standalone parallax-codex-hooks binary that implements the same logic without the rest of the parallax CLI:

cargo build --release --manifest-path integrations/codex/Cargo.toml
# binary: integrations/codex/target/release/parallax-codex-hooks

parallax-codex-hooks notification '{"type":"agent-turn-complete","last-assistant-message":"Done!"}'
parallax-codex-hooks pre-tool-use
parallax-codex-hooks post-tool-use

This is useful when you want to install only the hook binary without the full parallax binary.