Approvals
Approving Claude Code (and Codex) permission prompts from your phone
The usual reason an agent stops making progress is a permission prompt nobody has seen. There are three ways to answer one from your pocket: Claude Code's own push notifications, a DIY ntfy hook, or an app with an inbox. Here's how each works for Claude Code, what changes for Codex and other agents, and what each one costs you in security.
Quick answer
With a Pro, Max, Team or Enterprise plan, start Remote Control and, in /config, enable Push when actions required. The Claude app then notifies you, and you answer the prompt in the app. For a free, self-hosted alternative, open-source hooks such as claude-remote-approver send each PermissionRequest to ntfy with Approve/Deny buttons. Codex has the same PermissionRequest hook. Apps like Maude show prompts from several agents in one inbox, with push notifications that carry Allow/Deny.
When Claude Code wants to run a command or edit a file you haven't pre-approved, it stops and asks. If you're at the terminal, that takes a second. If you're not, the session waits, which can mean an hour of waiting on one keypress. Every remote-approval setup gets the prompt to your phone and your answer back to the agent. They differ in how the prompt is intercepted, where it travels, and who can answer it.
How remote approvals work
There are two mechanisms, and every tool uses one of them.
- The agent's own remote protocol. Claude Code's Remote Control forwards the real permission dialog to the Claude app. Antigravity's Remote Control and Codex's app-server work the same way. Nothing in the middle decides anything: you're answering the agent's own prompt.
- Hooks. Claude Code runs a program you configure at fixed points. A
PermissionRequesthook fires when a permission dialog is about to appear, and it can answer for you by printing a decision such as{"behavior": "allow"}or"deny". APreToolUsehook fires before every tool call and can returnallow,deny,askordefer. A hook that sends a push and waits for your tap is how every DIY phone-approval tool works. The details are in the hooks reference.
Native push in Claude Code
Anthropic's own path runs through Remote Control:
- Start a session with
claude remote-control(server mode) orclaude --remote-control, or type/remote-controlin a running session. - Sign in to the Claude app on your phone with the same account, and allow notifications.
- In the terminal, run
/configand enable Push when actions required, which covers permission prompts and questions. Push when Claude decides covers proactive updates such as "tests finished".
The docs note a few things you'll run into:
- Plans and auth. Remote Control is on Pro, Max, Team and Enterprise, and API keys aren't supported. On Team and Enterprise, an Owner has to turn it on.
- Prompts don't time out. Permission prompts and questions stay open until you answer them.
- Push pauses while you're at the terminal. Claude Code skips push while you're typing in or focused on the connected terminal.
CLAUDE_CLIENT_PRESENCE_FILEextends that to whenever you're at the machine. - The process has to stay alive. The
claudeprocess must keep running, so on a server, start it inside tmux. - Some modes are off-limits from the app. According to the mobile docs, you can't select Bypass permissions from the app, or Auto for a Remote Control session.
If you're on a Claude plan and only use Claude Code, start here. It's free with your plan and maintained by Anthropic.
DIY with ntfy hooks
ntfy is an open-source push service. You publish to a topic with a plain HTTP request, and the ntfy app on your phone shows it. Several open-source projects pair it with a PermissionRequest hook. The hook posts the pending tool call to your topic with action buttons, waits for your tap on a second topic, and prints the decision back to Claude Code. Credit where it's due:
| Project | Hook | If you don't answer | Notes |
|---|---|---|---|
| claude-remote-approver (yuuichieguchi) | PermissionRequest | Falls back to the terminal prompt after 120 s (300 s for plan reviews) | npm install -g claude-remote-approver; generates a 128-bit random topic; Approve / Always Approve / Deny |
| claude-push (coa00) | PermissionRequest | Falls back to the terminal after 90 s (configurable) | Shell install script; Allow / Deny |
| claude-code-phone-notifications (ssarnecki) | PermissionRequest, PreToolUse, Stop | Waits about 9 minutes, then falls back to the terminal | Waits 30 s before pushing in case you're at the desk; also pushes AskUserQuestion prompts (without buttons) |
| hookline (tsyche) | PreToolUse for Claude; PermissionRequest for Codex | 15-minute default, with a longer window for late replies | Also covers Codex, Grok and OpenCode; supports a self-hosted ntfy with credentials |
All four are MIT-licensed. The timeouts are their documented defaults. If all you want is a ping, with no remote answering, Claude Code's Notification hook is enough. The permission_prompt matcher fires when a dialog appears:
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{ "type": "command",
"command": "curl -s -d 'Claude Code is waiting for approval' https://ntfy.sh/your-long-random-topic" }
]
}
]
}
}
Put that in ~/.claude/settings.json on the machine running Claude Code. You'll still need to get to a terminal to answer. The projects above add the answer path.
Maude's inbox
Maude takes the first approach. Its daemon on your server talks to each agent's own protocol, so a permission request reaches the app as the real request rather than as a hook guess. Requests from every session on every server land in one inbox, next to errors and finished work. You can answer inline there, or straight from the push notification, which carries Allow and Deny. A request waits until you answer; the session doesn't time out and carry on without you. It works for Claude Code, Codex, OpenCode and Grok Build. Antigravity is the exception: headless agy can't pause before a tool runs, so Maude shows the denied action afterwards and retries it if you allow it. Maude is a paid app, and each agent needs its own account. It isn't the only app with an inbox and push: Happier, among others, has both.
Codex and other agents
- Codex has hooks too, enabled by default. A
PermissionRequesthook can answer with"behavior": "allow"or"deny", andPreToolUsecan deny. They live in~/.codex/hooks.jsonor[hooks]inconfig.toml. That's what hookline uses for Codex. Codex's oldernotifysetting runs a program when a turn completes. Third-party write-ups report that it doesn't fire for approval requests, so use hooks for approvals. For Codex's official phone app path and its Linux limits, see Codex CLI on a VPS. - Antigravity answers prompts from its Remote Control dashboard when you run it interactively or as the daemon. Headless
agydenies rather than asks. See Antigravity CLI on a server. - OpenCode and Grok Build are covered by hookline's plugin and hook support, or by multi-agent apps.
Security of remote approvals
An approval from your phone is as strong as the weakest link between the prompt and your tap.
- On ntfy.sh, the topic is the password. ntfy's docs say so directly: with no sign-up, anyone who knows a topic name can read it and publish to it. On a public server, a guessed topic means someone else can approve your agent's commands. Use a long random topic, or self-host ntfy with authentication.
- Read the command, not the title. A lock-screen push shows a summary.
rm -rfinside a long Bash line is easy to miss on a 6-inch screen. Use "always allow" for read-only tools, not forBash(*). - Know your fallback. The DIY hooks above fall back to the terminal prompt when they time out, so an unanswered request blocks rather than auto-approves. Write your own hook with the same rule. Claude Code's docs warn that a timed-out
PreToolUsehook doesn't block the tool call, which goes on through the normal permission flow, so don't count on a stalled hook as a gate. - Lock down the channel. Approval traffic reveals what your agent is doing. Anthropic's Remote Control goes through Anthropic's servers, and Maude's relay sees only end-to-end encrypted traffic. With a hook you choose where it goes. Anthropic's Require trusted devices setting limits which devices can use Remote Control.
- Approvals are a safety net, not a sandbox. Running the agent as a non-root user on a box you could rebuild matters more than any approval UI. See running agents with full permissions, safely.
Answer them from Maude
If your agents run on a server and you'd like one place to answer them all, try Maude with Claude Code or Codex. Add the server from the app, sign in with your own plan, and permission requests arrive as push notifications with Allow and Deny. The inbox collects everything that's waiting on you.
Frequently asked questions
Can Claude Code send push notifications?
/config. It needs a Pro, Max, Team or Enterprise plan; API-key logins aren't supported.Can I Allow or Deny from the lock screen?
What happens if I don't answer?
PreToolUse hook does not block the tool call.Does this work for Codex?
PermissionRequest hook that can allow or deny, and projects like hookline use it to route Codex approvals to ntfy. Codex's notify setting only covers finished turns, per third-party reports, so use hooks for approvals.Is it safe to approve commands from my phone?
What changed
- — First published. Remote Control and hooks behaviour checked against Anthropic and OpenAI docs; repo details and defaults from each project's README on this date.