Skip to content

hecspc/claude-notify

Repository files navigation

claude-notify

Notification bot for Claude Code hook events. Get notifications via Desktop, Telegram, Slack, Discord, ntfy, Pushbullet, Teams, Webhook, Email, WhatsApp, or OpenClaw when Claude needs your input — permission prompts, questions, idle sessions, or task completions.

Built in Rust for a single native binary with no runtime dependencies.

Why

When running Claude Code sessions (especially long-running or parallel ones), sessions sit idle waiting for attention. claude-notify sends notifications so you can monitor from mobile or another screen — and quickly switch between backends depending on where you are.

Claude Code Plugin

The easiest way to use claude-notify is as a Claude Code plugin. The plugin auto-registers all hooks and provides namespaced slash commands — no manual configuration needed.

# 1. Install the binary
curl -sSL https://raw.githubusercontent.com/hecspc/claude-notify/main/install.sh | sh

# 2. Install the plugin (auto-registers hooks)
claude plugin install claude-notify

# 3. Configure a backend via slash command
/claude-notify:setup-desktop
/claude-notify:setup-telegram <BOT_TOKEN> <CHAT_ID>

Plugin Skills

Skill Description
/claude-notify:setup-desktop Enable native OS notifications (zero-config)
/claude-notify:setup-telegram Configure Telegram bot notifications
/claude-notify:setup-slack Configure Slack webhook notifications
/claude-notify:setup-discord Configure Discord webhook notifications
/claude-notify:setup-ntfy Configure ntfy push notifications
/claude-notify:setup-pushbullet Configure Pushbullet notifications
/claude-notify:setup-teams Configure Microsoft Teams notifications
/claude-notify:setup-webhook Configure generic webhook notifications
/claude-notify:setup-email Configure email (SMTP) notifications
/claude-notify:setup-whatsapp Configure WhatsApp notifications via Meta Cloud API
/claude-notify:setup-openclaw Configure OpenClaw Gateway notifications
/claude-notify:use Switch active backends (e.g. desktop,slack)
/claude-notify:mute Mute notifications globally or for a session
/claude-notify:unmute Unmute notifications
/claude-notify:status Show current mute status
/claude-notify:session Toggle mute for the current session

Install (without plugin)

If you prefer not to use the plugin, you can install the binary and use setup to configure hooks manually.

# Install latest version
curl -sSL https://raw.githubusercontent.com/hecspc/claude-notify/main/install.sh | sh

# Install a specific version
curl -sSL https://raw.githubusercontent.com/hecspc/claude-notify/main/install.sh | sh -s 1.0.1

# Custom install directory (default: ~/.local/bin)
curl -sSL https://raw.githubusercontent.com/hecspc/claude-notify/main/install.sh | INSTALL_DIR=/usr/local/bin sh

Or build from source:

cargo build --release
cp target/release/claude-notify ~/.local/bin/

Quick Start

# One-command setup: configures credentials + hooks + Claude Code skills
claude-notify setup desktop                                           # zero-config native OS notifications
claude-notify setup telegram YOUR_BOT_TOKEN YOUR_CHAT_ID              # Telegram
claude-notify setup slack https://hooks.slack.com/services/T.../B.../xxx  # Slack
claude-notify setup discord https://discord.com/api/webhooks/123/abc  # Discord
claude-notify setup email me@x.com me@x.com smtp.x.com user pass     # Email (SMTP)
claude-notify setup ntfy https://ntfy.sh/my-claude-topic              # ntfy
claude-notify setup pushbullet YOUR_API_TOKEN                         # Pushbullet
claude-notify setup teams https://xxx.webhook.office.com/...          # Microsoft Teams
claude-notify setup webhook https://example.com/notify                # generic webhook
claude-notify setup webhook ha-appletv http://ha:8123/api/webhook/x   # named webhook instance
claude-notify setup whatsapp PHONE_ID ACCESS_TOKEN 14155551234        # WhatsApp
claude-notify setup openclaw http://localhost:3000 TOKEN +1555551234  # OpenClaw

# Switch backends on the fly
claude-notify use desktop              # at my desk
claude-notify use slack                # going AFK
claude-notify use desktop,slack        # both

This writes ~/.config/claude-notify/config.toml with your credentials, adds hooks to ~/.claude/settings.json, and installs Claude Code slash commands (/notify-mute, /notify-unmute, /notify-use, /notify-session).

Supported Events

Event Icon Description
Permission prompt 🔔 Claude needs tool approval (Bash, Edit, etc.)
Idle prompt Claude is waiting for your response
Elicitation dialog Claude is asking a question
Response complete Claude finished responding (includes last message summary)
Task completed 🎉 A background task finished (includes task subject, teammate, description)

Message Format

🔔 Permission Required
Session: safe-seal (66a021e0) | engineering-bot
─────────────────
Tool: Bash
Action: npm install express
✅ Response Complete
Session: safe-seal (66a021e0) | engineering-bot
─────────────────
I've updated the README.md with the new setup instructions and rebuilt the release binary.
🎉 Task Completed
Session: pink-swan (abc123) | engineering-bot
Task: Implement notification system
Teammate: implementer
─────────────────
Add Telegram notifications for Claude Code hook events

Sessions are identified by a friendly name derived from the session_id (e.g. safe-seal) plus the short UUID and project name, for quick identification across parallel sessions.

CLI Usage

claude-notify                                                  # Normal: read hook JSON from stdin, notify
claude-notify setup telegram <BOT_TOKEN> <CHAT_ID>             # Configure credentials + hooks (user-level)
claude-notify setup telegram <BOT_TOKEN> <CHAT_ID> --project   # Configure hooks in current project
claude-notify setup slack <WEBHOOK_URL>                        # Configure Slack notifications
claude-notify setup desktop                                    # Configure desktop notifications (zero-config)
claude-notify setup email <FROM> <TO> <HOST> <USER> <PASS>     # Configure email via SMTP
claude-notify setup discord <WEBHOOK_URL>                      # Configure Discord notifications
claude-notify setup ntfy <TOPIC_URL>                           # Configure ntfy notifications
claude-notify setup pushbullet <API_TOKEN>                     # Configure Pushbullet notifications
claude-notify setup teams <WEBHOOK_URL>                        # Configure Microsoft Teams notifications
claude-notify setup webhook <URL>                              # Configure generic webhook (unnamed)
claude-notify setup webhook <NAME> <URL>                      # Configure named webhook instance
claude-notify setup whatsapp <PHONE_ID> <TOKEN> <RECIPIENT>  # Configure WhatsApp via Meta Cloud API
claude-notify setup openclaw <URL> <TOKEN> <TARGET>          # Configure OpenClaw Gateway notifications
claude-notify use desktop                                      # Switch active backend(s)
claude-notify use desktop,slack                                # Multiple backends
claude-notify mute                                             # Mute all notifications
claude-notify mute safe-seal                                   # Mute a specific session (friendly name or UUID)
claude-notify unmute                                           # Unmute all
claude-notify unmute safe-seal                                 # Unmute a specific session
claude-notify status                                           # Show mute status
claude-notify --dry-run                                        # Print formatted message to stdout, don't send
claude-notify --version                                        # Print version

Claude Code Skills

Setup installs these slash commands into Claude Code:

Skill Description
/notify-mute Mute all notifications, or pass a session name to mute one
/notify-unmute Unmute all notifications, or pass a session name to unmute one
/notify-use Switch active backends (e.g. /notify-use desktop,slack)
/notify-session Toggle mute for the current session (no args needed)

Muting

Mute notifications globally or per-session. Use the friendly name from the notification (e.g. safe-seal) or the raw session UUID.

claude-notify mute              # Silence everything
claude-notify mute safe-seal    # Silence one session
claude-notify status            # Check what's muted
claude-notify unmute            # Re-enable all

Mute state is stored as files in ~/.config/claude-notify/muted/.

Setup Scopes

  • --user (default) — writes hooks to ~/.claude/settings.json, applies to all projects
  • --project — writes hooks to .claude/settings.json in the current directory, applies to this project only

Both scopes write backend credentials to ~/.config/claude-notify/config.toml.

Configuration

Config File

~/.config/claude-notify/config.toml:

backends = ["desktop"]  # or ["telegram"], ["slack"], ["desktop", "slack"], etc.

# Optional: filter which events trigger notifications (defaults to all)
# events = ["permission_prompt", "idle_prompt", "elicitation_dialog", "stop", "task_completed"]

[telegram]
bot_token = "123456:ABC-DEF..."
chat_id = "123456789"

[slack]
webhook_url = "https://hooks.slack.com/services/T.../B.../xxx"

[discord]
webhook_url = "https://discord.com/api/webhooks/123/abc"

[whatsapp]
phone_number_id = "123456789"
access_token = "EAAxxxxxxx"
recipient = "14155551234"

[openclaw]
gateway_url = "http://localhost:3000"
token = "my-gateway-token"
target = "+15555550123"
channel = "whatsapp"       # optional: whatsapp, telegram, discord, etc.

[email]
from = "claude-notify@example.com"
to = "you@example.com"
smtp_host = "smtp.example.com"
smtp_port = 587
smtp_username = "user"
smtp_password = "password"

[ntfy]
topic_url = "https://ntfy.sh/my-claude-topic"

[pushbullet]
api_token = "o.xxxxxxxxxxxxxxxxxxxxx"

[teams]
webhook_url = "https://xxx.webhook.office.com/webhookb2/..."

[webhook]
url = "https://example.com/notify"                    # unnamed webhook

[webhook.ha-appletv]                                  # named instance
url = "http://homeassistant:8123/api/webhook/claude-notify"

[webhook.ha-direct]                                   # named instance with auth headers
url = "http://homeassistant:8123/api/services/notify/apple_tv"
[webhook.ha-direct.headers]
Authorization = "Bearer YOUR_HA_LONG_LIVED_TOKEN"

Environment Variables

Env vars override config file values.

Variable Purpose Example
NOTIFY_BACKEND Active backend(s), comma-separated desktop, slack,discord
NOTIFY_EVENTS Event filter, comma-separated permission_prompt,idle_prompt
TELEGRAM_BOT_TOKEN Token from @BotFather 123456:ABC-DEF...
TELEGRAM_CHAT_ID User's chat ID 123456789
SLACK_WEBHOOK_URL Slack Incoming Webhook URL https://hooks.slack.com/services/...
DISCORD_WEBHOOK_URL Discord webhook URL https://discord.com/api/webhooks/...
EMAIL_FROM Sender email address claude-notify@example.com
EMAIL_TO Recipient email address you@example.com
EMAIL_SMTP_HOST SMTP server hostname smtp.example.com
EMAIL_SMTP_PORT SMTP port (default 587) 587
EMAIL_SMTP_USERNAME SMTP username user
EMAIL_SMTP_PASSWORD SMTP password password
NTFY_TOPIC_URL ntfy topic URL https://ntfy.sh/my-topic
PUSHBULLET_API_TOKEN Pushbullet API token o.xxxxxxxxxxxxxxxxxxxxx
TEAMS_WEBHOOK_URL Teams webhook URL https://xxx.webhook.office.com/...
WHATSAPP_PHONE_NUMBER_ID WhatsApp Business phone number ID 123456789
WHATSAPP_ACCESS_TOKEN Meta permanent access token EAAxxxxxxx
WHATSAPP_RECIPIENT Recipient phone (international format) 14155551234
OPENCLAW_GATEWAY_URL OpenClaw Gateway URL http://localhost:3000
OPENCLAW_TOKEN Gateway Bearer token my-gateway-token
OPENCLAW_TARGET Target destination +15555550123
OPENCLAW_CHANNEL Delivery channel (optional) whatsapp
WEBHOOK_URL Generic webhook URL https://example.com/notify

Event Filtering

To silence noisy events like "Response Complete":

events = ["permission_prompt", "idle_prompt", "elicitation_dialog", "task_completed"]

Desktop Setup

No configuration needed — just run claude-notify setup desktop. Uses osascript on macOS, notify-send on Linux, and PowerShell toast notifications on Windows.

Discord Setup

  1. In your Discord server, go to a channel's settings → Integrations → Webhooks
  2. Create a new webhook and copy the URL
  3. Run claude-notify setup discord <WEBHOOK_URL>

Ntfy Setup

  1. Pick a topic name at ntfy.sh (or use your own ntfy server)
  2. Subscribe to the topic on your phone via the ntfy app
  3. Run claude-notify setup ntfy https://ntfy.sh/my-claude-topic

Microsoft Teams Setup

  1. In Teams, create an Incoming Webhook via Workflows (Power Automate) — the legacy Office 365 connectors are deprecated
  2. Copy the webhook URL
  3. Run claude-notify setup teams <WEBHOOK_URL>

Email Setup

Configure SMTP credentials for email notifications. Uses STARTTLS on port 587 by default.

claude-notify setup email sender@example.com recipient@example.com smtp.example.com username password

For Gmail, use an App Password with smtp.gmail.com.

Webhook Setup

Point notifications at any HTTP endpoint. The webhook receives a POST with JSON:

{"title": "🔔 Permission Required", "body": "Session: safe-seal ...", "text": "full plain text"}

Unnamed (single): claude-notify setup webhook <URL>

Named instances: claude-notify setup webhook <NAME> <URL> — use webhook.<name> in backends:

claude-notify setup webhook ha-appletv http://homeassistant:8123/api/webhook/claude-notify
claude-notify setup webhook zapier https://hooks.zapier.com/hooks/catch/123/abc
claude-notify use webhook.ha-appletv,webhook.zapier   # use both

Custom headers (e.g. auth tokens) can be added manually to config.toml:

[webhook.ha-direct.headers]
Authorization = "Bearer YOUR_TOKEN"

Any 2xx response is treated as success.

Pushbullet Setup

  1. Go to Pushbullet Settings and create an Access Token
  2. Run claude-notify setup pushbullet <API_TOKEN>

Slack Setup

  1. Go to Slack API: Incoming Webhooks and create a new app (or use an existing one)
  2. Enable Incoming Webhooks and add one to your desired channel
  3. Copy the webhook URL
  4. Run claude-notify setup slack <WEBHOOK_URL>

OpenClaw Setup

OpenClaw is a self-hosted gateway that connects chat apps (WhatsApp, Telegram, Discord, iMessage, etc.) to AI agents. Use it to route claude-notify notifications through any channel OpenClaw supports.

  1. Install and run the OpenClaw Gateway
  2. Get your Gateway URL and Bearer token
  3. Run claude-notify setup openclaw <GATEWAY_URL> <TOKEN> <TARGET>
  4. Optionally specify a delivery channel: --channel whatsapp
claude-notify setup openclaw http://localhost:3000 my-token +15555550123
claude-notify setup openclaw http://localhost:3000 my-token +15555550123 --channel whatsapp

WhatsApp Setup

  1. Create a Meta Developer account and create an app with WhatsApp
  2. In the WhatsApp section, get your Phone Number ID and generate a permanent access token
  3. Run claude-notify setup whatsapp <PHONE_NUMBER_ID> <ACCESS_TOKEN> <RECIPIENT_PHONE>

The recipient phone number should be in international format without + (e.g. 14155551234).

Telegram Setup

  1. Message @BotFather on Telegram, send /newbot, and follow the prompts to get a bot token
  2. Message @userinfobot to get your chat ID
  3. Run claude-notify setup telegram <BOT_TOKEN> <CHAT_ID>

Hook Configuration

Generated by claude-notify setup (or auto-registered by the plugin), or add manually to ~/.claude/settings.json:

{
  "hooks": {
    "Notification": [{
      "matcher": "permission_prompt|idle_prompt|elicitation_dialog",
      "hooks": [{ "type": "command", "command": "claude-notify", "async": true }]
    }],
    "Stop": [{
      "hooks": [{ "type": "command", "command": "claude-notify", "async": true }]
    }],
    "TaskCompleted": [{
      "hooks": [{ "type": "command", "command": "claude-notify", "async": true }]
    }]
  }
}

All hooks use async: true so they never block Claude Code.

Architecture

Claude Code Event → Hook (async) → claude-notify → Notifier trait → Desktop / Telegram / Slack / Discord / Ntfy / Pushbullet / Teams / Webhook / Email / WhatsApp / OpenClaw

The notification backend is abstracted behind a Notifier trait. Adding new backends requires implementing a single trait:

pub trait Notifier {
    fn send(&self, message: &str) -> Result<(), Box<dyn std::error::Error>>;
    fn name(&self) -> &str;
}

Testing

# Dry run a permission prompt
echo '{"session_id":"abc123","cwd":"/tmp/test","hook_event_name":"Notification","notification_type":"permission_prompt","tool_name":"Bash","tool_input":{"command":"npm install"}}' | claude-notify --dry-run

# Dry run a stop event with last message
echo '{"session_id":"abc123","cwd":"/tmp/test","hook_event_name":"Stop","last_assistant_message":"I fixed the bug in the login handler."}' | claude-notify --dry-run

# Dry run a task completed event
echo '{"session_id":"abc123","cwd":"/tmp/test","hook_event_name":"TaskCompleted","task_subject":"Fix auth bug","teammate_name":"implementer"}' | claude-notify --dry-run

Disclaimer

This project was entirely designed, coded, and documented by AI (Claude, by Anthropic) using Claude Code. A human provided the requirements and direction — all implementation was AI-generated.

License

MIT

About

Get notified when Claude Code needs your attention. A lightweight Rust CLI that hooks into Claude Code events and sends notifications via Desktop, Telegram, Slack, Discord, or ntfy. Switch backends on the fly, mute per-session, and control everything from Claude Code slash commands.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors