Dev & Open Source

How to Run Claude Code Headless in 2026: A Practical Automation Guide

Claude Code headless mode runs the agent non-interactively via -p. How to script, schedule, and automate it in 2026: output, permissions, auth, CI/CD.

Waqas Ahmed Waseer
Waqas Ahmed Waseer Jul 13, 2026 8 min read
How to Run Claude Code Headless in 2026: A Practical Automation Guide

Claude Code headless mode runs the agent non-interactively: you pass the -p (or --print) flag with a prompt, Claude runs to completion, prints the result, and exits — no REPL, no keyboard, no one waiting at a terminal. That single flag turns an interactive coding assistant into a Unix-friendly command-line tool you can pipe into, wrap in a script, schedule with cron, or drop into a CI/CD pipeline. This guide covers how headless mode works in 2026, the flags that actually matter, how to get parseable JSON out of it, the permission and auth traps that quietly break unattended runs, and the lessons from running a headless Claude Code pipeline in production.

What is Claude Code headless mode?

Headless mode is Claude Code running without its interactive terminal UI. Add -p (short for --print) to any claude command and instead of opening the REPL, Claude reads the prompt, runs the full agent loop (reading files, running tools, editing code), then prints the final result and exits with a status code. It is the same agent that powers interactive Claude Code, just driven by a script instead of a human. As of 2026 the feature lives under the Agent SDK, which also ships as Python and TypeScript packages if you want callbacks and native message objects instead of shelling out.

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

Because non-interactive mode reads from stdin, it composes like any other CLI tool. You can pipe a build log straight in and redirect the answer out:

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

That composability (stdin in, text or JSON out, an exit code you can branch on) is the whole reason headless mode exists.

How to get structured output you can parse

Plain text is fine for a human reading a log, but automation needs structure. The --output-format flag accepts exactly three values: text (the default), json, and stream-json. The json format is the workhorse: it returns the answer plus session metadata in one object.

claude -p "Summarize this project" --output-format json | jq -r '.result'

The JSON payload includes result (the text), session_id, num_turns, is_error, duration_ms, and, critically for anyone running this at scale, total_cost_usd, a per-invocation cost figure so you can track spend without opening the dashboard. For machine-readable answers that conform to a shape you define, pair --output-format json with --json-schema '{...}'; the validated object comes back in a structured_output field. Use stream-json with --verbose when you want to render tokens as they arrive. Parse any of it with jq and you have a reliable programmatic interface.

Permissions: the part that trips everyone up

An interactive session asks before it runs a shell command or edits a file. A headless run has no one to ask, so by default it will refuse the action and can stall your pipeline. You have to grant permission up front. The cleanest tool is --allowedTools, a comma-separated allowlist:

claude -p "Run the test suite and fix any failures" --allowedTools "Bash,Read,Edit"

For finer control the flag uses permission rule syntax, so --allowedTools "Bash(git diff *)" allows only commands starting with git diff. To set a baseline for the whole run instead of listing tools, pass a --permission-mode: acceptEdits lets Claude write files and run common filesystem commands without prompting, while dontAsk denies anything not explicitly allowed, which is the right choice for a locked-down CI job. The blunt instrument, --dangerously-skip-permissions, approves everything and should only touch a throwaway sandbox or container, never a machine with credentials or production access.

Authentication: API key vs OAuth token

Headless runs need credentials that don't involve a browser login, and there are two honest paths. The first is ANTHROPIC_API_KEY, a key from the Anthropic Console billed per token, the natural fit for CI runners and pay-as-you-go automation. The second lets you reuse an existing subscription: run claude setup-token once, complete the OAuth flow in a browser, and it prints a one-year token you export as CLAUDE_CODE_OAUTH_TOKEN. That token is tied to a Pro, Max, Team, or Enterprise plan and scoped to inference only. Pick by billing model: metered API usage for burst CI workloads, the subscription token for a steady always-on agent. One caveat for scripted calls: --bare mode (which skips auto-discovery of hooks, skills, and MCP servers for reproducible runs) also skips OAuth, so under --bare you must supply ANTHROPIC_API_KEY.

Running Claude Code in CI/CD and on cron

Once a single command works non-interactively, scheduling it is ordinary DevOps. A cron entry that runs claude -p on a VPS turns the agent into a task that fires on its own: triaging logs at 2 a.m., drafting a changelog, or fixing lint on a schedule. In a pipeline, wrap the call in a script that pipes a diff in and branches on the exit code; Anthropic ships first-party GitHub Actions and GitLab CI/CD integrations for exactly this. Two flags matter for unattended reliability. Add --bare so runs don't silently inherit whatever hooks or MCP servers happen to sit in a teammate's ~/.claude, so you get the same result on every machine. And use --continue or --resume <session_id> when a job needs several turns that build on each other, capturing the session ID from the JSON output of the first call. If you are standing up the box yourself, our guide to self-hosting apps on a VPS covers the cron and hardening basics that keep a scheduled agent healthy.

FlagWhat it doesWhen you need it
-p / --printRun non-interactively, print result, exitEvery headless run
--output-format jsonStructured result with cost + session metadataAny scripted caller
--json-schemaForce output into a schema (structured_output)Machine-readable extraction
--allowedToolsPre-approve specific toolsStop the run stalling on prompts
--permission-modeSession-wide baseline (acceptEdits, dontAsk)Locked-down CI
--bareSkip auto-discovery for reproducible runsCI and SDK calls
--continue / --resumeMulti-turn conversations across callsStateful jobs

What we learned running a headless content engine

We use Claude Code headless in production ourselves: the pipeline that researches, writes, and publishes articles here at TechRiseUps runs as a scheduled claude -p job on our own WaseerHost infrastructure, driven by a custom skill rather than a person at the keyboard. A few lessons held up that the docs only hint at.

Permissions are the number one cause of a "stuck" run: a job that seems to hang is almost always Claude waiting for an approval that will never come, so pre-approve every tool the task genuinely needs and nothing more. Read total_cost_usd from the JSON on every invocation and log it; unattended agents have no natural cost ceiling, and the per-run figure is the only cheap way to catch a task that spiralled. Make each run idempotent, because a cron job will eventually fire twice or resume mid-way, and an agent that appends blindly makes a mess. And for long-running jobs that fan out with background subagents, raise the process file-descriptor limit, because a headless agent opening many files and sockets can silently hit the default ulimit and stall with no obvious error. None of these are exotic; they are the boring operational hygiene that separates a demo from a pipeline you trust to run while you sleep.

Frequently asked questions

What is headless mode in Claude Code? It is Claude Code running non-interactively via the -p / --print flag. Claude reads a prompt, runs the full agent loop, prints the final result, and exits, with no interactive terminal. It is meant for scripts, pipes, cron jobs, and CI/CD rather than hands-on coding.

How do I run Claude Code headless without paying for API keys? Generate a subscription-backed token with claude setup-token, then export it as CLAUDE_CODE_OAUTH_TOKEN. It authenticates against a Pro, Max, Team, or Enterprise plan instead of metered API billing. Note that --bare mode bypasses OAuth and still requires ANTHROPIC_API_KEY.

How do I stop Claude Code from asking for permission in headless mode? Pre-approve tools with --allowedTools "Bash,Read,Edit", or set a session baseline with --permission-mode acceptEdits (or dontAsk for locked-down CI). Only use --dangerously-skip-permissions inside a disposable sandbox, never on a machine with real credentials.

Can I run Claude Code headless from Python? Yes. Headless mode is part of the Agent SDK, which ships as Python and TypeScript packages in addition to the claude -p CLI. Use the SDK packages when you want tool-approval callbacks, native message objects, and structured outputs without parsing stdout.

Is headless mode the same as the Claude Agent SDK? They are two front doors to the same engine. claude -p is the CLI form of the Agent SDK — same tools, agent loop, and context management. The Python and TypeScript SDK packages give you fuller programmatic control for building agents into applications.

Sources

Some links may earn us a commission at no extra cost to you.

Waqas Ahmed Waseer

Waqas Ahmed Waseer

Waqas Ahmed Waseer is a developer and automation builder with 8+ years shipping production systems used by 100k+ people. He builds custom multi-tenant SaaS, AI automation (n8n, LLM workflows, WhatsApp bots) and hosting infrastructure (WHM/cPanel, CloudLinux) — and is the maker of WaSphere, FlowMaticX, and the WaseerHost hosting brand. 100+ projects delivered for SMBs, agencies and funded startups.

Related

More in Dev & Open Source

View all

Discussion · 0

Be kind. Comments are public.

    Newsletter · Monday edition

    The Monday brief.

    One email every Monday morning. The week ahead in AI, startups, hosting and dev tools — no fluff, no sponsored bait.

    Free. Unsubscribe in one click.