Delegate tasks to an independent Claude Code session for execution via Claude Code CLI.
You can understand claude -p as the CLI entry point of the Claude Code Agent SDK. Older documentation sometimes calls it headless mode, but its behavior is on the same capability line as the current -p entry point.
Prerequisites
- Install Claude Code CLI:
npm install -g @anthropic-ai/claude-code - Make sure authentication is complete:
claude auth login - You can use
claude auth status --textto quickly confirm the current login status - It is recommended to switch to the target project directory before running; automated calls use
claude -p
Invocation Methods
New session (default)
claude -p "你的任务描述" --output-format json --permission-mode bypassPermissions --model <flagship> --effort high
Returns a single JSON object, commonly used fields:
{
"type": "result",
"subtype": "success",
"is_error": false,
"result": "回复内容",
"session_id": "81a5f75b-...",
"total_cost_usd": 0.0944715,
"usage": { "input_tokens": 3, "output_tokens": 4 }
}
- From
session_idextract the session ID for subsequent multi-turn conversations - From
resultextract Claude's final reply - Use
is_error、subtype、usage、total_cost_usdto determine whether an error occurred and record the cost - If
--json-schemawas also passed, the result actually constrained by the schema is in thestructured_outputfield;resultmay be empty, so do not read it as a structured result
Event stream output (stream-json)
claude -p "你的任务描述" --output-format stream-json --verbose --model <workhorse> --effort medium
stream-json Must be paired with --verbose, otherwise the CLI will report an error directly. Current common events:
{"type":"system","subtype":"init","session_id":"bb6067a9-..."}
{"type":"assistant","message":{"content":[{"type":"text","text":"OK"}]}}
{"type":"result","subtype":"success","result":"OK","session_id":"bb6067a9-..."}
- Automation scripts usually use the last
type == "result"as the final result type == "assistant"is better suited for getting the complete reply after completion, not as a stable mid-stream incremental entry pointsystem/ hook / rate-limit events are normal noise; do not treat them as the final answersystem/initincludes startup metadata such as model, tools, plugins, and plugin_errors; when a script wants to verify whether plugins actually loaded successfully, this event is the most useful
If you need token-level incremental text, append --include-partial-messages, and parse type == "stream_event" and event.delta.type == "text_delta" events.
Continue a specified session
claude -p "后续提问" --output-format json --model <workhorse> --effort medium --resume "session_id"
Continue the most recent session (shortcut)
claude -p "后续提问" --output-format json --model <workhorse> --effort medium --continue
--continueautomatically continues the most recent session in the current directory- When an explicit
session_idhas already been saved, or when more stable script behavior is needed, prefer using--resume
Piped input / stdin
cat logs.txt | claude -p "Explain the failure in these logs" --output-format json --model <workhorse> --effort low
- Suitable for feeding logs, long text, and intermediate artifacts being generated directly to a child Claude Code
- If the upper-layer tool itself outputs
stream-json, then consider configuring--input-format stream-json
⚠️ --no-session-persistence: The session cannot be recovered
After adding --no-session-persistence , this sessionwill not be written to disk, so afterward itcannot be recovered by --resume or --continue recovery. Use it only in the following scenarios:
- One-off quick Q&A where you are sure there will be no follow-up questions
- Temporary calls in CI / scripts to avoid polluting the session list
- Sensitive tasks where you do not want records left locally
As long as follow-up questions may be needed later, do not add --no-session-persistence。
claude CLI parameters
Output and Results
| Flag | Description |
|---|---|
-p, --print |
Non-interactive mode;json / stream-json output depends on it |
--output-format FORMAT |
text(default) / json / stream-json |
--verbose |
Turn on verbose mode;stream-json is required |
--include-partial-messages |
in stream-json output partial message chunks |
--include-hook-events |
in stream-json include complete hook lifecycle events |
--json-schema SCHEMA |
Constrain structured output with JSON Schema |
Session Management
| Flag | Description |
|---|---|
-r, --resume SESSION_OR_NAME |
Resume the specified session ID or session name |
-c, --continue |
Resume the most recent session in the current directory |
--fork-session |
Fork a new session on resume / continue |
--from-pr NUMBER |
Resume the session associated with the specified PR |
--session-id UUID |
Explicitly specify the session ID |
-n, --name NAME |
Set a display name for the session; can later --resume <name> |
--no-session-persistence |
Do not persist the session |
Input and Streaming Integration
| Flag | Description |
|---|---|
--input-format FORMAT |
text(default) / stream-json; for programmatic input from upstream |
--replay-user-messages |
In stream-json input mode, replay user messages to stdout |
--permission-prompt-tool TOOL |
In non-interactive mode, delegate permission confirmation to the specified MCP tool |
Permissions and Tool Boundaries
| Flag | Description |
|---|---|
--permission-mode MODE |
default / acceptEdits / plan / auto / dontAsk / bypassPermissions |
--allowedTools TOOLS |
Allowlist specific tools, such as "Read,Grep,Glob,Bash(git *)" |
--disallowedTools TOOLS |
Disable specific tools |
--tools TOOLS |
Specify the available tool set;"" disables all,"default" uses all |
--dangerously-skip-permissions |
Skip all permission checks directly; extremely high risk |
--allow-dangerously-skip-permissions |
Allow "skip permission checks" to be enabled as an optional mode within the session |
acceptEdits is suitable for scripted fixes where "file writes are allowed, but you do not want to open up all Bash / network capabilities at once."dontAsk is better suited for tightly locked-down CI: any action not in the allowlist or read-only command set fails directly instead of entering interactive confirmation.
Model and Context
| Flag | Description |
|---|---|
--model MODEL |
Specify the model; explicitly passing it is recommended |
--effort LEVEL |
Reasoning effort:low / medium / high / xhigh / max |
--max-turns N |
Limit the number of agentic turns; set boundaries for automated sub-sessions |
--max-budget-usd AMOUNT |
Maximum spend limit |
--fallback-model MODEL |
--print automatic fallback model when overloaded in mode |
--system-prompt PROMPT |
Replace the default system prompt |
--append-system-prompt PROMPT |
Append to the system prompt |
--system-prompt-file FILE |
Load the system prompt from a file |
--append-system-prompt-file FILE |
Append the system prompt from a file |
--exclude-dynamic-system-prompt-sections |
Move dynamic information such as cwd / environment / git status out of the system prompt to improve cross-machine cache reuse |
--add-dir DIR |
Add additional accessible directories |
--mcp-config CONFIG |
Load MCP configuration (file or JSON string) |
--settings FILE_OR_JSON |
Load additional settings |
Runtime Environment
| Flag | Description |
|---|---|
-w, --worktree [NAME] |
Create an isolated worktree for the task |
--tmux |
With --worktree create a tmux / iTerm pane session |
--bare |
Recommended clean-room mode for scripted / SDK: skip hooks, skills, plugins, MCP, auto memory, and CLAUDE.md auto-discovery |
--disable-slash-commands |
Disable all skills / slash commands |
--agent AGENT |
Specify the agent used by the current session |
--agents JSON |
Inject custom agents definitions |
--plugin-dir PATH |
Load an additional plugin directory for the current session |
--chrome / --no-chrome |
Turn the Claude in Chrome integration on or off |
--bare applies only the flags you explicitly pass; it does not read local OAuth / keychain. When Anthropic authentication is needed, usually switch to ANTHROPIC_API_KEY or in --settings provide apiKeyHelper。
Multi-turn Conversation
- First
claude -p ... --output-format jsonGetsession_id - For follow-up questions use
claude -p ... --resume "session_id", or in the same directory use--continue - Automatically track
session_id, users do not need to manually understand the full protocol - Create a separate session for each task; multiple
session_iddo not interfere with each other
Model and effort selection
Explicitly specify based on task complexity --model and --effort:
| Task complexity | model | effort | Applicable scenarios |
|---|---|---|---|
| High | <flagship> |
high |
Architecture design, complex refactoring, multi-file coding |
| Medium | <workhorse> |
medium |
Single-file feature implementation, bug fixing, general analysis |
| Low | <workhorse> |
low |
Simple Q&A, code explanation, quick follow-up questions |
In the documentation,
<flagship>/<workhorse>is a placeholder, not a real model ID. Tiers are resolved at dispatch time according to the platform's current model lineup; do not hardcode model names—when model generations change, the tier semantics remain unchanged: flagship → the platform's current strongest reasoning model; workhorse → a model one tier below flagship with better cost-effectiveness. For actual values useclaude --helpor the current alias in the platform announcement (e.g.,fable/opus/sonnet).
Recommended parameter combinations
| Scenario | model | effort | permission-mode | Other flags |
|---|---|---|---|---|
| Complex coding | <flagship> |
high |
bypassPermissions |
--output-format json |
| General coding | <workhorse> |
medium |
bypassPermissions |
--output-format json |
| Scripted small fixes | <workhorse> |
medium |
acceptEdits |
--bare --allowedTools "Bash,Read,Edit" |
| Code review | <workhorse> |
medium |
plan |
--allowedTools "Read,Grep,Glob,Bash(git *)" |
| Locked-down CI checks | <workhorse> |
medium |
dontAsk |
--bare --allowedTools "Read,Grep,Glob" |
| Quick Q&A | <workhorse> |
low |
default |
--no-session-persistence(⚠️ unrecoverable) |
| Toolchain consuming event stream | <workhorse> |
medium |
Depends on the task | --output-format stream-json --verbose |
| Bounded automated sub-sessions | <workhorse> |
medium |
Depends on the task | --max-turns 3 --max-budget-usd 1 |
| Clean subprocess / prompt experiments | <workhorse> |
medium |
default or plan |
--bare |
| Structured output | <workhorse> |
medium |
default |
--json-schema schema.json |
| Isolated execution | <flagship> |
high |
bypassPermissions |
--worktree feature-x |
Usage rules
- Automated calls use by default
-p+--output-format json: get a stable single-object result; only switch when an event stream is truly neededstream-json stream-jsonalways paired with--verbose: this is a hard constraint of the CLI, not a suggestion- Always explicitly pass
--modeland--effort: avoid default value drift - Always run in the target project directory: first
cd /path/to/project, do not let Claude execute in the wrong repository - For coding tasks use
bypassPermissions, for review tasks useplan+ tool whitelist:planis not a hard sandbox, still configure--allowedTools - Keep the conversation continuous: as long as follow-up questions are possible, do not add
--no-session-persistence --continueis suitable for "continue the previous task"; when you need traceable script behavior, cross-directory stability, or explicit session binding, use--resume- When isolated modification is needed, prefer
--worktree: more stable than manually switching directories, and better suited for independent execution by sub-agents - When reporting results to the user, prefer taking the
resultfield: supplement withsession_id, cost and token usage when necessary - If only reading is allowed, do not rely only on the prompt: also add
plan, a tool whitelist, or--toolsrestrictions to prevent the subprocess from accidentally writing files - When a more controllable automation boundary is needed, add
--max-turns: avoid sub-sessions running too deep on ambiguous tasks - scripted / SDK calls default to preferring
--bare: this way localCLAUDE.md, skills, plugins, MCP and auto memory are not inherited, and the results are more reproducible -pdo not rely on/commitor similar interactive slash commands in this mode: describe the task directly in natural language; when necessary, explicitly give--append-system-prompt、--allowedToolsor--json-schema
Prompt References
Load the corresponding reference on demand by task type, don't stuff all default prompts into the main context at once:
- Coding / diagnosing / planning / narrow fix: read references/task-prompt-recipes.md
- Code review / adversarial review / test gap check: read references/review-prompt-recipes.md
- Delegated handoff / independent worker / continuing the same session: read references/delegation-prompt-recipes.md
These references provide default prompt templates that can be reused directly or lightly modified; prefer copying the closest template, then delete the blocks you don't need.
Examples
Coding task
cd /path/to/project && claude -p \
"Implement a REST API for TODO items with CRUD endpoints. Use Express.js." \
--output-format json \
--permission-mode bypassPermissions \
--model <flagship> \
--effort high
The returned result is a natural-language summary,session_id is used for follow-up questions.
Continue the most recent session
cd /path/to/project && claude -p \
"Continue from the current state. Add unit tests for the new endpoints and report only the final outcome." \
--output-format json \
--model <workhorse> \
--effort medium \
--continue
Suitable for "continue that task from just now" scenarios where you don't want to manually save session_id .
Event stream output to an upper-layer tool
cd /path/to/project && claude -p \
"Review the current diff and stream back progress plus a final verdict." \
--output-format stream-json \
--verbose \
--permission-mode plan \
--allowedTools "Read,Grep,Glob,Bash(git *)" \
--model <workhorse> \
--effort medium
Suitable for an upper-layer agent or script: read assistant / system events in the middle, and read result。
Streaming extraction of plain text increments
claude -p "Write a short changelog entry" \
--output-format stream-json \
--verbose \
--include-partial-messages | \
jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'
Suitable when your own upper-layer UI or script only wants to consume continuous text tokens and doesn't want to handle the entire event stream itself.
Pipe in logs or long text
cat logs.txt | claude -p \
"Explain the failure in these logs. Return root cause, evidence, and the smallest safe next step." \
--output-format json \
--model <workhorse> \
--effort low
Suitable for streaming a large chunk of context the parent process already has directly to the child Claude Code, instead of writing it to a temporary prompt.
Structured output to another tool
claude -p \
"Extract the main exported function names from src/auth.ts." \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' | \
jq '.structured_output'
Suitable when an upper-layer agent, CI or script only consumes structured fields; note that the result actually constrained by the schema is in structured_output, not result。
Code review
cd /path/to/project && claude -p \
"Review git diff HEAD~1. Focus on correctness, regression risk, and missing tests. Findings first." \
--output-format json \
--permission-mode plan \
--allowedTools "Read,Grep,Glob,Bash(git *)" \
--model <workhorse> \
--effort medium
Execute in an isolated worktree
cd /path/to/project && claude -p \
"Implement the fix in an isolated worktree, run the most relevant tests, and summarize the final result." \
--output-format json \
--permission-mode bypassPermissions \
--model <flagship> \
--effort high \
--worktree fix-login-timeout
Suitable for having the child Claude Code independently complete a piece of implementation without directly polluting the current working tree.
Clean child process / prompt experiment
Prerequisite: this example assumes you have already provided authentication via ANTHROPIC_API_KEY or the --settings in apiKeyHelper .--bare does not read the local OAuth / keychain, so an environment that directly relies on claude auth login will report Not logged in。
cd /path/to/project && ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" claude -p \
"Review src/auth.ts for contract drift only." \
--output-format json \
--permission-mode plan \
--allowedTools "Read,Grep,Glob" \
--model <workhorse> \
--effort medium \
--bare \
--max-turns 3
Suitable for more reproducible scripted calls, when you don't want local CLAUDE.md, plugins, skills or auto memory to affect the output.