The problem: you keep checking on the agent
claude agents, then you sit there refreshing to see if it's done. That polling is the tax on autonomy — the agent runs itself, but you still babysit it. v2.1.198 kills the polling. The fix is a hook you almost certainly already have — the Notification hook — and one new event it now fires.What v2.1.198 actually changed
Notification hook already existed — it fired when the agent needed a permission decision or went idle. Claude Code v2.1.198 added two new events to that same hook, covering the full background-agent lifecycle. Straight from the v2.1.198 release notes: "Added background agent notifications in claude agents — sessions that need input or finish now fire the Notification hook (agent_needs_input / agent_completed)."agent_needs_input— the background agent is blocked waiting on you (a question, a decision).agent_completed— the background agent has finished its work. This is the one you want for "ping me when it's done."- Both ride on the existing Notification hook — same config block, new triggers.
The snippet: ping yourself on agent_completed
Notification hook to your settings.json. The Notification event is the key; each entry runs a shell command. This one shells out to a webhook curl — swap the URL for your Slack Incoming Webhook, a Telegram Bot sendMessage URL, or any HTTP endpoint you own:{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "curl -s -X POST -H 'Content-Type: application/json' -d '{\"text\":\"Claude Code agent finished \\u2705\"}' \"$SLACK_WEBHOOK_URL\""
}
]
}
]
}
}settings.json already has a hooks key, add Notification as a sibling of your existing event keys — don't replace the whole hooks object. The empty matcher means it runs on any Notification event (which now includes agent_completed).Point it at Slack, Telegram, or any webhook
command is just a shell line, so the destination is your choice. Set the URL as an env var (e.g. SLACK_WEBHOOK_URL) so it's not hard-coded in the file:| Destination | URL to use | Payload shape |
|---|---|---|
| Slack | Your Incoming Webhook URL | {"text":"..."} |
| Telegram | https://api.telegram.org/bot<token>/sendMessage | {"chat_id":"...","text":"..."} |
| Any webhook | Your own HTTPS endpoint | Whatever your endpoint expects |
$SLACK_WEBHOOK_URL (or your bot token) from the environment rather than pasting the raw URL into settings.json.Test that it actually fires
- Sanity-check the hook is registered. Run
/hooksin Claude Code and confirmNotificationshows your command. This proves the JSON parsed and the hook loaded. - Dry-run the command by hand. Copy just the
curlline into your terminal (with the env var set) and run it. You should see the test message arrive in Slack/Telegram — this isolates the webhook from Claude Code. - Fire the real event. Launch a small background agent with
claude agentsand let it finish. On completion theagent_completedevent fires the Notification hook and you get the ping — no polling, no babysitting.
curl runs standalone, and re-open /hooks to make sure Notification is listed under the right settings file.Get the next drop
One agent-automation snippet a week, plus the occasional bonus template. No spam, unsubscribe anytime.
By submitting you agree to our Privacy Policy & Terms. Unsubscribe anytime.
Frequently asked questions
Is agent_completed a brand-new hook in Claude Code?
Notification hook. In v2.1.198 the Notification hook (which already fired on permission prompts and idle) gained two new triggers: agent_needs_input and agent_completed. Same config block, new events — so it's a tiny change, not a rebuild.How do I get pinged when my Claude Code agent finishes?
Notification hook to settings.json whose command curls your Slack/Telegram/webhook URL. When a background agent from claude agents finishes, the new agent_completed event fires the hook and your endpoint gets the message. See the snippet in the guide.Where do I put the settings.json hook?
hooks key already exists, add Notification as a sibling of your existing event keys rather than replacing the whole hooks object. Then run /hooks to confirm it loaded.Can I use this with Telegram instead of Slack?
command is just a shell line, so point the curl at https://api.telegram.org/bot<token>/sendMessage with a {"chat_id":"...","text":"..."} payload. Any HTTP endpoint you own works the same way.How does this combine with the auto-commit change in v2.1.198?
agent_completed notification and an agent can work unattended, open the draft PR, and ping you the moment it's done — you just review and merge. No polling.