Skip to main content

Automating Repetitive Tasks with Claude Code Headless Mode (claude -p)

Learn how to run Claude Code non-interactively from scripts or servers using headless mode (claude -p), including stdin piping, output formats, and permission flag caveats.

By
🌐 This article was machine-translated and may contain inaccuracies. Read the Korean original if in doubt.

Claude Code's headless mode — running the tool without a screen or an interactive session, executing a single command and finishing right away. Adding the -p flag lets you skip the back-and-forth of a terminal conversation: you pass in one prompt, Claude Code prints the answer, and it exits. This makes it possible to call Claude Code from scripts, servers, or cron jobs (scheduled tasks that run automatically at set times) without anyone sitting at the terminal. Follow this guide and in about 20 minutes you'll go from a basic headless call to choosing an output format and avoiding the permission-flag mistakes people hit most often.

🟢 Model references match the current lineup · model notice · Fable subscription
🟢 Model references match the current lineup · Claude Opus 5.5 / Claude Sonnet 5 / Claude Haiku 4.5 (higher tier: Claude Fable 5.1). This notice changes only when Anthropic ships a new model.

Fable 5 and 5.1 subscription (updated September 7, 2026): Claude Fable 5.1, released September 1, 2026, is the current Fable model and Fable 5 is now legacy. Plan terms are the same for both — Max and Team Premium plans include Fable at up to 50% of the weekly usage limit; Pro and Team Standard use usage credits (

🟢 Model references match the current lineup · Claude Opus 5.5 / Claude Sonnet 5 / Claude Haiku 4.5 (higher tier: Claude Fable 5.1). This notice changes only when Anthropic ships a new model.
0/M input, $50/M output tokens). The one-time
🟢 Model references match the current lineup · Claude Opus 5.5 / Claude Sonnet 5 / Claude Haiku 4.5 (higher tier: Claude Fable 5.1). This notice changes only when Anthropic ships a new model.
00 credit applied only to the Fable 5 transition and is not offered for 5.1. Some coding and debugging requests may be answered by an Opus model due to a security classifier (both models). See the Fable 5.1 guide and the Fable 5 availability guide for details.

Interactive mode claude Input → response Input → response (repeats) Session stays open Headless mode claude -p "prompt" Input once Output printed Exit

What you need before you start

Check the following before trying headless mode.

  • The Claude Code CLI (the command-line tool you run in a terminal) installed — on macOS, Linux, or WSL run curl -fsSL https://claude.ai/install.sh | bash; on Windows use PowerShell or WinGet per the official install steps.
  • At least one prior login via claude, or, for a server/CI environment, an API key ready in the ANTHROPIC_API_KEY environment variable.
  • Basic terminal familiarity — running commands and understanding what the pipe (|) symbol does.
  • A shell environment (such as bash) to run your script in, if you're automating this on a server or via cron.

Quick term glossary

  • Headless mode — running without a screen or interactive session: one command in, one result out, then exit.
  • Flag — an option appended to a command that changes its behavior, e.g. -p, --output-format.
  • stdin/stdout — the channels a program uses to receive input (stdin) and send output (stdout).
  • Pipe (|) — a shell symbol that feeds one command's output directly into another command's input.
  • Permission prompt — the interactive confirmation screen Claude Code shows before editing a file or running a command.

Step-by-step

Flag names and option values below can change between versions, so before wiring any of this into a real script, run claude -p --help in your terminal to confirm the exact options available in your environment.

Step 1 — A basic headless call

claude -p "Summarize the dependencies listed in this folder's package.json"

Adding -p (or --print) tells Claude Code not to open an interactive session — it just prints the answer to your prompt and exits.

You'll know it worked when: the response text prints to the terminal and you're immediately returned to a prompt where you can type another command. If the terminal instead sits there as if waiting for input, you likely forgot -p and it launched in interactive mode. Press Ctrl+C to exit, then re-run with -p.

Step 2 — Piping a file or another command's output as input

cat error.log | claude -p "Summarize the root cause of this error log in one line"

Piping (|) sends the piped content into Claude Code alongside your prompt. You can pipe in a log file, the output of git diff, or anything else that's plain text.

You'll know it worked when: the response reflects the actual piped content — for example, quoting the specific error text from your log file.

Step 3 — Choosing an output format

If a script needs to parse the result rather than just display it to a person, a structured format is safer than plain text, whose wording can shift slightly between runs.

--output-format valueWhat it doesWhen to use it
text (default)Prints a human-readable plain-text responseReading the result directly in the terminal
jsonPrints the full response as a single JSON objectA script needs to parse the result for a next step
stream-jsonPrints the process as a sequence of JSON eventsForwarding progress to another program in real time
claude -p "List all the TODO comments in the src folder" --output-format json

You'll know it worked when: instead of a human-readable sentence, the terminal prints JSON text starting with {. Run it once and inspect the actual field structure before you rely on it in a script.

Step 4 — Understanding permission flags

Headless mode has no screen to show a confirmation prompt on. So when it hits an action that would normally require your approval — like editing a file — the script can hang or exit with an error. The flags below let you decide in advance what's allowed.

Permission-required action occurs No flag set Can't show a prompt, so it hangs or exits with an error --allowedTools set Only the listed tools are pre-approved and proceed --dangerously-skip-permissions All approval steps skipped Risky — sandboxed use only
FlagWhat it doesWatch out for
--permission-modeSets the mode that governs the approval processConfirm the exact mode names and default with claude -p --help.
--allowedToolsPre-approves only the listed tools so they run without a promptScope it to only what your script actually needs.
--disallowedToolsExplicitly blocks specific tools from being usedUseful for blocking sensitive actions, like deletion-related commands.
--dangerously-skip-permissionsSkips every approval stepAs risky as it sounds — see the warning below.

Caution: --dangerously-skip-permissions skips every confirmation step before editing files or running commands. Using it in an automation pipeline where untrusted input might reach the prompt (say, text pulled from an external source and fed in directly) can lead to unexpected file changes or deletions. Only use it inside an isolated environment, like a container, and only when you fully control the input.

Step 5 — Keeping session context across multiple steps

claude -p "Now add test code for the file you just created" -c

-c (--continue) or --resume lets a new prompt pick up the context from a previous headless call. That's useful when a script needs to walk through a multi-step task that a single call can't finish in one shot.

You'll know it worked when: the response continues the earlier work without you having to re-explain the file or context.

Step 6 — Running it from a server or cron job

export ANTHROPIC_API_KEY="your_api_key_here"
claude -p "Summarize today's commits as Slack-ready text" --output-format json

On a server or in a cron job where interactive login isn't possible, authenticate with the ANTHROPIC_API_KEY environment variable instead.

Caution: never commit an API key directly into code or a repository. Inject it through environment variables or a secrets manager (your server's environment configuration, or your CI system's secrets store).

Common sticking points & fixes

Issues people run into most often when first automating with headless mode:

  • The terminal seems to hang — usually means -p was left off and it launched in interactive mode, waiting for input. Press Ctrl+C, then re-run with -p.
  • The script hangs or exits with an error — it hit an action that needed approval but had no screen to ask on. Pre-approve the needed tools with --allowedTools, or adjust --permission-mode.
  • Login-related errors in CI or cron — ANTHROPIC_API_KEY isn't set. Confirm the environment variable is actually reaching that shell session.
  • Parsing errors in your script — you're parsing plain human-readable text without setting --output-format. Switch to json or stream-json.

Going further

You can pipe git diff output in to draft commit messages, or loop the same prompt across multiple repositories for a batch check. This guide covered general-purpose automation from local and server scripts. Wiring this into a CI platform like GitHub Actions is covered separately — check that guide if you want to drop this into a pipeline step.

Frequently asked questions

Q. What's the difference between claude -p and plain claude?
Adding -p (--print) skips the interactive session entirely — it prints the response to your prompt and exits immediately. That fits scripts and servers, where no one is present to continue a conversation.

Q. Can headless mode still edit files?
Yes. But since there's no confirmation screen, you need to decide in advance what's allowed using permission flags like --allowedTools, or the script may hang instead of behaving as expected.

Q. When is it okay to use --dangerously-skip-permissions?
Best avoided when you can. If you truly need it, scope it as narrowly as possible and only run it inside an isolated environment, like a container, where you fully control the input.

Q. Which output format should I use if another program needs to read the result?
--output-format json or stream-json is recommended. The default plain-text format is easy for a person to read, but even small wording changes in Claude's response can break a parsing script.

Was this helpful?

Keep reading