Source: W15 release notes + Anthropic tools-reference + Noah Zweben (PM) tweet + claudefa.st + MindStudio deep-dives (ai-research/claude-code-monitor-tool-2026-05-09.md)
Anthropic shipped the Monitor tool in Claude Code v2.1.98 on April 9 2026 as a built-in background watcher: it spawns a shell command, treats the command’s stdout as an event stream, and wakes Claude with a new transcript message every time the command emits a line. The architectural shift is from time-driven to event-driven — replacing the Bash sleep-loop polling pattern with proper interrupt-driven re-entry.
Key Takeaways
- First-class Claude Code tool, not a Messages API primitive. Lives under
code.claude.com/docs/en/tools-reference#monitor-tool. There is no equivalent in the Anthropic Messages API as of May 2026 — this is a harness feature available only inside Claude Code (CLI / Desktop / web). - Four parameters:
description(label shown on every notification),command(shell script whose stdout is the event stream),timeout_ms(default 5 min, max 1 hr),persistent(runs full session; stop withTaskStop). - stdout = events, silence = nothing to report. Each line of output wakes Claude with a transcript message. While the command is silent, Claude spends zero tokens.
- Pairs with self-pacing
/loop. When you run/loopwithout an interval, Claude either schedules ticks based on the task or reaches for Monitor instead — choosing event-driven over time-driven on its own. - Two stable patterns: stream-and-filter (
tail -f log | grep ERROR,inotifywait, WebSocket emitter) and poll-and-if (cron-style script that emits only on condition change). - Token math is the headline win. Pre-Monitor pattern: a
/loop 30swaiting on a 10-min build burned ~20 polling round-trips of context. Post-Monitor: zero round-trips while the build runs, one transcript message when it finishes or breaks.
How it differs from existing background mechanisms
| Mechanism | Surface | Wakes Claude on output? | Survives session end? | Best for |
|---|---|---|---|---|
| Monitor tool (W15) | Claude Code built-in | Yes — stdout events stream into the conversation | No (session-scoped; persistent: true keeps it alive for the full session) | Live event sources, condition-changed polling, “tell me the moment X happens” |
Bash(run_in_background=true) | Claude Code Bash tool flag | No — output is buffered; Claude must poll with BashOutput to read it | No | Async commands where you’ll come back to read output later |
/loop <interval> <prompt> | Claude Code slash command | No — re-runs prompt at intervals (re-issues the same prompt + tools) | No (session-scoped) | “Re-check this every N minutes while I work” |
| Routines / Scheduled Tasks | Anthropic platform primitive | Independent agent run, not a wake event | Yes (cron-driven, persists across sessions) | Recurring time-based jobs, daily digests, weekly sweeps |
cron / launchd / GitHub Actions | Operating system / CI | No — no Claude session to wake | Yes | Time-based jobs that run without an active Claude session |
The decision tree:
- “I need Claude to react the moment X happens during this session” → Monitor
- “I need to fire a command in the background and come read the output later” →
Bash(run_in_background=true)+BashOutputpoll - “I need to retry/check a thing every N minutes for the rest of this session” →
/loop(which may itself reach for Monitor) - “I need a thing to happen on a schedule even when Claude isn’t running” → Routines or Scheduled Tasks / cron / GitHub Actions
Where Monitor replaces polling — concrete patterns
Tail-and-filter (stream-and-filter pattern):
# Watch application logs for errors
tail -f /var/log/app.log | grep --line-buffered "ERROR"
# Watch file system changes
inotifywait -m --format '%e %f' /watched/dirPoll-and-if (the only legitimate sleep-loop pattern remaining — emit on change, not on schedule):
# Poll GitHub PR for new comments every 30 seconds
last=$(date -u +%Y-%m-%dT%H:%M:%SZ)
while true; do
now=$(date -u +%Y-%m-%dT%H:%M:%SZ)
gh api "repos/owner/repo/issues/123/comments?since=$last" \
--jq '.[] | "\(.user.login): \(.body)"'
last=$now; sleep 30
doneConditional readiness signals (per MindStudio’s deep-dive):
“Start the dev server in the background. Monitor for the ‘ready’ message, then let me know when it’s accepting connections. Also alert me if it crashes.”
Timeout safety valves:
“Run the integration tests in the background. Monitor for completion. If they haven’t finished in 10 minutes, interrupt and report current status.”
Origin announcement (Noah Zweben, Claude Code PM)
“Claude can now follow logs for errors, poll PRs via script, and more. Big token saver and great way to move away from polling in the agent loop.” — @noahzweben, April 9 2026
Workflows where Monitor would replace polling
Three concrete patterns from this stack where Monitor cleanly replaces an existing sleep loop:
- Hermes self-improving loop — currently uses
/loop 5mto check whether the latest training run produced a new model. Monitor ontail -f hermes/runs/*/results.jsonl | grep --line-buffered '"completed":true'would wake the agent the millisecond a run finishes instead of burning a poll every 5 minutes. - GSC SEO Autonomous engine — currently polls Search Console for click-deltas every cron tick. The poll-and-if pattern (emit only when a tracked keyword crosses a threshold) directly maps to Monitor.
- Weekly wiki sweeps — already cron-scheduled (Friday + Sunday cloud routines). Monitor isn’t a fit here — sweeps run without an active Claude session, so Routines is the right primitive.
Implementation
Tool/Service: Claude Code built-in tool (since v2.1.98) Setup: No setup. Ship Claude Code v2.1.98+ and Claude can invoke the Monitor tool inline. Phrase prompts as “tell me the moment X” or “watch Y in the background” rather than “run X” so Claude reaches for Monitor instead of synchronous Bash. Cost: No incremental cost — token spend goes to zero while the watcher is silent. The cost win is everything you were spending on polling round-trips before. Integration notes:
- The Monitor tool’s
commandparameter accepts any shell script. Pipe throughgrep --line-buffered(or equivalent) so per-line filtering doesn’t block on stdio buffering. - Default
timeout_msis 5 minutes. Long-running watchers (full test suite, training run, all-day CI) need an explicit larger value orpersistent: true. persistent: truerequiresTaskStopto terminate. Worth the trade-off for “watch for the rest of this session” patterns; risky for misbehaving commands that may produce runaway output.- Stop/start discipline. A persistent monitor that emits a torrent of lines (e.g., a debug log on a hot path) will flood the conversation. Filter aggressively at the shell layer, not at the Claude layer.
Open Questions
- Messages API parity. Will Monitor (or an equivalent event-driven primitive) ship in the Messages API for non-Claude-Code agent harnesses? Currently it is Claude Code-only.
- Multiple concurrent monitors. The W15 docs are silent on the upper bound. Anecdotally, Anthropic’s example flow uses one or two; behavior with 10+ persistent monitors fanning lines into the same conversation is undocumented.
- Output buffering edge cases.
tail -f | grepworks because of--line-buffered; some commands buffer their own stdout block-wise (Python without-u, Node withoutprocess.stdout.uncork()). Monitor docs don’t enumerate the buffering pitfalls. - Token cost of high-frequency events. A monitor emitting 100 events per minute is essentially polling, just inverted. Where is the break-even?
- Interaction with Routines. If a Routine spawns a Claude session that then opens a Monitor, who owns lifecycle? Routine-level vs session-level termination semantics not specified.
Try It
- Replace your noisiest
/loop. Find the/loop 30s …you most regret. Rewrite as a Monitor invocation: “Watch dist/build.log for ‘compiled successfully’ and tell me when it lands. Alert me if ‘ERROR’ appears.” - Babysit a PR with one prompt.
> Tail the CI for PR #123 in the background. Tell me when checks turn green or red.Read the output ofgh pr checks --watchis a good underlying command if you want to peek at the shape Claude generates. - Wire dev-server crash detection.
> Start the dev server in the background. Monitor for the 'ready' line, then let me know when it accepts connections. Alert me if it exits unexpectedly.This pattern is the W15 docs’ demo example. - Compare token spend. Pre-Monitor, run a 10-minute task with
/loop 30s status. Post-Monitor, run the same task with a Monitor invocation./cost(W15 also shipped a per-model + cache-hit breakdown) tells you which approach won. - Replace one Hermes/GSC poll. Identify one polling cron in the broader stack and rewrite as Monitor. Document token delta in the relevant runbook.
Related
- Week 15 (April 6-10) Release Digest — original changelog entry; this article is the deep-dive.
- Claude Code CLI Reference — Bash tool, run_in_background flag, BashOutput.
- Scheduled Tasks — pairs with Monitor + self-pacing
/loopfor the time-driven half of background work. - Claude Code Routines — cron-style harness primitive for jobs that run without an active Claude session.
- Claude Code Hooks — different async surface; hooks fire on Claude Code lifecycle events, Monitor fires on external command output.
- Agent Skills Overview — Monitor is built-in, not a skill, but the “model-invoked tool” pattern is shared with skills.
- Claude Managed Agents — server-side runtime where the absence of a Monitor-equivalent shapes harness design.
- Cost & Intelligence Levers — Monitor is the cleanest cost lever to land in 2026 — it directly removes polling round-trips from the spend curve.