Skip to main content
Non-interactive mode (-p / --print) runs Claude Code as a single-shot command: send a prompt, get a response, exit. There is no REPL, no UI, and no user interaction. This makes it suitable for shell pipelines, CI/CD jobs, and SDK-style integrations.
The workspace trust dialog is skipped when Claude is run with -p. Only use this flag in directories you trust.

Basic usage

claude -p "your prompt here"
Claude processes the prompt, prints the response to stdout, and exits. By default the output is plain text.
# Ask a question
claude -p "what does the --dry-run flag do in rsync?"

# Ask about a specific file
claude -p "summarise the public API of src/auth/token.ts"

Reading from stdin

When stdin is not a TTY, Claude Code reads it and appends it to the prompt. This lets you pipe file contents, command output, or any text directly into a prompt.
# Explain a file
cat src/utils/retry.ts | claude -p "explain this code"

# Summarise a diff
git diff HEAD~1 | claude -p "write a concise commit message for this diff"

# Analyse test failures
npm test 2>&1 | claude -p "identify the root cause of these test failures"
If no stdin data arrives within 3 seconds, Claude Code proceeds without it and prints a warning to stderr. To skip stdin explicitly, redirect from /dev/null: claude -p "prompt" < /dev/null.

Output formats

Use --output-format to control how the response is printed. This flag only works with --print.
Plain text — Claude’s response as a string, suitable for human reading or piping into other tools.
claude -p "list the files changed in HEAD" --output-format text

Input format

Use --input-format to describe the shape of data arriving on stdin.
ValueDescription
text (default)Plain text read from stdin and appended to the prompt
stream-jsonA newline-delimited stream of JSON messages (SDK control protocol)
stream-json input is used for SDK integrations where the orchestrating process sends structured messages rather than raw text.

Limiting agentic turns

By default Claude Code will run as many tool-use turns as needed to complete the task. Use --max-turns to set a hard upper bound:
# Stop after at most 5 tool-use turns
claude -p "fix all lint errors" --max-turns 5
This is useful in CI pipelines where you want a safety limit on how much work Claude can do autonomously.

Exit codes

CodeMeaning
0Claude finished successfully
1An error occurred (API error, invalid flags, etc.)
Scripts should check the exit code before consuming stdout.

Using in scripts and CI/CD pipelines

#!/bin/bash
set -e

# Generate a PR description from the current diff
description=$(git diff main | claude -p "write a GitHub pull request description for this diff")

# Create the PR using the generated description
gh pr create --title "automated changes" --body "$description"
Set ANTHROPIC_API_KEY (or configure another auth method) before running Claude Code in CI. The interactive OAuth flow is not available in non-interactive mode.

Environment variables

Claude Code inherits environment variables from the calling shell. Variables that affect behaviour in non-interactive mode include:
VariableEffect
ANTHROPIC_API_KEYAPI key for authentication
CLAUDE_CODE_ENTRYPOINTIdentifies the caller context (e.g. sdk-ts, sdk-py, github-action)
GITHUB_ACTIONSWhen set to true, Claude Code identifies the client type as github-action

SDK usage pattern

The Claude Code CLI can be driven programmatically from the official SDKs. The SDK launches Claude Code as a subprocess with --output-format stream-json and --input-format stream-json, exchanging structured JSON messages over stdio.
# Equivalent to what the SDK does internally
claude -p "task description" \
  --output-format stream-json \
  --input-format stream-json
When using the SDK you do not need to construct these flags manually — the SDK handles the subprocess lifecycle and message parsing for you.

Complete flag reference for non-interactive mode

FlagDescription
-p, --printEnable non-interactive mode
--output-format <format>text (default), json, or stream-json
--input-format <format>text (default) or stream-json
--max-turns <n>Maximum number of agentic turns
--model <model>Model to use (alias or full name)
--allowed-tools <tools...>Comma or space-separated list of tools to allow
--disallowed-tools <tools...>Comma or space-separated list of tools to deny
--system-prompt <prompt>Override the system prompt
--append-system-prompt <prompt>Append text to the default system prompt
--add-dir <directories...>Additional directories to allow tool access to
--no-session-persistenceDisable saving the session to disk
-c, --continueContinue the most recent conversation
-r, --resume [session-id]Resume a specific session by ID

Build docs developers (and LLMs) love