If you have seen claude -p in a script or a GitHub workflow and wondered what it does, here is the short answer: -p (short for --print) runs Claude Code non-interactively. You give it a prompt, it does the work, prints the answer and exits, just like any other command-line tool.
That one flag turns Claude Code into something you can pipe data into, call from npm scripts, run in CI and chain in shell scripts.
This guide covers what claude -p is, every useful flag, JSON and structured output, permissions for unattended runs, bare mode, continuing conversations, ready-to-use examples and fixes for common errors, all checked against Anthropic’s current Claude Code docs.
- What it is:
claude -p "prompt"runs Claude Code once without the interactive interface, prints the result and exits (code 0 on success, non-zero on failure). - Pipe data in:
cat error.log | claude -p "explain the root cause"(stdin is capped at 10 MB). - Machine-readable output:
--output-format json(orstream-json), plus--json-schemafor structured results. - Permissions: pre-approve tools with
--allowedTools "Read,Edit,Bash"or set--permission-mode(acceptEdits,auto,dontAsk). - For CI: add
--barefor fast, repeatable runs that skip local hooks, plugins, MCP servers, CLAUDE.md and auto memory (needsANTHROPIC_API_KEY). - Limits:
--max-turnsand--max-budget-usdstop runaway jobs.
What claude -p Means
Normally, claude opens an interactive session in your terminal. Adding -p or --print switches to non-interactive mode, which Anthropic calls running Claude Code programmatically through the Agent SDK’s CLI.
You get the same tools, agent loop and context handling as the interactive app, but with no chat window. The run ends when Claude finishes, so you can:
- Use Claude inside shell scripts, Makefiles and npm scripts.
- Pipe logs, diffs and files into it, and redirect its answer to a file.
- Run it in CI/CD (GitHub Actions, GitLab) for reviews, fixes and reports.
- Get JSON back and parse it with tools like
jq.
Not installed yet? Follow our Claude Code install guide first.
Basic Usage
claude -p "What does the auth module do?"
Claude reads your project, answers and exits. Claude Code returns exit code 0 on success and a non-zero code when the run fails, so scripts can branch on it. Invalid flags are reported on stderr before the run starts.
To let Claude actually change files, pre-approve the tools it needs:
claude -p "Find and fix the bug in auth.py" --allowedTools "Read,Edit,Bash"
Not every flag combines with -p. For example, Claude Code rejects --bg with an error naming the conflict.
The Flags You Will Use Most
| Flag | What it does | Example |
|---|---|---|
-p, --print |
Non-interactive mode | claude -p "summarise README.md" |
--output-format |
text (default), json or stream-json |
--output-format json |
--json-schema |
Force output to match a JSON Schema | See the JSON section |
--allowedTools |
Pre-approve tools or commands | --allowedTools "Read,Edit" |
--permission-mode |
Baseline approvals: acceptEdits, auto, dontAsk |
--permission-mode acceptEdits |
--permission-prompts none |
Deny anything that would wait for a human (v2.1.259+) | Scheduled jobs |
--bare |
Skip auto-discovery of hooks, skills, plugins, MCP, CLAUDE.md, auto memory | CI runs |
--model |
Pick a model alias (sonnet, opus, haiku, fable) or full name |
--model sonnet |
--max-turns |
Cap agentic turns (print mode only) | --max-turns 5 |
--max-budget-usd |
Stop when estimated API spend hits a cap (print mode only) | --max-budget-usd 2 |
--continue, -c |
Continue the most recent conversation | claude -p "now fix it" -c |
--resume, -r |
Resume a session by ID, name or transcript path | --resume "$id" |
--append-system-prompt |
Add instructions on top of the default system prompt | Role prompts in scripts |
--mcp-config |
Load MCP servers from a file or JSON | Tools in bare mode |
Pipe Data In and Out
Non-interactive mode reads stdin, so it behaves like any Unix tool:
cat build-error.txt | claude -p "concisely explain the root cause of this build error" > output.txt
- Stdin cap: piped input is limited to 10 MB. For bigger inputs, save to a file and reference the path in your prompt.
- No extra permissions needed: piping a diff in means Claude does not need Bash permission to read it.
- Windows-friendly scripts: use escaped double quotes inside
package.jsonscripts.
JSON, Streaming and Structured Output
JSON with metadata
claude -p "Summarize this project" --output-format json | jq -r '.result'
The JSON includes the text in result, plus session_id, usage and total_cost_usd with a per-model cost breakdown, so scripts can track spend.
Structured output with a schema
claude -p "Extract the main function names from auth.py" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
| jq '.structured_output'
The result lands in structured_output. If Claude declines or the run fails, that field is missing, so always check it exists before using it. An invalid schema exits with Error: --json-schema is not a valid JSON Schema.
Live streaming
claude -p "Explain recursion" --output-format stream-json --verbose --include-partial-messages
Each line is a JSON event; the last line is a result message with the final text, cost and session data. Retryable API failures show up as system/api_retry events.
Permissions in Non-Interactive Runs
There is nobody to click “Allow” in a script, so decide permissions up front.
| Option | Effect | Good for |
|---|---|---|
--allowedTools "Read,Edit" |
Those tools run without asking | Targeted jobs |
--allowedTools "Bash(git diff *)" |
Only commands starting with git diff (note the space before *) |
Tight command allowlists |
--permission-mode acceptEdits |
File writes and common file commands (mkdir, mv, cp) auto-approved |
Lint fixes, refactors |
--permission-mode auto |
A classifier reviews most actions instead of you | Longer unattended tasks |
--permission-mode dontAsk |
Denies anything that would prompt | Locked-down CI |
--permission-prompts none |
Never waits for a human; prompts become denials | Cron jobs, scheduled runs |
Calls to tools you did not list still run if they need no approval (such as reading files in your working directory). In Manual mode, anything that needs approval is denied unless something approves it.
--bare, a -p run executes the hooks in a project’s .claude/settings.json and connects servers in its .mcp.json, even in a folder you have never trusted, and shows no trust dialog. Only run claude -p in repos you trust, or use --bare. See our MCP security best practices.Bare Mode for CI and Scripts
claude --bare -p "Summarize README.md" --allowedTools "Read"
--bare skips auto-discovery of hooks, skills, custom commands, subagents, plugins, MCP servers, auto memory and CLAUDE.md. It starts faster and gives the same result on every machine. Anthropic recommends it for scripted and SDK calls and says it will become the default for -p in a future release.
- Auth: bare mode never reads your subscription login or keychain. Set
ANTHROPIC_API_KEY(from the Claude Console) or use anapiKeyHelperin--settings. - Tools: Claude gets Bash, file read and file edit.
- Add context explicitly:
--append-system-promptor--append-system-prompt-file,--settings,--mcp-config,--agents,--plugin-dir. - Limits: no hooks (even passed via settings), no system reminders and no background tasks.
Because bare mode skips CLAUDE.md, pass key project rules with --append-system-prompt-file. Our CLAUDE.md guide explains what to put in that file.
Continue a Conversation
# First request
claude -p "Review this codebase for performance issues"
# Continue the most recent conversation
claude -p "Now focus on the database queries" --continue
# Resume a specific session
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"
Claude Code finds a session by ID in any project on the same machine, and --resume also accepts the absolute path to a session’s .jsonl transcript.
7 Ready-to-Use Examples
- Explain a failing build:
npm run build 2>&1 | claude -p "explain this error and suggest a fix" - Typo linter in package.json:
"lint:claude": "git diff main | claude -p \"you are a typo linter. report filename:line and the issue. return nothing else.\"" - Auto commit message:
claude -p "Look at my staged changes and create an appropriate commit" --allowedTools "Bash(git diff *),Bash(git log *),Bash(git status *),Bash(git commit *)" - Security review of a PR:
gh pr diff "$1" | claude -p --append-system-prompt "You are a security engineer. Review for vulnerabilities." --output-format json - Fix failing tests:
claude -p "Run the test suite and fix any failures" --allowedTools "Bash,Read,Edit" --max-turns 10 - Apply lint fixes:
claude -p "Apply the lint fixes" --permission-mode acceptEdits - Unattended dependency update:
claude -p "Update the dependency pins and run the tests" --permission-mode auto --permission-prompts none
Slash Commands and Skills in -p Mode
- Skills and custom commands work: include
/skill-namein the prompt and Claude Code expands it. See our Claude Skills guide. - Terminal-only commands like
/loginare not available. - Some commands take an argument:
/model sonnet,/effort,/fast, and/config thinking=falseto change a setting. - /mcp with no argument prints a text summary of server status.
Costs and Safety Limits
- Subscription vs API: normal
-pruns can use your Claude login;--bareruns bill your API key. Compare plans in our Claude Code pricing guide. - Cap spend:
--max-budget-usdstops the run (and any background work) at your limit. - Cap loops:
--max-turnslimits agentic turns; there is no limit by default. - Track costs: read
total_cost_usdfrom JSON output. - Background work: a run can wait for background tasks it started; by default, idle waiting stops after 10 minutes.
- Stopping: SIGTERM exits with code 143 and leaves the turn unfinished; send SIGINT first to end the turn cleanly.
More ways to save are in how to reduce Claude Code token usage.
Troubleshooting
| Problem | Likely cause | Fix |
|---|---|---|
| Claude says it cannot edit files | Edit or Bash not approved | Add --allowedTools "Read,Edit,Bash" or a permission mode |
Auth error in --bare |
Bare mode ignores your login | Set ANTHROPIC_API_KEY |
| Input too large error | Stdin over 10 MB | Write to a file and reference its path |
structured_output missing |
Claude declined or run failed | Check the field exists; look at result and exit code |
Unknown option --permission-prompts |
Claude Code older than v2.1.259 | Update Claude Code |
| A hook or MCP server unexpectedly ran | Normal -p loads project config |
Use --bare and pass only what you need |
| Different results on CI vs laptop | Local hooks, plugins or CLAUDE.md differ | Use --bare for repeatable runs |
| MCP server silently missing | Invalid --mcp-config entry skipped |
Check mcp_server_errors in the system/init event |
| Run hangs at the end | Waiting for background work | Check the stderr “Waiting for background work” line; lower the 10-minute cap with CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS |
My Take
claude -p is where Claude Code stops being a chat app and becomes a building block. Start with piping errors and diffs into it, then add --output-format json when you need to parse results.
For anything in CI, use --bare, a tight --allowedTools list and a --max-budget-usd cap. That combination is fast, predictable and safe.
FAQ
What does claude -p do?
It runs Claude Code non-interactively: it takes your prompt, does the work, prints the result and exits. -p is short for --print.
What is the difference between claude and claude -p?
claude opens an interactive session. claude -p runs one task without the interface, so it works in scripts, pipes and CI.
How do I get JSON output from Claude Code?
Add --output-format json. For a fixed shape, also pass --json-schema and read the structured_output field.
Does claude -p use CLAUDE.md?
Yes, normally it loads CLAUDE.md like an interactive session. With --bare it skips CLAUDE.md, hooks, plugins, MCP servers and auto memory.
How do I stop claude -p asking for permission?
Pre-approve tools with --allowedTools, or set --permission-mode acceptEdits, auto or dontAsk. Add --permission-prompts none for unattended runs.
Can I continue a claude -p conversation?
Yes. Use --continue for the most recent one, or --resume with a session ID from the JSON output.
Does claude -p cost extra?
It uses the same usage as interactive Claude Code. Bare mode bills your API key. Use --max-budget-usd to cap spend.
Can I use claude -p in GitHub Actions?
Yes. Anthropic documents GitHub Actions and GitLab CI/CD setups; use --bare and an API key secret for repeatable runs.



