Start here
Connect Codex
Add the Agentower hook to Codex — the CLI, the ChatGPT desktop app and the IDE extensions.
Codex uses the same hook script and settings file as Claude Code. If you've already connected Claude Code on this machine, skip to step 2.
What works for Codex: status on the board, Needs you when it waits for permission, allowing or denying from Agentower, and guardrail pauses. Replying to Codex or messaging it from Agentower isn't available yet — type those in its terminal.
#1. Save the address and key, and install the hook
Do steps 1 and 2 of Connect Claude Code — save ~/.agentower/claude-code.env and put agentower-hook.sh in ~/.agentower/. You don't need the Claude Code settings.json part.
To allow or deny Codex's requests from Agentower, set AGENTOWER_REMOTE in that file to own or team — see Answers from Agentower on this computer. It's off unless you change it.
#2. Add the hook to Codex
Add these entries to ~/.codex/hooks.json (merge them with any hooks you already have). AGENTOWER_TOOL=codex tells the script it's reporting for Codex.
{
"hooks": {
"SessionStart": [{ "hooks": [{ "type": "command", "command": "AGENTOWER_TOOL=codex sh \"$HOME/.agentower/agentower-hook.sh\"", "async": true, "timeout": 10 }] }],
"SessionEnd": [{ "hooks": [{ "type": "command", "command": "AGENTOWER_TOOL=codex sh \"$HOME/.agentower/agentower-hook.sh\"", "async": true, "timeout": 10 }] }],
"UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "AGENTOWER_TOOL=codex sh \"$HOME/.agentower/agentower-hook.sh\"", "async": true, "timeout": 10 }] }],
"PreToolUse": [{ "hooks": [{ "type": "command", "command": "AGENTOWER_TOOL=codex sh \"$HOME/.agentower/agentower-hook.sh\"", "async": true, "timeout": 10 }] },{ "hooks": [{ "type": "command", "command": "AGENTOWER_TOOL=codex sh \"$HOME/.agentower/agentower-hook.sh\" guard", "timeout": 5 }] }],
"PostToolUse": [{ "hooks": [{ "type": "command", "command": "AGENTOWER_TOOL=codex sh \"$HOME/.agentower/agentower-hook.sh\"", "async": true, "timeout": 10 }] }],
"PermissionRequest": [{ "hooks": [{ "type": "command", "command": "AGENTOWER_TOOL=codex sh \"$HOME/.agentower/agentower-hook.sh\"", "async": true, "timeout": 10 }] },{ "hooks": [{ "type": "command", "command": "AGENTOWER_TOOL=codex sh \"$HOME/.agentower/agentower-hook.sh\" ask-approval", "timeout": 600 }] }],
"Stop": [{ "hooks": [{ "type": "command", "command": "AGENTOWER_TOOL=codex sh \"$HOME/.agentower/agentower-hook.sh\"", "async": true, "timeout": 10 }] }],
"SubagentStart": [{ "hooks": [{ "type": "command", "command": "AGENTOWER_TOOL=codex sh \"$HOME/.agentower/agentower-hook.sh\"", "async": true, "timeout": 10 }] }],
"SubagentStop": [{ "hooks": [{ "type": "command", "command": "AGENTOWER_TOOL=codex sh \"$HOME/.agentower/agentower-hook.sh\"", "async": true, "timeout": 10 }] }]
}
}Codex asks you to review new hooks the first time it sees them. Approve them, then start a new session: it appears on the Agents board within a few seconds.
#The work record
With hook version 6, a Codex agent's work record has its shell commands by kind, commits, pushes and pull requests, each turn's totals and its work stream, and — for projects with Work details on — the instruction and the agent's summary. Less than for Claude Code:
- Test results: Codex gives hooks no test output, so a test run comes without passed and failed counts or test names; the Work tab says "Test results: not reported by Codex".
- Files: the hook counts file changes only from Claude Code's edit tools, so files Codex changes with its own patch tool aren't counted.
#Plan limits
Nothing to set up: at the end of each Codex turn, the hook reads only the plan-limit numbers from that session's record on your computer and sends them, so your ChatGPT plan shows on the Usage page. Name the account with AGENTOWER_CODEX_ACCOUNT in ~/.agentower/claude-code.env if you have more than one.
#3. Optional: token counts
Codex can send its token counts to Agentower through its OpenTelemetry export. If ~/.codex/config.toml has no [otel] section yet, add this one, with your own key:
[otel]
log_user_prompt = false
exporter = { otlp-http = { endpoint = "https://ingest.agentower.com/v1/logs", protocol = "json", headers = { "authorization" = "Bearer at_live_your_key_here" } } }If you already have an [otel] section, point its exporter at your tower's /v1/logs address with protocol = "json" instead. Agentower reads only the token counts from it — Codex sends no cost figure. Technical details: OpenTelemetry.
#Disconnect
Remove the entries that mention agentower-hook.sh from ~/.codex/hooks.json.