[ ABOYEUR · v0.1.1 ]

Privacy-first push notifications for AI coding agents. Built into Brigade.

Agent Notify is built into Brigade: privacy-first push from coding agents to Discord, Telegram, and Signal. brigade setup installs the binary from the release manifest. Zero telemetry. Brigade can plan messages; send is always opt-in.

View on GitHub →

Part of the Brigade fleet · brigade.tools · escoffierlabs.dev

Agent Notify GitHub stars Agent Notify GitHub stars

[ 01 · DISPATCH ]

Agent emits an event: Claude Code Stop and Notification hooks via --hook claude-code-*, the Codex CLI notify line via --hook codex-notify, OpenClaw or Hermes session-end hooks piping canonical JSON on stdin, a shell wrapper with jq and --hook custom for anything else, or a direct one-line message argument.
Resolve and format: Channels are resolved, the message is formatted per channel, and outbound HTTP goes only to the URLs you configured.
Channels you configured: Env vars for the quick path, or a config.toml with named channels and profiles once you outgrow env-only. Secrets are referenced by env-var name, never written to the file. doctor and status validate the wiring without sending.

[ 02 · GUARANTEES ]

Zero telemetry, by design

No telemetry endpoints, ever. No update checks at startup or runtime. Outbound HTTP goes only to the channel URLs you configured, and nowhere else.

No persistent state

No state file, no log file, no cache. Each run reads your config and env, sends, and exits. A privacy test in the repo asserts these properties hold.

Secrets stay in env vars

The config references env-var names, not literal tokens. Bot tokens, webhook URLs, and Signal credentials never live in the config file on disk.

Single Go binary

One static binary you build and drop in ~/bin or /usr/local/bin. No runtime, no daemon, and no extra notification relay standing between your machine and the channel API.

[ 03 · CHANNELS ]

Set env vars for the channels you want and send. A message with multiple channels configured fans out to all of them. Each channel formats the canonical message in its native style.

Discord

Setup: set DISCORD_WEBHOOK_URL to a channel webhook. Format: embed with title and body, color by level, tags as inline fields, source as footer.

Telegram

Setup: set TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID for the Bot API. Format: Markdown V2 with a level emoji prefix, bold title, and tags as an italicized footer.

Signal

Setup: set SIGNAL_CLI_URL, SIGNAL_FROM, and SIGNAL_TO for a self-hosted Signal CLI. Format: plain text with a level emoji prefix, title on its own line, and a [tag] footer.

[ 04 · TRY IT IN 60 SECONDS ]

Verify the wiring before you trust it, with no live send.

$ agent-notify doctor
[OK  ] config: loaded
[OK  ] routing: 2 channel(s) selected
[OK  ] channel:discord-main: env present
[WARN] channel:signal-personal: inactive channel: url/from/to env missing or empty
[OK  ] channel:telegram-personal: env present
doctor checks config and channel env vars without sending anything.
$ agent-notify status
configured: true
config:     ~/.config/agent-notify/config.toml
profile:    agent-stop
channels:   [telegram-personal discord-main]
status prints the resolved routing for the active profile.

Add --json to either command for machine-readable output you can pipe into a script.

[ 05 · PRIVACY ]

If you set DISABLE_TELEMETRY=1 to stop a harness from phoning home, you also lose its built-in mobile push, because that feature routes through the same telemetry plumbing. agent-notify gives you the same UX with no extra notification relay or telemetry between your machine and the channel API.

No telemetry endpoints, ever. No update checks at startup or runtime. No persistent state: no state file, log file, or cache. Outbound HTTP only to the channel URLs you configured. A repo test asserts the above properties hold.

The v1 release is deliberately small: no retry queue, no templating, and three channels. A rate-limited or down channel means a dropped notification, and the canonical message goes through as-is. The boundaries are documented, not hidden.

[ 06 · WHY NOT SOMETHING ELSE ]

Why not the harness's built-in mobile push?

It rides the same telemetry channel you disabled with DISABLE_TELEMETRY=1. Turning off the data exhaust turns off the notifications too. agent-notify decouples the two: notifications stay, telemetry stays off.

Why not ntfy, Pushover, or a hosted push SaaS?

Those route your messages through a third party server and, for the SaaS options, an account you have to trust. agent-notify talks only to the channel APIs you already control: your own Discord webhook, your own Telegram bot, your own Signal CLI host.

Why not a hand-rolled curl in your hook?

You can, for one channel. The moment you want two channels, level-based formatting, named routing profiles, and a --skip for a noisy channel, you are rebuilding this. agent-notify is that wrapper, with a doctor to tell you when the wiring is wrong.

Why not a webhook relay like Apprise?

Apprise is excellent and supports far more services. agent-notify is deliberately narrow: three channels, zero runtime dependencies, one static Go binary, and first-class hook adapters for coding agents. If you need dozens of notification targets, use Apprise.

[ 07 · WHAT IT IS NOT ]

Not a hosted service

There is no server to sign up for, no API key from Escoffier Labs, no dashboard. It is a binary you run.

Not a message queue

There is no retry queue. A rate-limited or down channel means a dropped notification (exit code 3), not a redelivery later.

Not a templating engine

The canonical message goes through as-is. Level, title, body, tags, and source are the whole model.

Not a general-purpose alerting platform

It does not poll, schedule, or evaluate conditions. Something else decides when to notify; agent-notify only delivers.

[ 08 · COMMANDS ]

agent-notify "build finished" Send a message. The bare form is shorthand for the send subcommand.
agent-notify send "..." Explicit send. Fans out to the resolved channels for this run.
agent-notify init Generate a starter config file at ~/.config/agent-notify/config.toml.
agent-notify status --json Report configured channels and profiles without sending anything.
agent-notify doctor Validate channel and profile wiring before you trust it. --json for scripts.
agent-notify hooks print claude-code Print a ready-to-paste hook snippet for Claude Code settings.
agent-notify hooks print codex Print the notify line for the Codex CLI config.toml.
agent-notify version Print version, commit, build date, Go version, and platform.

[ 09 · INSTALL ]

Agent Notify ships inside brigade-cli. No separate install:

Attach via Brigade: brigade add notifications

Brigade itself: brigade.tools · pipx install brigade-cli