Codex Setup
Native Codex hooks for phone approvals, policy enforcement, and session tracking with Pushary
Complete the Quickstart first to create your account and get your API key.
Pushary connects to Codex through MCP and native Codex hooks. The MCP server gives Codex access to push notification tools. The hooks run Pushary's policy engine on Codex tool calls: phone approvals, always-deny rules, the kill switch, task titles, and session tracking.
Setup wizard
npx @pushary/agent-hooks setupNative Codex hooks need Codex 0.122 or newer. On older versions the wizard falls back to the legacy notify handler (notifications only, no policy engine or kill switch).
Select "Codex". The wizard will:
- Install
@pushary/agent-hooksglobally - Add the Pushary MCP server via
codex mcp add - Write six hook entries to
~/.codex/hooks.json - Remove the legacy notify handler from
~/.codex/config.tomlif present - Save your API key to your shell profile
Trust the hooks
Codex does not run hooks until you trust them. This is a one-time step:
- Open Codex
- Run
/hooks - Review the Pushary entries and trust them
All six entries run the same pushary-codex-hook command, so there is one command to review. Upgrades do not re-prompt because the trust hash is tied to the hook definition, and the command string stays stable across versions.
For CI environments where the trust prompt cannot be answered, Codex supports --dangerously-bypass-hook-trust. Use it only in CI.
What each hook does
| Event | What happens |
|---|---|
PermissionRequest | Codex would ask you for permission in the terminal. Pushary sends the question to your phone instead. Yes runs it, No denies it. If your policy says escalate on timeout, the question falls back to the Codex terminal prompt. |
PreToolUse | The enforcement backstop. Runs before every shell or apply_patch call: the kill switch and always-deny policies block the call here, even when Codex would not have asked. |
PostToolUse | Records tool_complete or tool_error events with receipts, and cleans up pending phone questions. |
UserPromptSubmit | Captures your prompt as the session's task title on the Fleet Board. Set PUSHARY_TASK_TITLES=off to disable. |
Stop | Records the session as idle and cancels pending phone questions. |
SessionStart | Registers the session on the Fleet Board from the first second. |
Capability parity with Claude Code
| Capability | Claude Code | Codex |
|---|---|---|
| Phone approvals from the lock screen | Yes | Yes, via PermissionRequest |
| Policy enforcement (always-deny, auto-approve, argument patterns) | Yes | Yes, via PreToolUse |
| Kill switch | Yes | Yes, stops the next gated tool call |
| Task titles | Yes | Yes |
| Parallel session tracking | Yes | Yes |
Activity receipts (tool_complete / tool_error) | Yes | Yes |
| Edit and Write file gating | Yes | Partial, apply_patch calls map to your Edit policies |
What hooks cannot intercept yet
Codex hook interception is incomplete by OpenAI's own documentation: unified_exec and non-shell tools are not yet intercepted. Treat enforcement on Codex as a guardrail, not a security boundary. Policies and the kill switch apply to shell commands and apply_patch calls, which covers most of what an agent does, but not everything.
Manual setup
If you prefer not to use the wizard:
MCP server
codex mcp add pushary --url https://pushary.com/api/mcp/mcp --bearer-token-env-var PUSHARY_API_KEYSet your API key in your shell profile (~/.zshrc or ~/.bashrc):
export PUSHARY_API_KEY="pk_xxx.xxx"Hooks
Install the hooks package globally:
npm install -g @pushary/agent-hooksAdd the entries to ~/.codex/hooks.json. Replace the command with the output of which pushary-codex-hook and use the same path in every entry:
{
"hooks": {
"PermissionRequest": [
{
"matcher": "Bash|apply_patch",
"hooks": [
{ "type": "command", "command": "/path/to/pushary-codex-hook", "timeout": 180, "statusMessage": "Waiting for your phone" }
]
}
],
"PreToolUse": [
{
"matcher": "Bash|apply_patch",
"hooks": [
{ "type": "command", "command": "/path/to/pushary-codex-hook", "timeout": 180, "statusMessage": "Checking Pushary policy" }
]
}
],
"PostToolUse": [
{
"matcher": "Bash|apply_patch",
"hooks": [
{ "type": "command", "command": "/path/to/pushary-codex-hook", "timeout": 10 }
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{ "type": "command", "command": "/path/to/pushary-codex-hook", "timeout": 10 }
]
}
],
"Stop": [
{
"hooks": [
{ "type": "command", "command": "/path/to/pushary-codex-hook", "timeout": 10 }
]
}
],
"SessionStart": [
{
"matcher": "startup|resume",
"hooks": [
{ "type": "command", "command": "/path/to/pushary-codex-hook", "timeout": 10 }
]
}
]
}
}Then complete the trust step above.
MCP tools
Once connected, Codex can use these tools:
| Tool | Description |
|---|---|
send_notification | Send a push with optional rich context |
ask_user | Ask a question: yes/no, multiple choice, or free text |
wait_for_answer | Poll for your response |
cancel_question | Cancel a pending question |
Legacy notify handler (deprecated)
Older Codex versions without hook support fall back to the pushary-codex notify handler in ~/.codex/config.toml. It captures turn completions and approval requests, but has no policy engine, no kill switch, and no session tracking. The setup wizard installs it automatically only when your Codex version predates hooks, and removes it once you upgrade and re-run setup.