Agent Update

Guide

Agents that can reach you.

What a long run can tell you, what it can ask you, and why two-way beats a webhook.

The problem is the waiting

Tokens are not the expensive part of running a coding agent. You are. On a refactor, a migration or a long test suite, the agent works for twenty minutes and you stay near the terminal for twenty minutes, because you cannot predict when either thing you care about happens: it finished, or it stopped and needs you.

Neither is worth watching a scrollback for. Both are worth a notification.

Getting told when a run finishes

Give the agent a tool that texts you, then tell it when to use it. In Agent Update that tool is send_message. The agent calls it with one sentence, and the sentence arrives on your phone as a push notification. The call goes to our server, not to your machine, so nothing has to stay open on your laptop.

It works the same in any agent. Claude Code, Codex, Cursor, OpenCode and poolside all speak MCP, so they get the tool from one URL and one header — see the quick start. Anything that does not speak MCP, like a cron job or a four-line shell script, makes the same call over plain HTTP.

Getting the when right matters. An agent that texts on every file write gets muted within a day, and a muted agent is no agent. Write the rule where the agent will read it — CLAUDE.md, AGENTS.md, a Cursor rule — and be specific: text me when a long task finishes, text me when you are blocked, never text me about anything under a minute.

Letting a run ask you something

A notification service cannot do this half. ask_question sends a question with up to six tappable options. Give it a wait_seconds between 1 and 60 and the tool call blocks until you answer or the window closes. Your answer comes back as the result of the call, so the run keeps going with your decision instead of guessing or stopping.

POST /v1/agent/messages
curl -sS -X POST https://api.tryagentupdate.com/v1/agent/messages \
  -H "Authorization: Bearer $AGENT_UPDATE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "question",
    "text": "The migration drops the legacy sessions table. Run it?",
    "options": ["Run it", "Skip for now"]
  }'

The way to think about it: a question is an approval gate. Anywhere a run would otherwise stop and wait for you, or guess and be wrong, is a question rather than a message. Four that come up constantly:

  • Anything destructive — a migration that drops a table, a force-push, deleting a bucket.
  • Anything that spends money or reaches production — a deploy, a release, a paid run.
  • A requirement with two honest readings, where guessing wrong costs an hour of rework.
  • A failure the agent cannot attribute: carry on, or stop here?

Whether it gates is just wait_seconds. At 0 the question is sent and the run carries on — right for something you want to see and answer whenever. Above zero nothing proceeds until you answer or the clock runs out, which is the gate. Say what happens when the clock runs out in the same breath as the instruction to ask: take the safe option and report it, or leave the work undone. An agent with no fallback either invents one or stalls.

You do not have to use the options. Tap one, or ignore them and type a reply — the agent gets whatever you wrote. Over plain HTTP the waiting half is GET /v1/agent/messages/:id/answer?wait=45, which returns the moment you answer.

This is what makes an overnight run worth starting. An agent that hits a destructive migration at 2am asks, waits its sixty seconds, and if you are asleep it takes the fallback you told it to take.

Every agent is its own sender

Messages arrive as iOS communication notifications, not app banners. The agent is the sender: its name is the title, and it gets its own avatar and its own thread in Notification Centre.

That matters for Focus. iOS lets you allow a person through Do Not Disturb, and each agent counts as one. So the deploy that matters can wake you while the other four stay silent until morning. A service that sends everything from itself cannot do that.

Why not ntfy or a Slack webhook

They are one-way. A script pushes a line out and nothing comes back into the run. They are good at telling you something happened. They cannot let a run pause for your answer, which is the case that costs you time.

The second difference is on the phone. A webhook lands as one more banner from one more app, so letting the deploy alert through Focus means letting everything through. Here each agent has its own permission.

If you only want a completion ping and you already run ntfy, keep running ntfy. If you want the run to ask you things, you need a different tool.

What it costs

Starter is free forever: 1 agent, unlimited messages, no card. Plus is $3 a month for 2 agents, Max is $5 a month for 5 agents, and Ultra is $10 a month for 15 agents.

A plan buys one thing: how many agents you can run at once. Messages are unlimited on every plan and nothing is metered. Live status — the one-line “what is it doing right now” beside each agent — is included on every paid plan. Subscriptions are auto-renewable in-app purchases through the App Store. Hitting the agent cap stops you adding new agents. It never deletes the ones you have.

What you have to install

Nothing. No SDK, no webhook endpoint to expose, no queue. Your agent makes an HTTPS request and the notification arrives. The whole integration is a token, five tools and one base URL.

There is exactly one optional local piece, and it is worth knowing what it buys. Outbound — the agent texting you — needs nothing. Inbound is the asymmetric half: your reply sits on the server until the agent calls check_replies, which on a long run can be a while. A small CLI wires that into Claude Code, Codex and Cursor so a reply lands at the end of a turn, or mid-run if you leave it polling. It is not a service and nothing starts with your machine. The quick start sets it up per harness.

Start with the quick start, then the page for whatever you are running: Claude Code, Codex, Cursor, OpenCode, poolside, or one of the rest.