Founder pricing: Pro at $9.99/mo forever for the first 50 members. 18 of 50 left Claim yours →
All posts

Claude Code headless mode: turn the agent into a shell command

The SanuDesk team 6 min read
Claude Code headless automation

The build fails, and you perform the ritual: copy the log, open a session, paste it, type "what broke?", read the answer, close the tab. Somewhere around the fortieth repetition it lands: you are the pipe. Two programs are talking through your clipboard, and one of them is a text-processing tool pretending it needs a meeting with you.

Claude Code has a flag for this. Add -p and the agent stops being a chat you attend and becomes a shell command that runs once, prints its result, and exits. That one change moves it into a category your tooling already understands: pipeable, schedulable, callable from any script you own.

What Claude Code headless mode actually is

claude -p "your task" runs the full agent, tools and all, with no interface attached. It reads stdin, so cat build-error.txt | claude -p "explain the root cause" does what you hope, and it writes stdout, so > and | behave. The official docs call this running Claude Code programmatically, which is the right frame: the agent as a function.

The key property: headless mode makes the agent composable. An interactive session bolts the model to your attention; a headless run bolts it to your toolchain. git log can feed it, jq can parse it, cron can trigger it, CI can gate on it.

A few flags do the plumbing:

  • --output-format json returns the result plus metadata, including what the run cost.
  • --json-schema forces output into a shape you define, which turns "please answer in JSON" from a hope into a contract.
  • --allowedTools and --permission-mode decide up front what the run may do; nobody is at the keyboard to approve.
  • --bare skips your local hooks, skills and instruction files, so the command behaves the same on every machine.

The idea is not exclusive to one vendor: Codex has codex exec, and Gemini CLI takes a prompt flag the same way.

Three places a scripted agent earns its keep

In a pipe. One-shot transforms with a clear input: a failing build log into a root cause, a week of git log into release notes, flaky test output into a ranked list of suspects. If the job is "turn this text into that text," it never needed a conversation.

In your repo's scripts. A package.json script or Makefile target that pipes git diff main through a picky reviewer prompt gives every developer the same check with zero setup. This is the mirror image of Claude Code hooks: hooks put your shell commands inside the agent's loop, headless mode puts the agent inside your shell scripts. How to brief that reviewer is a craft of its own: make an agent your first reviewer covers it.

In CI. A pipeline step that reviews the diff, labels the PR, or drafts the changelog entry, with JSON output feeding jq so the next step can act. Anthropic's own best practices guide describes teams fanning headless runs across issue triage and large migrations exactly this way.

When a script beats a session

The dividing line: if you can write the whole ask down before the run starts, and something other than you can judge the result, script it. If the ask will change the moment you see the first attempt, keep it interactive.

Scripts win when the task repeats on a trigger (every push, every night, every new issue), when another program consumes the output, and when one prompt runs across many inputs. A loop over thirty files with one instruction is a script; nobody should type it thirty times.

Sessions win for anything exploratory: debugging an unknown, shaping an API, any work you would steer after seeing the first attempt. A headless run cannot be steered, only re-briefed and re-run from zero.

Where headless runs go wrong

The honest section, because unattended one-shots fail in their own ways:

  • The permission flag becomes a bypass valve. A headless run cannot ask, so the first friction tempts people toward blanket skip-everything flags. In CI, that hands an agent your repo and network on the say-so of whatever text landed in its prompt. Grant narrow rules instead, like --allowedTools "Bash(git diff *)", and treat guardrails as part of the script, not an obstacle to it.
  • Pipelines assume functions; models are not functions. The same input can produce a differently worded output tomorrow. A schema pins the shape, not the judgment. Keep each run small, and let tests decide whether the result ships.
  • Green output stops being read. The nightly review job nobody opens is quietly rotting. The habits from reviewing agent work apply to automated output most of all: sample it on a schedule.
  • Cost multiplies by cron. A cheap run, multiplied by every push and every repo, is a real line item. The JSON output reports each run's cost; logging it ends the mystery.
  • Your laptop leaks into the script. Without --bare, a headless run picks up your local instruction files, hooks and MCP servers, so the same script can behave differently on a teammate's machine. Reproducible runs declare their context explicitly.

Scripts for the verbs, a desk for the judgment

Headless mode is the right tool when the result is machine-checkable. But a lot of recurring agent work does not end in an exit code; it ends in a diff a human has to look at. A cron entry cannot look at anything, and a folder of last night's output is nobody's favorite review queue.

That review layer is what SanuDesk is built for. It is a desktop app that tiles your Claude Code, Codex and Gemini sessions into one grid, next to a Kanban board that does the dispatching: write the task as a card, deploy it to a fresh session with one click, and when the agent stops, the card parks itself in a review lane with a note on what changed and how to test it. The recurring chores that outgrow a one-shot pipe become Loops: the same brief fired on a schedule, every run journaled, with your real environment available, so the job that needs your database just works. It is bring-your-own-model, driving the agent subscriptions you already pay for, and the grid and board are in the free plan (details on pricing).

The split is clean: pipe the transforms, schedule the chores into a review lane, and keep a live session for the work that needs steering.

Pipe one real thing through it today

The experiment is one line, run in a repo with changes on a branch:

git diff main | claude -p "You are a picky reviewer. For each real problem \
in this diff, print file:line and a one-line issue. If it is clean, print \
CLEAN and nothing else."

If it prints CLEAN, good news. If it catches something, you just built a reviewer that costs one line and runs anywhere your shell does. Promote it to a repo script so the whole team gets it, and the next time you catch yourself pasting output into a chat window, notice the moment: that is a pipe asking to exist.

Download SanuDesk free to give the work that needs human eyes a grid and a review lane, or see how the board, grid and Loops fit together on the features page.

Run your own fleet of agents

SanuDesk is a free desktop app that tiles your Claude Code and Codex sessions and gives every project a Kanban board your agents work from.