Guide

Claude Code headless mode: claude -p, flags, login on a server, and CI

One flag turns Claude Code into a command you can script: run a task, get the result, exit. The flags, the permissions, and how to sign in on a machine with no browser.

Claude Code's headless mode is claude -p "your prompt": it runs one task without the interactive screen, prints the result and exits, so you can use it in scripts, CI pipelines and git hooks. Anthropic now documents it as "Run Claude Code programmatically," the command-line form of the Agent SDK. Add --output-format json for a result with the session ID and cost, --permission-mode dontAsk plus --allowedTools to control what it may do, and --bare for the same behavior on every machine. On a server, sign in with claude setup-token (a one-year token for any paid plan) or an API key. One thing to know first: a -p run shows no trust dialog, so a repository's own hooks and MCP servers run without asking.

Key takeaways

  • Run it: claude -p "prompt", or pipe input in: cat error.log | claude -p "explain this" (Anthropic).
  • Output: text, json (result, session ID, turns, cost) or stream-json; --json-schema for validated structured output.
  • Permissions: anything that would need approval is denied, and the run continues; use dontAsk with an allowlist in CI.
  • Login: claude setup-token for a plan, or ANTHROPIC_API_KEY, which -p always uses when it's set.
  • Safety: no trust dialog in -p, so use --bare on repositories you don't trust.
Flags from Anthropic's CLI reference, October 8, 2026. Print-mode-only flags work with -p.
FlagWhat it does
-p, --printRun one task without the interactive screen, then exit
--output-formattext, json or stream-json
--json-schemaReturn validated JSON matching your schema
--allowedTools / --disallowedToolsTools that run without asking, or never
--permission-modedefault, acceptEdits, plan, auto, dontAsk or bypassPermissions
--bareSkip hooks, skills, plugins, MCP servers, memory and CLAUDE.md
--max-turns / --max-budget-usdStop after N turns or an estimated dollar amount
--continue / --resumePick up the latest or a named conversation
--append-system-promptAdd instructions to the system prompt
--model / --fallback-modelChoose the model, and backups if it's unavailable
--mcp-configLoad MCP servers from a JSON file
--no-session-persistenceDon't save the session to disk

How do you run Claude Code in headless mode?

Pass -p (or --print) with your prompt (Anthropic):

claude -p "Find and fix the bug in auth.py" --allowedTools "Read,Edit,Bash"
cat build-error.txt | claude -p "Explain the root cause of this build error"
gh pr diff 42 | claude -p "Review this diff for security problems"

Claude Code "exits with code 0 on success and a non-zero code when the run fails," so scripts can branch on it. Piped input is capped at 10MB; for anything bigger, write a file and name it in the prompt. --continue picks up the latest conversation in the folder, and --resume <id> a specific one.

What output formats does claude -p support?

  • text (the default): just the answer.
  • json: one object with result, session_id, num_turns, duration_ms, is_error, total_cost_usd, token usage and any permission_denials.
  • stream-json: one JSON line per event as it happens, for live progress.

With --output-format json --json-schema '<schema>', the answer comes back in structured_output, validated against your JSON Schema, and an invalid schema fails before the run starts.

What happens when Claude needs permission with nobody there?

In a -p run with no one to answer, requests that would prompt "are denied," Claude is told nobody can approve them, and the run continues (Anthropic). So decide up front what it may do:

  • --allowedTools: tools and commands that run without asking, such as "Bash(npm test)" "Read".
  • --permission-mode dontAsk: "Locked-down CI and scripts": reads and allowlisted tools run, everything else is denied (Anthropic).
  • --permission-mode acceptEdits: file edits and common file commands run without asking.
  • --permission-mode auto: a classifier reviews each action instead of you.
  • bypassPermissions (or --dangerously-skip-permissions): everything runs. Anthropic's guidance is "Isolated containers and VMs only."

Is headless mode safe?

Mostly, if you treat the repository as code that will run. Anthropic's warning: "Without --bare, a -p session runs the hooks in a project's .claude/settings.json and connects the servers in its .mcp.json, even in a folder you've never trusted." A cloned repository can therefore run its own commands in your CI job. --bare skips hooks, skills, plugins, MCP servers, memory and CLAUDE.md, and Anthropic calls it "the recommended mode for scripted and SDK calls," set to become the default for -p. Bare mode doesn't read your subscription login, so it needs ANTHROPIC_API_KEY (Is Claude Code safe?).

How do you log in to Claude Code on a headless server?

(Anthropic)

  • A plan token: run claude setup-token on any machine where you can sign in. It prints a one-year token that "requires a Pro, Max, Team, or Enterprise plan"; set it as CLAUDE_CODE_OAUTH_TOKEN on the server. It can make model requests only, not Remote Control.
  • An API key: set ANTHROPIC_API_KEY from the Claude Console. "In non-interactive mode (-p), the key is always used when present."
  • A cloud provider: Amazon Bedrock, Google Cloud or Microsoft Foundry through their environment variables.
  • Interactive login without a browser (SSH, WSL, containers): run claude, press c to copy the login URL, open it on another device, and paste the code back.

claude auth status exits with 1 when you're not logged in, which makes a quick check in scripts.

Can you use a Claude subscription in headless mode?

For your own scripts, yes: signed in with your plan, -p runs count against your plan's five-hour and weekly limits (Claude Code usage limits). Anthropic's terms say Pro and Max limits "assume ordinary, individual usage of Claude Code and the Agent SDK," and products you build for other people should use an API key rather than your login (Claude Agent SDK).

The monthly API credits that Max and Team plans get from October 2026 cover claude -p "when you run them yourself with an API key from your linked Claude Console organization"; signed in with your plan instead, the same runs "still draw from your plan's usage limits." Runs started by the Claude Code GitHub Action don't use the credits at all (Anthropic).

How much does a headless run cost?

The same as interactive use: plan limits or API rates. The JSON output's total_cost_usd is a client-side estimate, "not authoritative billing data," and --max-budget-usd 5 stops a run once that estimate reaches $5. --max-turns caps the number of agent turns. Anthropic's token-saving advice applies here too.

Headless examples

  • In CI: claude -p "run the test suite and fix failures" --permission-mode dontAsk --allowedTools "Bash(npm test)" "Read" "Edit".
  • On every file: a shell loop, for file in $(cat files.txt); do claude -p "Migrate $file from Python 2 to Python 3" ...; done, from Anthropic's best practices.
  • As a linter: an npm script that pipes git diff into claude -p with a review prompt.
  • On GitHub: the official anthropics/claude-code-action@v1 runs Claude on pull requests and issues (Claude Code GitHub Actions).
  • In a container: Anthropic's reference dev container adds a firewall, though with permissions skipped, dev containers "do not prevent a malicious project from exfiltrating anything accessible inside the container," Claude's credentials included.

Does Claude Code have a headless browser?

Not built in. Claude in Chrome, Anthropic's browser extension, drives your real Chrome, and "Browser actions run in a visible Chrome window in real time"; it also needs a plan login, not an API key or setup token (Anthropic). For a headless browser in CI, people add a browser-automation MCP server (Claude Code MCP).

What is the Codex equivalent?

codex exec "task". "By default, codex exec runs in a read-only sandbox"; allow edits with --sandbox workspace-write. --json streams JSON Lines events, -o writes the final message to a file, and CODEX_API_KEY signs in for automation (OpenAI, how to use Codex).

How has headless mode changed?

  • September 29, 2025 (v2.0.0): the Claude Code SDK became the Claude Agent SDK.
  • October 2025: --max-budget-usd added.
  • March 2026 (v2.1.81): --bare added.
  • September 2026: --permission-prompts none for unattended runs, and auto mode in -p.
  • October 7, 2026: monthly API credits for Max and Team.

From Anthropic's changelog (GitHub).

When the work needs people, not a script

Headless mode is for runs nobody watches. Poly (usepoly.co) is for the opposite: a team works with one Claude Code or Codex agent in a shared browser room, everyone sees each step live, and any member can approve a change before it happens. Free to start. What is Poly?

Common questions

What is Claude Code headless mode?

Running Claude Code non-interactively with claude -p "prompt": it does one task, prints the result and exits. Anthropic documents it as running Claude Code programmatically, the command-line form of the Agent SDK, for scripts and CI.

How do I log in to Claude Code on a headless server?

Run claude setup-token on a machine with a browser to get a one-year token for a Pro, Max, Team or Enterprise plan, and set it as CLAUDE_CODE_OAUTH_TOKEN on the server. Or set ANTHROPIC_API_KEY, which -p always uses when present.

Can I use my Claude subscription with claude -p?

Yes, for your own use; those runs count against your plan's usage limits. Max and Team API credits cover claude -p only when it runs on an API key from your linked Console organization.

How do permissions work in claude -p?

Anything that would ask for approval is denied and the run continues. Pre-approve tools with --allowedTools, or use --permission-mode dontAsk for locked-down CI, acceptEdits for file edits, or auto for a classifier.

What does --bare do in Claude Code?

It skips hooks, skills, plugins, MCP servers, memory and CLAUDE.md, so a scripted run behaves the same everywhere and a repository can't run its own hooks. Anthropic recommends it for scripted calls; it needs an API key.