For alerts at your desk, turn on Completion Sound and System Notifications under Cursor Settings > General > Notifications. For your phone, use Cursor for iOS (public beta on paid plans) or a stop hook in ~/.cursor/hooks.json that posts to a push service. If you want the agent to ask you a question and wait for the answer, give it an MCP tool that does exactly that.
Each of these catches a different moment, and none of them catches everything. The rest of this guide covers what each option does, the exact settings and files, and the gaps that the Cursor forum keeps asking about.
Built-in desktop notifications
Cursor has two notification toggles in Cursor Settings > General > Notifications. Neither is described in the official docs, so the details below come from Cursor staff replies on the forum.
- Completion Sound plays a chime when the agent finishes. Since mid-2026 it waits until the parent agent and its background subagents are all done, so a run with several subagents no longer chimes for each one (staff reply, Aug 2026). It is one global toggle, with no per-chat control.
- Custom sound. With Completion Sound on, click Browse and pick an mp3, wav or ogg file (staff reply, June 2026).
- System Notifications shows an OS notification when the agent needs your attention, approval prompts included. According to a staff reply in the hook feature request thread, these only appear when Cursor isn't the focused window.
The focus rule catches people out. If Cursor is on one monitor and you're reading docs in a browser on another, you get the banner. If Cursor is in front but you're looking at your phone, you get nothing, so turn on both toggles.
On macOS, also check that Cursor is allowed to post notifications in System Settings > Notifications, or the toggle in Cursor has nothing to deliver through.
Fewer prompts in the first place
The agent only stops for approval when your run mode tells it to. Cursor's run modes live in Settings > Agents > Approvals & Execution:
- Auto-review, the default: allowlisted calls run right away, other shell commands run in the sandbox when they can, and the rest go to a classifier. You see an approval prompt when the classifier blocks a call and the agent still wants to go ahead.
- Allowlist: anything not on your allowlist waits for you.
- Run Everything: no approval prompts.
Browser, file-deletion and external-file protections can still ask for approval in any mode. Cursor also says plainly that Auto-review "is not a security boundary", so the trade-off is yours to make.
Cursor CLI notifications
The Cursor CLI (the agent command) doesn't use the editor's settings. It has its own notifications setting in ~/.cursor/cli-config.json ($env:USERPROFILE\.cursor\cli-config.json on Windows), which the CLI configuration reference describes as "Send a terminal notification when the agent finishes or needs input".
Add it next to the keys already in the file:
{
"version": 1,
"editor": { "vimMode": false },
"permissions": { "allow": ["Shell(ls)"], "deny": [] },
"notifications": true
}
Three things to know:
- Only
permissionscan be set per project (in<project>/.cursor/cli.json).notificationsbelongs in the global file. - The file must be plain JSON with no comments. The CLI manages some fields itself and may rewrite them.
- The CLI uses the same MCP configuration as the editor, so the MCP setup later in this guide works for terminal sessions too. Run
agent mcp listto confirm the server loaded.
Cursor on your phone
Cursor for iOS launched on June 29, 2026, in public beta on paid plans. The mobile docs list Premium, Super, Ultra, Teams and Enterprise, plus the legacy paid plans, and it needs iOS or iPadOS 26.0 or later.
What it gives you:
- Push notifications when an agent finishes, needs input, or is ready for review, according to the launch post.
- Live Activities on the lock screen and Dynamic Island for up to eight agents.
- Cloud agents (formerly Background Agents) that you can start from the phone and leave running. They can also be started from cursor.com/agents, the desktop app, Slack, GitHub, Linear and the API.
- Remote Control for agents running on your computer. On Cursor 3.9.8 or later, turn it on under Settings > Agents in the Agents Window, then type
/remote-controlin the agent's input and send your next message. The session shows up in the app's inbox. On Teams and Enterprise, an admin has to enable it first.
With Remote Control, the agent loop moves to the cloud but every tool call still runs on your machine. So your computer has to stay awake and online. There's a "Keep this computer awake" setting for when it's plugged in.
Two caveats. First, there's no Android app: the docs say "Android is planned" and suggest installing cursor.com/agents in Chrome as a web app. Second, the mobile docs describe following progress, sending follow-ups and reviewing pull requests, but they don't spell out approving individual commands from the phone. If that's the moment you care about, try it in the app before you rely on it.
If you only use Cursor and you carry an iPhone, the iOS app is the best option here. It's built in, it knows the agent's real state, and it needs no scripts.
Push alerts with a stop hook
Cursor hooks are scripts that Cursor runs at fixed points in the agent loop, passing JSON in on stdin and reading JSON back from stdout. The one you want for notifications is stop, which runs when the agent loop ends. Its input is the common fields (conversation_id, workspace_roots and others) plus:
{ "status": "completed", "loop_count": 0 }
status is completed, aborted or error. A hook can return {"followup_message": "..."} to have Cursor send another message automatically. For a notification you return {}.
Hooks live in one of two files:
~/.cursor/hooks.jsonfor you, in every project. Commands run from~/.cursor/.<project>/.cursor/hooks.jsonfor a repo, checked in with it. Commands run from the project root, so paths look like.cursor/hooks/notify-phone.sh.
A notification is personal, so use the user file. Cursor watches it and reloads on save.
The hook script
This script pushes a notification only when a run took two minutes or more, so you don't get pinged for quick answers while you're sitting right there. It uses two more hooks to get there: beforeSubmitPrompt records the start time, and afterAgentResponse keeps the first 300 characters of the agent's final message to use as the notification body.
Save it as ~/.cursor/hooks/notify-phone.sh:
#!/bin/bash
# ~/.cursor/hooks/notify-phone.sh
# beforeSubmitPrompt: note the start time. afterAgentResponse: keep the reply.
# stop: push a notification if the run took 2 minutes or more.
input=$(cat)
event=$(jq -r '.hook_event_name' <<<"$input")
state="${TMPDIR:-/tmp}/cursor-$(jq -r '.conversation_id' <<<"$input")"
case "$event" in
beforeSubmitPrompt)
date +%s > "$state.start"
echo '{"continue": true}'
exit 0 ;;
afterAgentResponse)
jq -r '.text[0:300]' <<<"$input" > "$state.msg"
echo '{}'
exit 0 ;;
esac
# stop
status=$(jq -r '.status' <<<"$input")
start=$(cat "$state.start" 2>/dev/null || date +%s)
elapsed=$(( $(date +%s) - start ))
project=$(basename "$(jq -r '.workspace_roots[0] // "cursor"' <<<"$input")")
msg=$(cat "$state.msg" 2>/dev/null)
[ -z "$msg" ] && msg="The agent loop ended."
key=$(cat ~/.config/alertmcp/key 2>/dev/null)
if [ -n "$key" ] && [ "$status" != "aborted" ] && [ "$elapsed" -ge 120 ]; then
priority=normal; [ "$status" = "error" ] && priority=high
jq -n --arg t "Cursor $status: $project ($((elapsed / 60)) min)" \
--arg b "$msg" --arg p "$priority" \
'{title: $t, body: $b, priority: $p, topic: "cursor"}' |
curl -s -m 10 -o /dev/null https://api.alertmcp.com/v1/alerts \
-H "Authorization: Bearer $key" \
-H "Content-Type: application/json" -d @-
fi
echo '{}'
Then register it for all three events in ~/.cursor/hooks.json. If the file already exists, merge these entries into its hooks object:
{
"version": 1,
"hooks": {
"beforeSubmitPrompt": [{ "command": "./hooks/notify-phone.sh" }],
"afterAgentResponse": [{ "command": "./hooks/notify-phone.sh" }],
"stop": [{ "command": "./hooks/notify-phone.sh", "timeout": 15 }]
}
}
Make it executable and store your key outside any repo. The script needs jq.
chmod +x ~/.cursor/hooks/notify-phone.sh
mkdir -p ~/.config/alertmcp
printf '%s' 'amcp_sk_your_key' > ~/.config/alertmcp/key
chmod 600 ~/.config/alertmcp/key
The script posts to AlertMCP's HTTP endpoint, but any push service works. For ntfy, replace the jq -n ... | curl ... pipeline with one line:
curl -s -m 10 -o /dev/null -H "Title: Cursor $status: $project" -d "$msg" https://ntfy.sh/your-long-random-topic
Our comparison of ntfy, Pushover and Slack webhooks covers the trade-offs between push services, including what each one costs and what happens on iOS.
A few notes from the hooks docs:
- Open the Hooks tab in Customize, or the Hooks output channel, to see whether your hook ran and why it failed.
- On Windows, the desktop app runs hook commands through PowerShell, so you'd port this script to a
.ps1file. - Cloud agents run project hooks from
.cursor/hooks.jsonbut never user hooks from~/.cursor. For cloud agents, rely on the iOS app or put the hook in the repo. - The body carries the first 300 characters of the agent's last message. If that may contain code or secrets you don't want on a third-party server, send a fixed string instead.
What hooks can't catch
There's no hook for "the agent is waiting for your approval". The current event list is sessionStart, sessionEnd, preToolUse, postToolUse, postToolUseFailure, subagentStart, subagentStop, beforeShellExecution, afterShellExecution, beforeMCPExecution, afterMCPExecution, beforeReadFile, afterFileEdit, beforeSubmitPrompt, preCompact, stop, afterAgentResponse and afterAgentThought. A July 2026 feature request on the forum asks for one, and Cursor staff called it something they're tracking.
The workaround staff suggested is beforeShellExecution (or beforeMCPExecution for MCP tools). It runs before the command, with the command text in its input, and must return {"permission": "allow" | "deny" | "ask"}. A hook with a matcher for risky commands can send a push and return "ask", so Cursor still shows its own prompt. Be careful with these: for permission hooks, invalid JSON blocks the action, and returning "allow" approves it without you.
stop also never fires while the agent is paused on an approval card, because the loop hasn't ended. That gap is why System Notifications and the iOS app matter.
If you also run Claude Code, Cursor can load Claude Code hooks too. Our Claude Code notifications guide covers that side.
Let the agent ask you a question
Hooks tell you that something happened. Sometimes you want the reverse: the agent stops before a migration, asks "Run it against staging?" on your phone, and continues with your answer. That needs a tool the agent can call and wait on, which is what MCP is for.
AlertMCP is one such MCP server. Add it to .cursor/mcp.json in the project, or ~/.cursor/mcp.json for every project. Cursor's MCP docs support ${env:NAME} in url and headers, which keeps the key out of the repo:
{
"mcpServers": {
"alertmcp": {
"url": "https://api.alertmcp.com/mcp",
"headers": { "Authorization": "Bearer ${env:ALERTMCP_KEY}" }
}
}
}
You get an amcp_sk_ key from the dashboard after you sign in with Google or GitHub. Setup for other clients is in our remote MCP server guide.
Then tell the agent when to use it. Cursor rules go in .cursor/rules/ and must use the .mdc extension; a plain .md file there is ignored. Save this as .cursor/rules/alertmcp.mdc:
---
description: When to notify or ask the user through AlertMCP
alwaysApply: true
---
- When a task takes longer than 2 minutes, call alertmcp notify when you finish.
- Before running migrations, deploys or deleting files, call alertmcp ask with
the safest option first, then call get_answer until it returns an answer.
- If nobody answers before the deadline, do not run the risky step.
If you'd rather not use rules, the same lines work in an AGENTS.md file at the project root.
Here's what happens at run time:
- The agent calls
askwith a question of up to 200 characters and two to four buttons, safest first, such as "Not yet" then "Run migration". - You get a push on your phone and desktop with those buttons.
- The agent calls
get_answer, which waits up to 50 seconds per call (25 by default) and returns answered, pending or timed out. On pending, it calls again. - Your workspace sets a deadline between 5 minutes and 24 hours. When it passes, the agent is told nobody answered, or continues with the first (safest) option, or the question escalates to your team's admins. You choose which.
Two practical points. Cursor asks for approval before using MCP tools by default, so allowlist AlertMCP's tools in Settings > Agents > Approvals & Execution. Otherwise the ask itself waits for a click at your desk.
And to be plain about the limits: AlertMCP doesn't answer Cursor's own approval prompts. It can't see the Run/Reject card Cursor shows for a shell command. The agent calls ask because your rule or its own judgement says to, and that's the only time you hear from it. For Cursor's built-in prompts, use the iOS app.
AlertMCP isn't the only server that does this. Pushary has its own ask-and-wait tools, and community servers connect agents to ntfy, Telegram or Discord. What AlertMCP adds is apps for Android, iOS (TestFlight beta), macOS, Windows, Linux, the web and a CLI, plus per-topic rate limits and quiet hours so a chatty agent can't flood you. The Cloud plan is free for up to 1,000 alerts a month. If you're deciding when an agent should ask at all, our guide to human-in-the-loop AI agents covers that policy question.
Which option to use
| Option | Reaches you on | Agent finished | Waiting on approval | Agent waits for your answer |
|---|---|---|---|---|
| Completion Sound | Desktop speakers | Yes | No | No |
| System Notifications | Desktop, when Cursor isn't focused | Yes | Yes | No |
CLI notifications |
Your terminal | Yes | Yes ("needs input") | No |
| Cursor for iOS | iPhone, iPad | Yes | Needs input, per Cursor | Follow-ups via Remote Control |
stop hook plus push |
Any device with a push app | Yes | No | No |
MCP ask (AlertMCP) |
Phone, desktop, web | Via notify |
No, agent-initiated only | Yes |
Most people end up combining two of these:
- iPhone, Cursor only: turn on both desktop toggles and install Cursor for iOS. You probably need nothing else.
- Android, or a Windows or Linux desk: desktop toggles plus a
stophook to a push service. - Several agents, or decisions you want made away from the desk: an MCP server with ask-and-wait tools, plus a rule that says when to use it.
Frequently asked questions
- Does Cursor notify me when the agent finishes?
- Yes, on the desktop. Turn on Completion Sound and System Notifications under Cursor Settings > General > Notifications. System notifications only appear when the Cursor window is not focused. The Cursor CLI has its own notifications setting in ~/.cursor/cli-config.json.
- Can Cursor send notifications to my phone?
- Cursor for iOS, in public beta on paid plans since June 2026, sends a push when an agent finishes, needs input or is ready for review. There is no Android app yet. On Android, or for a plain ping on any device, use a stop hook that posts to a push service such as ntfy, Pushover or AlertMCP.
- What is the Cursor stop hook?
- It is a hook defined in hooks.json that runs when the agent loop ends. It receives a status of completed, aborted or error, and it can return a followup_message that Cursor submits as your next message.
- Can a Cursor hook tell me when the agent is waiting for approval?
- Not directly. Cursor has no dedicated hook for the moment an approval card appears. The closest workaround is a beforeShellExecution or beforeMCPExecution hook, which runs before a command or MCP tool call and returns allow, deny or ask.
- Can AlertMCP approve Cursor's own run prompts from my phone?
- No. AlertMCP is agent-initiated: the agent calls its ask tool because a rule or its own judgement tells it to. It does not see or answer the approval cards Cursor shows for commands and tools. For those, use Cursor's iOS app.