magus v0.4.2 is out. See what's new
¶ View markdown source · ✎ Suggest an edit
2 min read

Attention hooks

An agent blocked on a permission prompt, or one that finished twenty minutes ago, is only useful if you find out. magus session notify normalizes one host event and, with --desktop, posts a desktop notification.

It does not publish an event to the daemon or Console. Use it to bring a person back to the host where the agent needs an answer.

printf '%s\n' "needs your approval" | magus session notify --outcome Notification --desktop
printf '%s\n' "finished" | magus session notify --outcome Stop -o json

Why this is not an MCP tool

An MCP server only ever observes tool calls. A blocked agent makes no call at all - the blockage IS the silence, and silence is precisely what MCP has no way to report. The host's own hook system is the only surface that fires on it. So this is a hook sink rather than a tool, and it stays one whether or not the daemon is up.

The envelope

--outcome takes whatever the host calls its event. It is classified by substring, case-insensitively, into canonical outcomes: waiting, permission, failed, finished, diagnostic, update. Anything unrecognized becomes other and still notifies, because a missed alert is the failure this exists to prevent.

When a host hands you JSON, shape it into the canonical envelope before piping it in. The command deliberately does not know host field names:

jq -c '{schema_version: 1, outcome: .hook_event_name, source: {kind: "agent"}, message: .message}' \
  | magus session notify --desktop

Wiring it per host

The event names below are the ones each host documents. Check yours against its current documentation, because these move; the magus side never changes.

host event(s) to wire
Claude Code Notification, Stop, SubagentStop
Codex its hook or notify program setting
OpenCode its plugin surface
Cursor its agent hook surface
any other host any event that means "a human is needed"

Claude Code's Notification fires both on a permission prompt and on idle waiting for input; its event JSON carries hook_event_name, message and session_id. Its page has the config.

Fail quietly, on purpose

A notifier hook should exit 0 and swallow its own output. A notifier that can fail is a hook that can break the session it was meant to watch - the same reasoning as the guard's fail-open contract.

Resolve the binary the way the guard does: prefer a repo-local ./magus, then PATH, and do nothing if neither exists. Do not fall back to a fixed path like /tmp/magus; a stale binary there runs happily and enforces months-old rules while looking perfectly healthy. magus doctor's guard binary check reports which binary a hook would actually run and fails when it is older than your working tree.

agentsnotifyhooksnotificationsdesktop
Last updated (d120b58e)
Earlier changes on this page (2)

Full history ↗ · Blame source ↗

Glossary

Op

A single tool-native command a target composes (long form: operation); the middle of the work hierarchy (Spell to Op to Target). See operations.

Daemon

The background magus host that owns shared state such as services and the warm knowledge graph. See daemon.

CI

An ordinary magusfile-defined target you compose yourself with magus\needs - magus does not hardcode its stages. Magus.RunCI treats it specially only in that it strips the rw charm, it is the anchor magus affected ci keys off, and a selected scope with no project declaring it is a load error rather than a silent no-op. See targets.

Health

The at-a-glance daemon state derived from the pool: healthy when the pool is reporting, degraded when it reports an error, down when there is no pool. The dashboard color-codes each state. See daemon.

Session

One magus process's recorded facts - the targets it finished, their outcomes, and the lease it acted as - kept in a repo-scoped store every worktree shares. magus session lists them; the store prunes itself by last-fact age.

Conventions

This page uses none of the site's convention markers. The full set is on the conventions page.