docspatterns2 min read

Claude Code Headless Mode & CI/CD

Claude Code without a human at the keyboard. Pipe mode turns it into a build tool you can wire into GitHub Actions, pre-commit hooks, and nightly jobs.

Claude Code doesn't need you watching

Everything so far has been interactive: you type, Claude responds, you approve. That's the normal mode.

But Claude Code also runs without you. You pipe in a prompt, it does the work, and pipes out the result. No chat, no approval prompts, no human in the loop.

This is how Claude Code becomes part of your build pipeline.

bash
echo "review this PR for bugs" | claude -p

The -p flag: pipe mode

The key flag is -p. It makes Claude Code non-interactive:

bash
# Basic: prompt as argument
claude -p "list all TODO comments in this project"

# Pipe stdin: feed data to Claude
cat error.log | claude -p "summarize the errors and suggest fixes"

# Pipe output: capture the result
claude -p "generate a changelog from recent commits" > CHANGELOG.md

# Chain: one Claude call feeds another
git diff | claude -p "review this diff" | claude -p "format as markdown table"

Key differences from interactive mode: nobody is there to click Allow, so any tool call that would have asked for permission is denied. Pre-approve what the job needs with --allowedTools, for example claude -p "fix the failing test" --allowedTools "Read,Edit,Bash(npm test *)". Output goes to stdout, and that includes failures such as missing authentication, which print as the result. You can script around it like any other Unix tool.

For CI, add --bare. It skips auto-discovery of hooks, skills, plugins, MCP servers, auto memory and CLAUDE.md, so the run starts faster and behaves the same on every machine. Without it, a -p run in a cloned repo runs that repo's hooks and connects its MCP servers, even in a folder you never trusted. Bare mode needs ANTHROPIC_API_KEY set.

CI/CD integration

GitHub Actions

yaml
# .github/workflows/review.yml
name: AI Code Review
on: [pull_request]

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Claude Code
        run: npm install -g @anthropic-ai/claude-code
      - name: Review PR
        run: |
          git diff origin/main...HEAD | claude -p "Review this diff for bugs, 
          security issues, and style violations. Be concise." > review.md
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
      - name: Post review
        run: gh pr comment ${{ github.event.number }} --body-file review.md

Pre-commit hook

bash
#!/bin/bash
# .git/hooks/pre-commit
git diff --cached | claude -p --model haiku \
  "Check this diff for: hardcoded secrets, console.log statements, 
   TODO comments. Reply 'PASS' if clean, or list issues." | \
  grep -q "PASS" || { echo "Review failed. Fix issues first."; exit 1; }

Automated test analysis

bash
# Run tests, feed failures to Claude
npm test 2>&1 | claude -p "Analyze these test results. 
  For each failure, explain the likely cause and suggest a fix."

Model selection for headless

Use the --model flag to match the model to the job:

bash
# Haiku 5.5 for fast, cheap tasks (linting, formatting checks)
claude -p --model haiku "check this file for style issues"

# Sonnet for standard tasks (code review, analysis)
git diff | claude -p --model sonnet "review this diff"

# Opus for complex tasks (architecture review, security audit)
claude -p --model opus "audit this codebase for security vulnerabilities"

Haiku for high-volume automated checks. Sonnet for standard CI tasks. Opus only when the stakes justify the cost. Measured on 2026-10-08 with Claude Code v2.1.293, one short diff review cost $0.01 to $0.02 on Haiku 5.5 ($0.0121 and $0.0204 over two runs). On 2026-09-27 the same kind of review cost about $0.08 on Haiku 4.5 and $0.24 on Sonnet 5. Most of that is Claude Code writing its own system prompt and tools into the cache, not your diff. So a pipeline with 2 Haiku calls and 1 Sonnet call runs about $0.28 ($0.02 x 2 + $0.24). Use v2.1.293 or later: on older versions --model haiku still runs Haiku 4.5. Fewer tools and MCP servers in the runner means a smaller prompt and a smaller bill.

bash
# Three steps in a GitHub Actions workflow
git diff origin/main...HEAD | claude -p --model sonnet "review this diff"
npm test 2>&1 | claude -p --model haiku "summarize failures"
claude -p --model haiku "generate changelog from recent commits" > CHANGELOG.md

Practical examples

Generate release notes

bash
git log v1.2.0..HEAD --oneline | claude -p \
  "Generate release notes from these commits. Group by: Features, Fixes, Other. 
   Write for end users, not developers." > release-notes.md

Automated documentation

bash
claude -p "Read all TypeScript files in src/api/ and generate 
  API documentation in Markdown format" > docs/api-reference.md

Nightly codebase health check

bash
claude -p "Analyze this project for: dead code, unused dependencies, 
  files over 500 lines, missing tests for public functions. 
  Output as a checklist." | tee health-report.md

Security: don't skip this section

Headless mode runs with whatever API key is in the environment. In CI:

  • Use secrets management. Never hardcode API keys in workflow files.
  • Scope permissions. Use project-level API keys with limited access.
  • Review outputs. Automated Claude output should be reviewed before merging or deploying.
  • Watch your costs. Automated pipelines can spend fast. Use Haiku for high-frequency checks, set spend alerts in the Anthropic console.

New guides, when they ship

One email, roughly weekly. CLAUDE.md templates, workflows I actually use, and the cut-for-length stuff that does not make the public guides. One-click unsubscribe.

Or read Product Field Notes, the Substack