AI Agent Notifications
Notifications from AI coding agents (Claude Code, Codex, Cursor, Gemini CLI, Aider) when they finish or need input. Plus AGENTS.md snippet and Agent Skill.
AI coding agents run for minutes or hours, and they stop whenever they need a decision from you. Alphorn turns those moments into a notification on the channel you actually look at (Slack, Telegram, SMS, push, email, or any other supported channel), with filters so a blocked agent can page you while a finished task only lands in a chat.
Every agent integration is the same HTTP request:
curl -fsS --max-time 5 -X POST https://app.alphorn.dev/n/V1StGXR8_Z5jdHi6B-myT \
-H "Authorization: Bearer $ALPHORN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Claude Code - my-app", "message": "Needs permission to run tests", "priority": 4, "tags": ["ai-agent", "claude-code", "permission"]}'Create a webhook first (see Webhooks) and use its Endpoint URL (plus its API key, if you switched on Require API key).
Set up your agent
MCP Server
send_notification tool for any MCP client
Claude Code
Stop and Notification hooks
OpenAI Codex CLI
Stop and PermissionRequest hooks, legacy notify
Cursor
stop hook for agent runs
Gemini CLI
AfterAgent and Notification hooks
Aider
notifications-command
Recommended conventions
Using the same fields across all agents keeps your filters simple:
| Situation | priority | Tags |
|---|---|---|
| Task finished | 2 | ai-agent, <agent>, completed |
| Waiting for input | 3 | ai-agent, <agent>, waiting |
| Needs permission or blocked | 4 | ai-agent, <agent>, permission |
| Failed | 4 | ai-agent, <agent>, error |
Put the project name in the title (for example Claude Code - my-app) so you can tell parallel sessions apart. Alphorn truncates title to 200 and message to 4,000 characters, so you can pass an agent's last response without trimming it. See the API Reference for all fields.
Let the agent notify you itself
Hooks fire on fixed events. To let the agent decide when a notification is worth sending (for example "tell me when the migration is done"), give it instructions. Set two environment variables where the agent runs:
export ALPHORN_WEBHOOK_URL="https://app.alphorn.dev/n/V1StGXR8_Z5jdHi6B-myT"
export ALPHORN_API_KEY="alp_..."The snippets below build the JSON with jq, so the agent's environment needs jq and curl.
AGENTS.md snippet
Add this to the AGENTS.md (or CLAUDE.md) of your project. Codex, Cursor, and many other agents read AGENTS.md automatically. Claude Code reads CLAUDE.md, which can import it with a line containing @AGENTS.md.
## Notifications
Notify the user with Alphorn when a long-running task finishes or fails, or when you
are blocked on a decision and the user may not be watching. Do not notify for routine steps.
```bash
curl -fsS --max-time 5 -X POST "$ALPHORN_WEBHOOK_URL" \
-H "Authorization: Bearer $ALPHORN_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg t "<short title>" --arg m "<what happened, what you need>" \
'{title: $t, message: $m, priority: 3, tags: ["ai-agent"]}')"
```
- priority: 2 = finished, 3 = needs input, 4 = blocked or failed
- Start the title with the project name. Never include secrets in the message.Agent Skill
Agents that support Agent Skills (including Claude Code) load a skill only when it is relevant. Save this as ~/.claude/skills/alphorn-notify/SKILL.md for all projects, or .claude/skills/alphorn-notify/SKILL.md for one project:
---
name: alphorn-notify
description: Send the user a notification through Alphorn. Use when the user asks to be notified, pinged, or alerted, when a long-running task finishes or fails, or when you are blocked and the user may be away.
---
# Notify the user with Alphorn
Requires ALPHORN_WEBHOOK_URL and ALPHORN_API_KEY in the environment, plus jq and curl.
```bash
curl -fsS --max-time 5 -X POST "$ALPHORN_WEBHOOK_URL" \
-H "Authorization: Bearer $ALPHORN_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg t "$TITLE" --arg m "$MESSAGE" --argjson p 3 \
'{title: $t, message: $m, priority: $p, tags: ["ai-agent"]}')"
```
- Title: project name plus a few words, e.g. "my-app - tests passing".
- Message: what happened and what you need from the user, in one or two sentences.
- Priority: 2 = finished, 3 = needs input, 4 = blocked or failed.
- A 201 response means the notification was accepted.
- 401: the Authorization header is missing or malformed, or the API key is wrong. Check that ALPHORN_API_KEY is set.
- 400: invalid JSON body. 403: webhook disabled. 404: wrong webhook URL. 413: body too large (over 1 MiB). 429: quota exceeded, don't retry right away. 508: loop detected.
- Never include secrets, tokens, or file contents in the message.Custom agents
For an agent you build yourself, send a notification at the decision points:
import os
import requests
WEBHOOK = os.environ["ALPHORN_WEBHOOK_URL"]
HEADERS = {"Authorization": "Bearer " + os.environ["ALPHORN_API_KEY"]}
def notify(event, message, priority=3):
requests.post(WEBHOOK, json={
"title": f"Agent - {event}",
"message": message,
"priority": priority,
"tags": ["ai-agent", event],
}, headers=HEADERS, timeout=5)
# When the agent needs human input
notify("waiting", "Agent is blocked and needs your decision")
# When a task completes
notify("completed", f"Finished in {duration}m: {summary}", priority=2)
# When something goes wrong
notify("error", f"{error}", priority=4)
# Cost tracking
notify("cost", f"${cost:.2f} spent of ${budget:.2f} budget",
priority=4 if cost > budget * 0.8 else 2)Routing examples
| Channel | Filter | Purpose |
|---|---|---|
| Telegram | Tags has any of waiting, permission | Instant alert when any agent is blocked |
| Slack (#dev) | Tags has any of ai-agent | All agent activity |
| SMS | Priority greater than 3 | Only when an agent is stuck or failed |
Tags has any of completed | Archive of finished tasks |
Integrations
Send alerts to Alphorn from Grafana, Prometheus Alertmanager, Uptime Kuma, GitHub Actions, Jenkins, Home Assistant, Sonarr, and other tools via webhooks.
MCP Server
Alphorn MCP server: give Claude Code, Claude Desktop, Cursor, Codex, and other MCP clients a send_notification tool that reaches Slack, Telegram, email, or SMS.