Claude Code headless mode (-p): scripts, CI and cost caps

Claude Code headless mode is claude -p: one prompt in, one answer out, no terminal UI. The flags that cap spend and tools, output formats, and CI.

Contents

Short answer: Claude Code headless mode is claude -p "your prompt". It runs one task without the interactive interface, prints the result and exits with a status code your script can check. Cap it with --max-budget-usd and --max-turns, limit its tools with --allowedTools or --tools, and add --output-format json when a program reads the answer.

Everything below was read in Anthropic's headless docs and CLI reference on 22 October 2026. Flags change between versions, so check claude --version against the docs if one is refused.

What headless mode is#

The -p flag (long form --print) is Claude Code's non-interactive mode. Anthropic's docs file it under the Agent SDK: "a CLI for scripts and CI/CD", next to the Python and TypeScript packages. The agent loop, tools and context handling are the same as in an interactive session. The difference is that nobody is there to answer questions.

bash
claude -p "What does the auth module do?"

It reads stdin, so it fits in a pipe:

bash
cat build-error.txt | claude -p "explain the root cause of this build error" > output.txt

Three behaviours matter for scripts:

  • Exit codes. It exits 0 on success and non-zero when the run fails. A bad flag prints to stderr before anything starts; a failure inside the run, such as missing sign-in, is printed as the result on stdout.
  • Piped input is capped at 10MB. For anything bigger, write it to a file and name the path in the prompt.
  • It loads your setup unless you say otherwise. Without --bare, claude -p loads hooks, skills, plugins, MCP servers, auto memory and CLAUDE.md from the folder and from ~/.claude, as an interactive session would, and it shows no trust dialog.

The flags that cap spend and tools#

claude -p in the centre, joined to four boxes: tools (--allowedTools, --tools), permissions (--permission-mode dontAsk), turns (--max-turns 5) and a budget cap in amber (--max-budget-usd 5.00). The edges you set on a claude -p run From Anthropic's CLI reference, October 2026. claude -p Tools --allowedTools --tools Permissions --permission-mode dontAsk Turns --max-turns 5 Budget (estimate) --max-budget-usd 5.00

A headless run has no one to press Escape. These flags are how you put the edges in yourself.

Flag What it does
--max-budget-usd 5.00 Stops the run once estimated API spend reaches the amount. Subagents count toward it
--max-turns 3 Stops after that many agentic turns, with an error. No limit by default
--allowedTools "Read,Edit,Bash(git diff *)" Tools that run without asking. Uses permission-rule syntax
--tools "Bash,Edit,Read" Restricts which built-in tools exist at all; "" turns them all off
--disallowedTools "mcp__*" Deny rules; a bare name removes the tool
--permission-mode dontAsk Denies every call that would otherwise prompt. Also acceptEdits, auto, plan
--permission-prompts none For unattended runs: anything that would prompt is denied and Claude is told not to retry
--bare Skips hooks, skills, plugins, MCP servers, memory and CLAUDE.md for a repeatable start
--model sonnet / --effort low The model and effort level for this run

Two details are easy to miss.

The budget is an estimate. Anthropic says --max-budget-usd is checked against Claude Code's client-side cost estimate, which can differ from your bill, and that "spend can pass the cap, so leave headroom". On a Pro or Max sign-in that dollar figure isn't a bill at all: the run draws on your plan's 5-hour and weekly limits, and the cap is still a useful brake on how much of them one script can use.

Approvals default to no. With v2.1.302 or later, a claude -p run with nothing setting a mode starts in Manual mode, where a call that needs approval is denied unless something approves it. So a script that "does nothing" is often a script whose tools were never allowed. List them with --allowedTools (our guide to Claude Code permission rules covers the syntax); the trailing * in Bash(git diff *) matches any command that starts with git diff.

Output formats#

--output-format takes three values:

  • text (default): plain text, for people and for > file.txt.
  • json: one object with result, session_id, usage and total_cost_usd with a per-model breakdown.
  • stream-json: one JSON event per line as the run goes. Add --verbose, and --include-partial-messages for token-by-token text.

For a fixed shape, add a JSON Schema:

bash
claude -p "Extract the main function names from auth.py" \
  --output-format json \
  --json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
  | jq '.structured_output'

If Claude declines or the run fails, there is no structured_output field, so check for it before you use it.

To continue a run later, keep the session ID:

bash
id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$id"

A plain claude --continue skips sessions started with -p, so the ID is how you get back to them. claude -p --continue does include them.

Running it in CI#

The plain way is a CI step that installs Claude Code and runs claude --bare -p … with an API key in a secret. Anthropic recommends --bare for scripted calls and says it will become the default for -p. In bare mode Claude Code never reads your subscription sign-in or the keychain, so set ANTHROPIC_API_KEY.

On GitHub there is an official action, anthropics/claude-code-action@v1. Run /install-github-app inside Claude Code for a guided setup, or add the workflow by hand. It works two ways:

  • Interactive: with no prompt input, it answers @claude mentions in issues and pull requests.
  • Automation: with a prompt, it runs on any GitHub event, including a cron schedule.

It authenticates with ANTHROPIC_API_KEY, or with CLAUDE_CODE_OAUTH_TOKEN from claude setup-token, which uses your Claude subscription. CLI flags go through claude_args:

yaml
claude_args: "--max-turns 5 --model claude-sonnet-5"

Anthropic's cost advice for the action is short: runs use GitHub Actions minutes and model tokens, so set --max-turns, a workflow timeout and GitHub's concurrency controls. A team-wide secret should be an API key rather than one person's subscription token.

Where headless runs spend more than you expect#

  • Your whole setup loads. Without --bare, every MCP server and a long CLAUDE.md go into each run's context. Anthropic's cost docs say MCP tool definitions are deferred by default, but CLI tools like gh still use less context.
  • Background work keeps the run open. After its turn, claude -p waits for background commands and subagents it started, and by default stops idle background work after 10 minutes. A dev server started in a script can keep the run alive.
  • Continued runs report the total. With --continue or --resume, total_cost_usd is the whole conversation's estimate, earlier runs included. Earlier spend doesn't count toward a new --max-budget-usd.

For whether an API key or a subscription suits scripted work, see API key or subscription for Claude Code.

When you want a trigger, not a script#

Headless mode is a building block. You still need something to start it: cron, CI, a webhook handler. Anthropic's own cloud option is Claude Code's cloud scheduled tasks (formerly Routines).

If a script is all you need, claude -p with a budget and a turn cap is enough. Shuriken is for the runs you want to watch and answer rather than parse. It runs Claude Code, Codex and the other agents as chats on your own computers, and on a server it runs with no screen: add the machine under Settings › Devices › Add device › A server and run the one command the app gives you. Shuriken then runs there as a service that restarts on its own, and you follow its chats from the app or your phone. To try it, download Shuriken.

Sources

  1. Claude Code docs: Run Claude Code programmatically (accessed 22 October 2026)
  2. Claude Code docs: CLI reference (accessed 22 October 2026)
  3. Claude Code docs: GitHub Actions (accessed 22 October 2026)
  4. Claude Code docs: Manage costs effectively (accessed 22 October 2026)

Frequently asked questions

What is Claude Code headless mode?

It is Claude Code run with -p (or --print): it takes one prompt, works through it without the interactive interface, prints the result and exits. Anthropic's docs describe it as using the Agent SDK from the CLI.

How do I stop a claude -p run from spending too much?

Pass --max-budget-usd with a dollar amount and --max-turns with a number. The budget is checked against Claude Code's own cost estimate, and Anthropic says spend can pass the cap, so leave headroom.

Does claude -p use my Pro or Max subscription?

It can. A plain claude -p run uses the sign-in Claude Code already has. With --bare it never reads your subscription sign-in, so you need ANTHROPIC_API_KEY or an apiKeyHelper.

How do I get JSON out of claude -p?

Add --output-format json. The answer is in the result field, next to session_id, usage and total_cost_usd. Add --json-schema to get a structured_output field that matches your schema.

Can I run Claude Code in GitHub Actions?

Yes, with Anthropic's official action, anthropics/claude-code-action@v1. It authenticates with an API key or a subscription token from claude setup-token, and takes CLI flags such as --max-turns through claude_args.

Free tools