Headless mode
📖 4 min readUpdated 2026-04-18
Headless mode runs Claude Code non-interactively. No terminal UI, no approval prompts (either pre-authorized or blocked). The agent takes input, does the work, and emits output, ready to be wired into automation.
Why you'd want it
- Running an agent from a cron job
- Running an agent as a CI/CD step
- Running an agent from a webhook handler
- Running an agent inside a larger system (as a microservice)
How to run Claude Code headless
The CLI supports a non-interactive mode, pass a prompt, get output, exit.
echo "Analyze yesterday's error logs and write a summary" | claude --headless --print
Options you'll want:
--headless, disable the TUI, read prompt from stdin
--print, print final response to stdout and exit
--max-turns N, hard cap on agent turns
--permission-mode auto, pre-approve known-safe actions
--no-input, never prompt the user; fail or skip when a decision is needed
What changes in headless mode
- Approval prompts become denials. If the agent tries to do something that needs approval and no one's there, the harness denies the call. Your permission list had better cover what the agent needs.
- Errors surface immediately. No retry-from-interactive. Design for graceful failure.
- State management matters. Each run starts from a clean slate unless you persist context (memory file, external DB).
Permission design for headless
In headless mode, the permission list has to be right. No user to rescue you.
- Allow everything the agent will actually need
- Deny everything risky (even if it seems unlikely)
- Log every tool call so you can review later
- Set a strict
--max-turns to cap runaway costs
Patterns
Task-runner pattern
Write a shell script or cron entry that pipes a task description into Claude Code:
#!/bin/bash
claude --headless --print --max-turns 50 << 'EOF'
Check yesterday's server logs for 5xx errors. Summarize into
a report. Post to Slack channel #alerts.
EOF
Webhook handler pattern
A web server receives a webhook, formulates a prompt, invokes Claude Code headless, returns the response.
CI/CD step pattern
In a GitHub Action: after the test suite runs, invoke Claude headless to analyze failures and open an issue.
Logging
Every headless run should log:
- Timestamp
- Input prompt
- All tool calls + results
- Final output
- Exit code
- Cost (tokens consumed)
Use a PostToolUse hook to pipe tool calls to your log system.
Common pitfalls
- Infinite loops. Set max-turns. Always.
- Forgotten credentials. Headless runs don't have access to your keychain unless you explicitly pass env vars.
- Silent failures. A headless run that errors at tool-call time but still exits 0 will run for months unnoticed. Make errors loud.
- Runaway costs. Without a human checking in, a broken agent can spend thousands of dollars of API calls in a week. Budget alerts matter.