AlphornAlphorn Docs

AI Agent Notifications

Get notified when AI coding agents need input, finish tasks, or encounter errors.

AI coding agents run for minutes or hours. You don't want to sit watching a terminal — let Alphorn notify you when the agent needs attention.

Claude Code

Claude Code has a built-in hooks system that can send HTTP requests or run shell commands on specific events. Configure it to notify Alphorn when Claude is waiting for your input.

Setup

Add a Notification hook to your Claude Code settings. You can configure hooks at three levels:

  • ~/.claude/settings.json — all projects (recommended)
  • .claude/settings.json — single project (shareable)
  • .claude/settings.local.json — single project (gitignored)

Notify when waiting for input

This fires whenever Claude Code is idle and waiting for your input:

~/.claude/settings.json
{
  "hooks": {
    "Notification": [
      {
        "matcher": "idle_prompt",
        "hooks": [
          {
            "type": "command",
            "command": "jq -c '{title: (\"Claude Code — \" + (.cwd | split(\"/\") | last)), message: .message, priority: 3, tags: [\"ai-agent\", \"claude-code\", \"waiting\"]}' | curl -s -X POST https://app.alphorn.dev/api/webhooks/wh_abc123 -H 'Content-Type: application/json' -d @-",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

The hook receives JSON on stdin with the fields notification_type, message, cwd, and session_id. The jq command transforms it into Alphorn's payload format and curl sends it.

Notify on permission prompts

Get alerted when Claude needs you to approve a tool call:

~/.claude/settings.json
{
  "hooks": {
    "Notification": [
      {
        "matcher": "permission_prompt",
        "hooks": [
          {
            "type": "command",
            "command": "jq -c '{title: (\"Claude Code — Permission needed\"), message: .message, priority: 4, tags: [\"ai-agent\", \"claude-code\", \"permission\"]}' | curl -s -X POST https://app.alphorn.dev/api/webhooks/wh_abc123 -H 'Content-Type: application/json' -d @-",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Notify on all events

Catch everything — idle prompts, permission requests, and auth events:

~/.claude/settings.json
{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "jq -c '{title: (\"Claude Code — \" + (.cwd | split(\"/\") | last)), message: ((.notification_type // \"notification\") + \": \" + (.message // \"no details\")), priority: (if .notification_type == \"permission_prompt\" then 4 else 3 end), tags: [\"ai-agent\", \"claude-code\", .notification_type]}' | curl -s -X POST https://app.alphorn.dev/api/webhooks/wh_abc123 -H 'Content-Type: application/json' -d @-",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Available notification types

MatcherWhen it fires
idle_promptClaude finished and is waiting for your input
permission_promptClaude needs permission to run a tool
auth_successAuthentication completed
elicitation_dialogAn MCP server is requesting user input
(empty string)All notification types

OpenAI Codex CLI

Codex CLI doesn't have a built-in hook system, but you can wrap it with a script that sends notifications on completion:

codex-notify.sh
#!/bin/bash
WEBHOOK="https://app.alphorn.dev/api/webhooks/wh_abc123"
PROJECT=$(basename "$PWD")

# Run Codex
codex "$@"
EXIT_CODE=$?

if [ $EXIT_CODE -eq 0 ]; then
  curl -s -X POST "$WEBHOOK" \
    -H "Content-Type: application/json" \
    -d "{
      \"title\": \"Codex — $PROJECT\",
      \"message\": \"Task completed\",
      \"priority\": 3,
      \"tags\": [\"ai-agent\", \"codex\", \"completed\"]
    }"
else
  curl -s -X POST "$WEBHOOK" \
    -H "Content-Type: application/json" \
    -d "{
      \"title\": \"Codex — $PROJECT\",
      \"message\": \"Exited with code $EXIT_CODE\",
      \"priority\": 4,
      \"tags\": [\"ai-agent\", \"codex\", \"error\"]
    }"
fi

Use it as a drop-in replacement:

alias codex="/path/to/codex-notify.sh"

Aider

Aider supports a --notification-command flag that runs a shell command when it needs attention:

aider --notification-command "curl -s -X POST https://app.alphorn.dev/api/webhooks/wh_abc123 \
  -H 'Content-Type: application/json' \
  -d '{\"title\": \"Aider — waiting\", \"message\": \"Aider needs your input\", \"priority\": 3, \"tags\": [\"ai-agent\", \"aider\", \"waiting\"]}'"

Or set it permanently in .aider.conf.yml:

.aider.conf.yml
notification-command: >-
  curl -s -X POST https://app.alphorn.dev/api/webhooks/wh_abc123
  -H 'Content-Type: application/json'
  -d '{"title": "Aider — waiting", "message": "Aider needs your input", "priority": 3, "tags": ["ai-agent", "aider", "waiting"]}'

Custom agents

For any agent or script you build yourself, send a notification at the decision points:

import requests

WEBHOOK = "https://app.alphorn.dev/api/webhooks/wh_abc123"

def notify(event, message, priority=3):
    requests.post(WEBHOOK, json={
        "title": f"Agent — {event}",
        "message": message,
        "priority": priority,
        "tags": ["ai-agent", event],
    }, 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=5)

# Cost tracking
notify("cost", f"${cost:.2f} spent of ${budget:.2f} budget",
       priority=4 if cost > budget * 0.8 else 2)

Routing examples

ChannelFilterPurpose
Telegramtags CONTAINS "waiting" OR tags CONTAINS "permission"Instant alert when any agent is blocked
Slack (#dev)tags CONTAINS "ai-agent"All agent activity
PagerDutytags CONTAINS "error" AND priority >= 4Escalate critical agent failures
Emailtags CONTAINS "completed"Archive completed task summaries

On this page