Run Claude Code in CI With No Human: Headless Mode Explained

July 24, 2026 · Claude Certified Architect (CCA) Prep (part 29)

▶ Watch on YouTube & subscribe to The Stack Underflow

A new issue lands on your repo at 2 a.m. Nobody is at a keyboard. You want Claude Code to open the issue, look at the codebase, write a triage comment, and maybe attach a label — automatically, as part of your CI pipeline. You reach for the same claude binary you use every day at your desk. It works great when you’re typing into it. It hangs the moment a GitHub Actions runner tries to drive it the same way. Something about the invocation has to change, and picking the wrong one is the difference between a working pipeline and a stuck job that eventually times out.

The one-sentence version: A CI job with no human at the keyboard needs a non-interactive invocation — headless (print) mode, not the interactive terminal UI — because only headless mode is designed to run once, emit structured output, and exit.

The question

You must run Claude Code inside CI to triage new issues, with no human at the keyboard. What’s the best invocation?

  • A) The interactive TUI
  • B) Headless / print mode (claude -p '…', JSON output)
  • C) Copy-paste into chat
  • D) A cron job that opens a terminal

Pause here and pick an answer before you keep reading.

The answer

B — headless / print mode. You invoke Claude Code non-interactively, typically something like claude -p "triage issue #123" --output-format json, and the pipeline consumes whatever comes back as structured data.

The mechanism is about what each invocation mode actually is, not just what flag you type. The interactive TUI is built around a loop that waits for a human to read output and type the next instruction. It expects a terminal session with a person attached to the other end. CI has no person. A CI runner can’t read a rendered terminal UI, and it has no way to answer an interactive prompt if one appears — so an interactive session inside CI either hangs waiting for input or gets killed by the job timeout.

Headless mode inverts that contract. You give it a complete prompt up front, it runs the agent loop start to finish without asking anything, and it prints a single result — ideally as JSON — and exits with a status code. That’s precisely the shape a CI step needs: input in, deterministic output out, a clean exit.

GitHub Actions / CI runner

        │  triggers on: issues.opened

┌───────────────────────────────────────────────────┐
│ claude -p "triage issue #123 in this repo:         │
│   summarize root cause, suggest a label"           │
│   --output-format json                             │
│                                                     │
│  no TTY attached · no prompts asked · runs once    │
└───────────────────────────────────────────────────┘

        │  stdout: { "result": "...", "label": "bug", ... }

   next CI step parses JSON

        ├──▶ post triage comment on the issue
        └──▶ apply the suggested label

The JSON output format matters as much as the non-interactive part. A CI step downstream doesn’t want to scrape prose out of a chat transcript — it wants a field it can parse reliably. Headless mode’s structured-output option is what turns “the agent ran” into “the pipeline can act on what the agent found.” (If forcing that structure to actually validate is a topic you want to go deeper on, see How Do You Guarantee Valid JSON? Forcing Structured Output.)

Why the other options fail

  • A) The interactive TUI — built for a human watching a live session and answering prompts as they come up. Point it at a CI runner and it either blocks indefinitely waiting for input that will never arrive, or the job just times out. There’s no keyboard on the other end to unblock it.
  • C) Copy-paste into chat — this isn’t automation at all; it reintroduces the exact human-in-the-loop step you’re trying to remove. If a person has to open a chat window and paste something in, you don’t have a CI pipeline, you have a manual process with extra steps.
  • D) A cron job that opens a terminal — cron can schedule when something runs, but “opens a terminal” still implies an interactive session waiting for a human, which a scheduled job can’t provide. Cron solves the wrong problem here; the problem isn’t timing, it’s that the invocation mode itself assumes a person is present.

The concept behind it

Zoom out from this one question and the pattern generalizes to any tool with both an interactive and a scriptable mode: the invocation mode has to match who — or what — is driving it.

DriverWhat it needsClaude Code mode
A developer at a keyboardLive back-and-forth, editable multi-turn session, visible diffsInteractive TUI
A CI runner, cron job, or webhook handlerA single complete prompt in, structured result out, no prompts, an exit codeHeadless / print mode (-p)
A human copy-pasting into chatNothing — this is a workaround, not an integrationN/A

Two properties make headless mode specifically suited to automation, and they’re worth internalizing rather than memorizing:

  1. No interactive prompts. Headless mode either runs with the permissions and context it was given or it fails — it does not stop mid-run to ask “should I proceed?” That’s exactly what a scriptable process needs: predictable behavior with no human to answer.
  2. Structured, parseable output. --output-format json (or the current equivalent — check the docs, this is exactly the kind of flag that gets renamed) turns the agent’s final answer into something a downstream step can parse with a JSON library instead of regex-scraping a transcript.

This is also where headless mode intersects with permissions design, because a fully unattended run needs to know in advance what it’s allowed to do — there’s no human standing by to approve a risky action mid-run. That’s the same scoped-permissions idea covered in Allow npm test, Gate Destructive Git: Claude Code Permissions: a CI-triggered headless run should be handed a tight, pre-approved allowlist, not run wide open.

One caveat worth carrying into the exam and into production: Domain 3 tracks live product behavior, and headless mode’s exact flags and output-format options are among the fastest-moving parts of Claude Code. The durable thing to remember is the mechanism — non-interactive invocation, structured output, no human required — not the precise flag spelling, which you should verify against the current Claude Code docs before you wire it into a real pipeline.

FAQ

What’s the actual command to run Claude Code headlessly? The general shape is claude -p "your prompt here" with an output-format flag for structured results, e.g. --output-format json. Treat this as illustrative — the exact flag names and available output formats change between releases, so confirm current syntax in the official Claude Code CLI reference before you script against it.

Can headless mode still use tools like file edits or Bash commands in CI? Yes — headless mode runs the same underlying agent loop with the same tool access as an interactive session, it just doesn’t stop to ask permission interactively. That’s why permission configuration matters more, not less, for headless runs: whatever the run is allowed to do, it will do without a human confirming each step.

Is headless mode only for CI, or can I use it locally too? It’s useful anywhere you want a single, scriptable, non-interactive invocation — a shell script, a cron job on your own machine, a pre-commit hook, or a CI pipeline. The defining trait isn’t “runs in CI,” it’s “runs with nobody watching and needs to finish on its own.”

Why not just automate the interactive TUI with something like a terminal-scripting tool? You could technically try to drive a TUI programmatically, but you’d be fighting the tool’s design rather than using it. Headless mode exists specifically so you don’t have to simulate keypresses against an interface built for humans — use the mode built for the job instead of automating around the one that isn’t.

Not affiliated with, authorized, or endorsed by Anthropic. “Claude” and “Claude Certified Architect” are trademarks of Anthropic. These are original practice questions for study, not real exam content — verify current exam details on Anthropic’s official pages.

Where this fits in the CCA series

This is Domain 3 (Claude Code Configuration & Workflows, 20% of the exam) — the domain about how you actually run and govern Claude Code day to day, not just how you prompt it. If you’re studying the full blueprint, start with Claude Certified Architect (CCA) Exam Guide: All Five Domains on One Diagram.

Headless mode is the automation half of D3; the other half is where rules and shortcuts live. See Instructions or a Hook — Which Runs Every Time? CLAUDE.md vs Hooks for the advisory-vs-enforced distinction that also matters once your triage run needs guaranteed side effects, Allow npm test, Gate Destructive Git: Claude Code Permissions for scoping what an unattended run can touch, and A Scoped ‘Test-Writer’ Agent: Custom Subagents in Claude Code for delegating a headless run’s work to a narrowly-tooled specialist instead of the full main agent.

Browse all tutorials for the rest of the series.

Found this useful? The deep version lives on YouTube — new breakdowns of how AI dev tools actually work, weekly.

Subscribe on YouTube →