Claude Code notifications on iPhone and approving permissions
Published:2026-11-08
To answer Claude Code permission prompts from your phone, use Anthropic's Remote Control to reply in the Claude app, or use a PreToolUse hook that asks another app for approval. A Notification hook can only tell you something happened; it cannot send an answer back. Nodd's nodd hook is a PreToolUse hook that asks on your iPhone, allows the tool only after a Face ID approval, and turns rejection, expiry, and network failure into a denial.
When Claude Code stops
Before Claude Code uses a tool that needs permission, it shows a prompt and waits. If that prompt appears after you walk away, nothing happens until you come back. The longer the task you hand off, the more this costs you.
There are two moments you want to hear about.
- It stopped to ask for permission, before running a command or editing a file. You want to answer, not just know
- It finished, or is waiting for input. A notification is enough
The first needs a notification and a way to send the answer back. The second needs only a notification. Which one you are solving decides the tool.
What Claude Code has built in
Permission modes and rules
Start by removing prompts you do not need. Claude Code has permission modes, described in the official docs.
default | Asks the first time each tool is used. Labeled Manual in the UI |
|---|---|
acceptEdits | Accepts file edits and common filesystem commands in the working directory |
plan | Reads and explores without editing source files |
auto | No routine prompts. A background classifier checks actions such as shell commands against your request |
dontAsk | Denies anything that would prompt. Calls allowed by your rules still run |
bypassPermissions | Skips prompts. The docs say to use it only in isolated environments such as containers or VMs |
In your settings, permissions lists commands that run without asking and commands that are always refused. Rules are evaluated deny first, then ask, then allow, and the first match wins.
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git commit *)"
],
"deny": [
"Bash(git push *)"
]
}
}
Allowing safe commands and denying dangerous ones cuts the number of prompts. Someone still has to answer the ones that remain.
Remote Control and push notifications
Anthropic's Remote Control lets you drive a Claude Code session running on your computer from the Claude app on your iPhone or from claude.ai/code. Start it with claude remote-control, or run /remote-control in an open session. In /config, turn on "Push when actions required" and permission prompts and questions arrive as push notifications you can answer in the app.
You can keep the conversation going from your phone too, so if you use Claude Code with a claude.ai subscription, try this first. Per the docs it works on Pro, Max, Ultra, Team, and Enterprise plans, not with API keys, and on Team and Enterprise an Owner has to enable it. Your computer stays on with Claude Code running. A permission prompt stays open until you answer; it does not expire into a denial.
Permission relay through channels
Channels, a research preview, push messages from Telegram, Discord, or iMessage into a running session. A channel that supports permission relay forwards prompts so you can approve or deny remotely. The docs warn that anyone who can reply through the channel can approve tool use, so allowlist only senders you trust with that.
Notify-only hooks
Hooks run commands at fixed points in Claude Code. The Notification hook runs when Claude Code sends a notification, and you can match permission_prompt (a permission prompt has waited about six seconds) or idle_prompt (Claude finished about 60 seconds ago and you have not typed). The Stop hook runs every time Claude finishes responding.
The hook gets JSON on standard input, so you can forward it to any push service. This example sends it to ntfy. Anyone who guesses an ntfy.sh topic name can read it, so pick a long, unguessable one.
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [{"type": "command", "command": "jq -r .message | curl -s -H 'Title: Claude Code' -d @- https://ntfy.sh/YOUR-HARD-TO-GUESS-TOPIC"}]
}
]
}
}
This is quick and works with any service. But as the docs say, Notification hooks cannot block or change anything. You see the prompt on your phone and still have to go back to the keyboard to answer it.
If you only want to know when it is done, idle_prompt fits better than Stop, which fires after every response, even while you sit there. With Nodd, nodd send does the same.
{
"hooks": {
"Notification": [
{
"matcher": "idle_prompt",
"hooks": [{"type": "command", "command": "nodd send 'Claude Code: waiting for input' --level low"}]
}
]
}
}
Comparison
| Permission rules and modes | Fewer prompts. The rest are answered at the computer |
|---|---|
| Remote Control | Answer prompts and keep chatting in the Claude app. Needs a claude.ai plan, not an API key. Prompts have no deadline |
| Channel permission relay | Answer from Telegram and others. Research preview, needs Bun and a plugin |
| Notification hook and a push service | Works with any service. Notifies only; cannot answer |
| PreToolUse hook with Nodd | Runs only after a Face ID approval. Has a deadline, and expiry or failure means deny. Works with any Claude Code sign-in. Cannot continue the conversation |
Approve from your iPhone with nodd hook
A PreToolUse hook runs before a tool and can return allow or deny as JSON on standard output. Claude sees the reason for a deny. Nodd's nodd hook uses this to ask for approval on your iPhone before the tool runs.
Setup
Install the CLI and log in. Scan the QR code from nodd login under Settings > Log in to CLI in the app.
brew install blipdrop/tap/nodd
nodd login
Add this to a Claude Code settings file, such as ~/.claude/settings.json or the project's .claude/settings.json. It is the same as on the MCP and hooks page.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{"type": "command", "command": "nodd hook", "timeout": 1260}]
}
]
}
}
Every run of a tool that matches matcher asks for approval. It arrives as an approval at level: high, titled Claude Code: tool name, with the command as the body. For other tools the body is the tool input, cut at 1,000 characters.
What each answer does
| Approved | allow. The tool normally runs without Claude Code's own prompt |
|---|---|
| Rejected | deny. A rejection reason reaches the agent as Rejected in Nodd: reason |
| Expired, cancelled, failed | deny |
| Network failure, or anything unconfirmed | deny. Every failure becomes a denial |
A rejection reason can be up to 200 characters. Write something like "use staging, not production" and Claude reads it and changes course.
The deadline and the hook timeout
The default response deadline is 300 seconds. nodd hook waits until 15 minutes after the deadline, 1,200 seconds in total by default, so the Claude Code hook timeout must be longer. The 1,260 above is that value. Add the same amount if you extend the deadline. For 600 seconds:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{"type": "command", "command": "nodd hook --expires-in 600", "timeout": 1560}]
}
]
}
}
Claude Code cancels a hook that reaches its timeout and discards its output. Per the docs, a timed-out PreToolUse hook does not block the tool; the call goes back to the normal permission flow. A short timeout cuts nodd hook off before it can print a denial.
Ask only for some commands
Gating all of Bash means even ls sends a notification. Claude Code hooks take an if field with permission rule syntax. This asks only for git push.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{"type": "command", "if": "Bash(git push *)", "command": "nodd hook", "timeout": 1260}]
}
]
}
}
The docs call if best-effort: when Claude Code cannot tell which commands will run, it runs the hook anyway. But a command written another way, such as git -C . push, does not match. For anything you must stop, gate it without if or refuse it with a deny rule.
There is a diagram of the flow in Use cases.
Caveats
- Ask and deny rules beat the hook. Even when the hook returns
allow, a matching deny rule refuses the call and a matching ask rule still prompts at the computer. Do not put commands you leave tonodd hookin ask rules, or you approve twice - Plan mode ignores the approval. Per the docs, in plan mode a hook's
allowhas no effect on calls that are not read-only - Claude waits. Nothing after that tool call happens until you answer or the deadline passes
- Open requests are limited. 3 on Free, 500 on Team. With several subagents in parallel, requests over the limit are refused and
nodd hookdenies them - Keep secrets out of commands. The command becomes the message body. Bodies are stored encrypted to each device, but our servers can read a body until it is encrypted, and rejection reasons are not encrypted to devices. For passwords, see passing secrets to scripts
- MCP cannot enforce a stop. A model can ignore answers from
nodd mcp. Use the hook when execution must stop. Human approval for AI agents explains the difference
FAQ
- Can I answer Claude Code permission prompts from my phone?
- Yes. On a claude.ai plan, Remote Control lets you answer in the Claude app. With a PreToolUse hook, another app such as Nodd can return approve or reject.
- Can I answer from a notification sent by a Notification hook?
- No. Notification hooks cannot block or change anything, so they only tell you. To answer, use Remote Control or a PreToolUse hook.
- What happens if I do not respond on my iPhone?
- nodd hook returns a denial when the response deadline passes, and the command does not run. The default deadline is 300 seconds, and --expires-in changes it.
- Does it work if I use Claude Code with an API key or Amazon Bedrock?
- nodd hook runs as a hook from your Claude Code settings, so it does not depend on how Claude Code signs in. Remote Control needs a claude.ai account and does not work with API keys.
- Does it work on the free plan?
- Yes. The free plan allows 3 open requests at a time. If you run several agents at once, Team fits better.
Nodd delivers questions from scripts, CI, and AI agents to your iPhone, and returns your Face ID approval to the program that asked. There is a free plan.