Headless Mode & Fan-Out Automation
Running Claude non-interactively in scripts and CI, and fanning one prompt across many files or repos.
Claude as a command-line program
Everything so far assumed an interactive session — you type, Claude responds, you steer. Headless mode removes the human: claude -p "prompt" runs one prompt non-interactively and exits, like any Unix command. That single flag turns Claude into a scriptable building block for CI pipelines (the automated checks that run on every commit), pre-commit hooks, and shell scripts.
Two output flags make the results machine-usable:
--output-format json— one parseable JSON result your script can read fields from--output-format stream-json— line-by-line events as they happen, for long tasks you want to monitor
And because it's a normal command, it composes the Unix way — pipe data in, pipe results out:
# Pipe a log in for analysis
cat error.log | claude -p "Summarize the distinct errors and likeliest root cause"
# Pipe structured results onward to another tool
claude -p "..." --output-format json | your_command
Fan-out: one prompt, hundreds of targets
The pattern that makes headless mode genuinely powerful is fan-out: apply the same prompt independently across many files or repos. Large migrations and codebase-wide analyses stop being weeks of hand-editing and become a loop.
The workflow has a critical safety step — test small before running big:
- Have Claude generate the task list (say, every file importing the old framework).
- Write the loop:
for file in $(cat files.txt); do
claude -p "Migrate $file from React to Vue. Return OK or FAIL." \
--allowedTools "Edit,Bash(git commit *)"
done
- Run it on 2–3 files first. Read the diffs. Refine the prompt where results disappoint.
- Only then run on all 2,000 files.
Each iteration of the loop is an independent headless run with fresh context — file 1,847 gets the same quality of attention as file 1. The "Return OK or FAIL" convention gives your script a parseable success signal: collect the FAIL lines into a retry list, inspect a few to see whether the prompt needs another refinement, and re-run just those.
Why the small trial matters so much: a flawed prompt discovered at file 3 costs you five minutes of rewording. The same flaw discovered after the loop has already rewritten 1,400 files is a cleanup project. The economics of fan-out are all-or-nothing — the prompt is the program, so debug it like one before deploying it.
Scoping what an unattended run can do
An unattended agent must not be able to do everything an interactive one can — nobody is watching to say no. Two mechanisms:
--allowedToolswhitelists exactly which tools the run may use. In the loop above, the agent can edit files and run git commit — nothing else. It cannot push, delete branches, or run arbitrary shell commands.--permission-mode autoadds a classifier — a small model that inspects each action and blocks risky ones (like scope escalation). If actions get repeatedly blocked with no human present to approve them, the run aborts rather than fighting the guardrail.
The rule of thumb: scope an unattended run to the minimum tools the task needs, the same way you'd scope a deploy key rather than handing a cron job your personal credentials.
Real deployments of the pattern
Nightly CI triage. A scheduled job runs:
claude -p "Triage new Sentry issues, label duplicates, and draft a
fix PR for the top crash" \
--allowedTools "Bash(gh *),Read,Grep" \
--output-format json
The JSON output feeds a team dashboard. The tool allowlist means the job can use the GitHub CLI and read code, but can't edit anything directly — drafting a PR through gh is its only write path.
Non-engineering fan-out. Anthropic's growth marketing team built a two-subagent pipeline that takes a CSV of underperforming ads and produces hundreds of compliant new ad variants in minutes — a task that used to consume agency hours. Headless mode isn't a developer-only tool; it's how any repetitive text-shaped workflow gets automated.
When to reach for headless mode
Ask two questions: Does this need my judgment at each step? and Will this run more than once? If the answers are "no" and "yes," it's a headless candidate. Interactive sessions are for work where you steer; headless is for work you've already figured out how to steer — captured in a prompt, scoped by an allowlist, verified by a parseable success signal.