The CLI — Print Mode, JSON Output & CI/CD
The final chapter is the manual for the binary itself: every way to invoke claude, the flags that shape a session before it starts, print mode as a scriptable SDK, JSON output you can pipe straight into jq, and the patterns that turn Claude Code into CI/CD infrastructure.
One command, three lanes — and output formats belong to only one of them
claude "explain this project"
cat logs.txt | claude -p "explain"
claude -r "auth-refactor"
Since v2.1.113, "claude" launches a native binary — npm is just the delivery truck
The CLI now runs as a native per-platform binary (macOS, Linux, Windows), fetched via optional npm dependencies and matched to your OS and architecture at install time. The user-facing install is unchanged: npm install -g @anthropic-ai/claude-code remains the recommended path.
| downloads.claude.ai | Download host (v2.1.116+) — native-binary artifacts ship from https://downloads.claude.ai/claude-code-releases |
| proxy allowlists | Corporate networks must add downloads.claude.ai to egress rules — environments that only allowlisted storage.googleapis.com or the npm registry will see claude update and fresh installs fail |
| claude install 2.1.131 | Pin a specific native-binary version — accepts stable, latest, or an explicit version string |
| JS bundle | Still produced for Windows and pinned environments — those installs keep Glob/Grep as first-class tools (the native-build difference lands on section 08) |
Nine invocations cover the daily loop — interactive, print, piped, and resumed
| claude | Start the interactive REPL |
| claude "query" | Start the REPL with an initial prompt already submitted |
| claude -p "query" | Print mode — answer the query, then exit |
| cat file | claude -p "query" | Process piped content — cat logs.txt | claude -p "explain" |
| claude -c | Continue the most recent conversation |
| claude -c -p "query" | Continue in print mode — prior context, single-shot answer |
| claude -r "‹session›" "query" | Resume a session by ID or name with a new prompt |
| claude update | Update to the latest version |
| /doctor | Diagnose installation, config, and plugin health from inside the REPL — since v2.1.116 it opens while Claude is responding, shows inline status icons, and the f keypress auto-fixes detected issues |
The CLI grew a toolbelt — plugins, auth, state purging, and headless review are subcommands now
| claude mcp · mcp serve | Configure MCP servers — or run Claude Code itself as an MCP server (Chapter 5) |
| claude plugin init ‹name› | Scaffold a new plugin in .claude/skills — auto-loads, no marketplace required (v2.1.157+); plus install/enable/disable, tag ‹version› for validated release tags (v2.1.118+), and prune to drop orphaned auto-installed dependencies (v2.1.121+) |
| claude project purge [path] | Delete all local state for a project — transcripts, tasks, debug logs, file-edit history, prompt history, the ~/.claude.json entry. --dry-run previews, -y skips confirmation, -i confirms each item, --all walks every project (v2.1.126+) |
| claude ultrareview [target] | Run /ultrareview non-interactively — findings to stdout, exit 0 clean / 1 findings; --json for raw payload, --timeout ‹min› overrides the 30-minute default (v2.1.120+) |
| claude auth login · logout · status | login supports --email/--sso and, since v2.1.126, accepts the OAuth code pasted into the terminal when the browser callback can't reach localhost (WSL2, SSH, containers); status exits 0 logged-in / 1 not |
| claude agents | Open the multi-session Agent View (Research Preview, v2.1.139+) — full treatment on section 15 |
| claude remote-control · auto-mode defaults | Start the Remote Control server (Chapter 9B) · print auto-mode default rules as JSON (Chapter 9A) |
Most flags are chapters you've already read — the CLI is where they all meet
| Identity & place | |
| -n, --name · -v · -w · --tmux | Session name · version · isolated git worktree (Ch. 4) · tmux session for it |
| --add-dir ../apps ../lib | Extra working directories |
| Config sources | |
| --settings · --setting-sources | Settings from file/JSON · which scopes load; /config changes persist to ~/.claude/settings.json since v2.1.119 |
| --mcp-config · --strict-mcp-config | MCP servers from JSON · only those servers (Ch. 5) |
| --plugin-dir ./my-plugin | Plugins from a directory, repeatable (Ch. 7) |
| Surfaces (Ch. 9B) | |
| --remote · --rc · --teleport | Web session on claude.ai · Remote Control · pull a web session local |
| --from-pr · --channels · --chrome · --ide | PR-linked sessions (GitHub, GitLab, Bitbucket since v2.1.119) · channel plugins · browser · IDE |
| Stripping things out | |
| --bare | Minimal mode — skips hooks, skills, plugins, MCP, auto memory, CLAUDE.md |
| --disable-slash-commands · --no-session-persistence | No skills or slash commands · don't save the session (print mode) |
| --exclude-dynamic-system-prompt-sections | Drop dynamic prompt sections for better cache hits |
| Lifecycle & debug | |
| --init / --init-only · --maintenance | Run init hooks · run maintenance hooks and exit |
| --debug "api,mcp" · --verbose · --enable-lsp-logging · --betas | Filtered debug · verbose · LSP logs · beta API headers |
Pick the model per invocation — and give unattended runs a fallback
| --model opus | Short name (sonnet, opus, haiku) or full ID like claude-sonnet-4-6-20250929 |
| --model opusplan | The split alias — Opus plans, Sonnet executes |
| --fallback-model sonnet | Automatic fallback when overloaded — the reliability flag for print-mode automation |
| --agent my-custom-agent | Pick a named agent for the session |
| --effort xhigh | Thinking effort: low → medium → high → xhigh → max (section 16) |
# match the model to the task claude --model opus "design a caching strategy" claude --model haiku -p "format this JSON" # reliability for unattended runs claude -p --model opus \ --fallback-model sonnet "analyze architecture"
Gateway model discovery (v2.1.129+, opt-in): when ANTHROPIC_BASE_URL points at a gateway, set CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1 to populate /model from its /v1/models endpoint. Opt-in because discovery can surface models you're not entitled to — v2.1.126 made it implicit and that was reverted.
Three flags rewrite who Claude is — but only two of them work interactively
| --system-prompt | Replaces the entire default system prompt — interactive ✅ · print ✅ |
| --system-prompt-file | Replaces with a file's contents — interactive ❌ · print only ✅ |
| --append-system-prompt | Appends to the default prompt — interactive ✅ · print ✅ |
Replace when you want a clean persona with none of the defaults; append when you want the defaults plus house rules.
# complete custom persona claude --system-prompt "You are a senior security engineer. Focus on vulnerabilities." # keep defaults, add house rules claude --append-system-prompt "Always include unit tests with code examples" # long prompt from a file — print mode only claude -p --system-prompt-file \ ./prompts/code-reviewer.txt "review main.py"
Restrict, allow, block — three different verbs, three different flags
| --tools "Bash,Edit,Read" | Restrict which built-in tools exist at all |
| --allowedTools | Allow without prompting — "Bash(git log:*)" "Read" |
| --disallowedTools | Remove from context — "Bash(rm:*)" "Edit" |
| --permission-mode plan | Begin in a specific permission mode (Ch. 9A) |
| --permission-prompt-tool | Delegate permission prompts to an MCP tool — the headless answer to "who clicks yes?" |
| --dangerously-skip-permissions | Skip all prompts — the name is the warning |
# read-only review claude --permission-mode plan "review this codebase" # safe tools only, no prompts for git reads claude --tools "Read,Grep,Glob" -p "find TODOs" claude --allowedTools "Bash(git status:*)" "Bash(git log:*)"
- Glob/Grep footnote (v2.1.113+): native builds run them as embedded bfs/ugrep via Bash — but keep writing Glob/Grep in configs; the substitution is transparent on every platform
- PowerShell (v2.1.119): auto-approve with the same matcher syntax — PowerShell(Get-ChildItem:*)
- Resume fix (v2.1.132+): --permission-mode is now honored on --continue/--resume — older versions silently dropped it, downgrading plan-mode sessions
JSON output plus a schema turns Claude into a typed function
| --output-format | text (default) · json · stream-json — print mode |
| --input-format | text · stream-json — print mode |
| --include-partial-messages | Streaming events as they arrive — requires stream-json |
| --json-schema '{…}' | Validated JSON matching your schema — structure is enforced, not requested |
| --max-budget-usd 5.00 | Hard spend cap for a print-mode run |
| --verbose | Verbose logging |
# JSON for programmatic use claude -p --output-format json "list all functions in main.py" # streaming JSON for real-time processing claude -p --output-format stream-json "generate a long report" # schema-validated structure claude -p --json-schema '{"type":"object", "properties":{"bugs":{"type":"array"}}}' \ "find bugs and return as JSON"
jq is the other half of the API — filter, reshape, and gate on Claude's JSON
# extract a field · filter an array claude -p --output-format json "analyze this code" | jq '.result' … "list issues" | jq -r '.issues[] | select(.severity=="high")' # pick several fields (object construction) … "describe the project" | jq '{name, version, description}' # reshape · CSV · count … | jq 'map({title: .title, priority: .priority})' … | jq -r '.functions[] | [.name, .lineCount] | @csv' … | jq '.todos | length'
# gate a script on Claude's verdict RESULT=$(claude -p --output-format json \ "is this code secure? answer with {secure: boolean, issues: []}" < code.py) if echo "$RESULT" | jq -e '.secure == false' > /dev/null; then echo "Security issues found!" echo "$RESULT" | jq '.issues[]' fi # conditional verdicts … | jq 'if .vulnerabilities | length > 0 then "UNSAFE" else "SAFE" end'
Heads-up: the source guide prints the multi-field example as .{name, …} — that's not valid jq. Object construction is written {…} with no leading dot, as shown here.
In CI, flags are the guardrails — turns, budget, schema, and an exit code to gate the merge
exit 1 → block
Anything that flows through a pipe can flow through Claude
Logs & history in, analysis out
tail -1000 /var/log/app/error.log | \ claude -p "summarize these errors, suggest fixes" cat access.log | claude -p "identify suspicious access patterns" git log --oneline -50 | claude -p "summarize recent development activity" grep -r "TODO" src/ | claude -p "prioritize these TODOs by importance"
Batch processing with loops
# summarize every file — haiku keeps it cheap for file in src/*.ts; do claude -p --model haiku "summarize this file: $(cat $file)" >> summaries.md done # generate tests per module for module in $(ls src/modules/); do claude -p "generate unit tests for src/modules/$module" > "tests/$module.test.ts" done
Same idea with find … -exec for batch code review across a tree.
Sessions are branches — name them, fork them, and purge the residue when you're done
| claude -c | Continue the most recent conversation |
| claude -r "feature-auth" "…" | Resume by name or ID, appending a new prompt |
| --session-id "550e8400-…" | Pin a specific session UUID |
| --resume abc123 --fork-session | Branch — a new independent session; the original remains unchanged |
# parallel threads of work claude -r "feature-auth" "add password reset" claude -r "feature-payments" "continue Stripe work" # fork to explore without risk claude --resume feature-auth --fork-session \ "try OAuth instead"
Why fork?
- Try alternative implementations without losing the original
- Experiment with different approaches in parallel
- Branch variations from successful work
- Test breaking changes without touching the main session
Cleanup: claude project purge
When a project ends, its local state lingers — transcripts, tasks, debug logs, edit history, prompt history. claude project purge ~/work/repo --dry-run previews the deletion; --yes executes it; --all --interactive walks every project on the machine (v2.1.126+).
--agents defines a team inline — and it outranks project and user definitions for the session
claude --agents '{
"code-reviewer": {
"description": "Expert code reviewer. Use
proactively after code changes.", ← required
"prompt": "You are a senior code reviewer…",
← required
"tools": ["Read","Grep","Glob","Bash"],
← optional · inherits all if omitted
"model": "sonnet" ← optional · sonnet|opus|haiku
}
}' "review the auth module"
Or load from a file: claude --agents "$(cat ~/.claude/agents.json)" — and combine with -p/--model for scripted runs.
Priority when names collide
| 1 | CLI-defined (--agents) — session-specific, overrides everything below |
| 2 | Project-level (.claude/agents/) — current project |
| 3 | User-level (~/.claude/agents/) — all projects |
The team-file pattern
Keep a shared agents.json defining your reviewer (opus), documenter (sonnet/haiku), and refactorer (with a restricted tools list) — everyone on the team gets the same specialists with one flag. The full priority table, including plugin-level agents, is in the Chapter 4 deck.
claude agents replaces the wall of terminal tabs — one list, every session, its status
A Research Preview (v2.1.139+): one view of every Claude Code session on the machine — running, blocked on you, done. Built for background agents, scheduled tasks, and --bg-launched sessions.
- Dispatch from the view or via claude --bg ‹prompt› — with the same configuration flags as claude itself
- --json (v2.1.145) prints the list as machine-readable JSON — status bars, session pickers, tmux integrations
- Ctrl+T pins a session (v2.1.147): stays alive when idle, restarted in place for updates, shed under memory pressure last
- In an attached session, Shift+Tab cycles permission modes incl. auto (v2.1.143); finished sessions with an open shell move to Completed (v2.1.141 fix)
Dispatch flags
| --cwd ‹path› | Scope the list / new session to a directory (v2.1.141) |
| --add-dir · --settings · --mcp-config · --plugin-dir | Per-dispatch workspace, settings, MCP and plugin config (v2.1.142) |
| --permission-mode · --model · --effort | Pin the mode, model, and effort per dispatched session (v2.1.142) |
| --dangerously-skip-permissions | No prompts for the dispatched session — sandboxes only (v2.1.142) |
Scoping note: in the Agent View Ctrl+T pins; in the main session it toggles the task list.
Three models, five effort levels — and the defaults have been moving up
| Opus 4.8 | claude-opus-4-8 · 1M tokens · most capable; effort low → max, default high (v2.1.154) |
| Sonnet 4.6 | claude-sonnet-4-6 · 1M tokens · balanced; Pro/Max default effort raised medium → high in v2.1.117 |
| Haiku 4.5 | claude-haiku-4-5 · 200K tokens · fastest; no effort levels |
Fast Mode: as of v2.1.154, /fast runs Opus 4.8 as a research preview — about 2× the standard rate for ~2.5× the output speed. The old Opus-4.6 override env var was deprecated and removed 2026-06-01; to get fast mode on 4.6, switch model first, then /fast on.
Effort: low ○ → medium ◐ → high ● → xhigh → max
- Default is high on Opus 4.8, Opus 4.6 and Sonnet 4.6 — xhigh on Opus 4.7
- xhigh needs Opus 4.8/4.7 · max works on Opus 4.8/4.7/4.6 and Sonnet 4.6 (session-only)
- Set it three ways: --effort high · /effort high · CLAUDE_CODE_EFFORT_LEVEL=high
- "ultrathink" in a prompt activates deep reasoning; the /effort menu's ultracode is not an effort level — it sends xhigh and has Claude orchestrate dynamic workflows
If a behavior exists, an environment variable probably governs it — ~45 in this chapter alone
| Auth, models & reasoning | |
| ANTHROPIC_API_KEY · ANTHROPIC_MODEL | Authentication · model override (+ per-tier Opus/Sonnet/Haiku defaults) |
| MAX_THINKING_TOKENS · CLAUDE_CODE_EFFORT_LEVEL | Thinking budget · effort level |
| Feature kill-switches | |
| CLAUDE_CODE_DISABLE_* | AUTO_MEMORY · BACKGROUND_TASKS · CRON · GIT_INSTRUCTIONS · 1M_CONTEXT · ALTERNATE_SCREEN (pipe-friendly scrollback, v2.1.132+) |
| DISABLE_UPDATES | Blocks all update paths incl. manual — stricter than DISABLE_AUTOUPDATER (v2.1.118+) |
| Tasks & agents | |
| …ENABLE_TASKS · …TASK_LIST_ID | Task list · named task dir shared across sessions |
| …SUBAGENT_MODEL · …EXPERIMENTAL_AGENT_TEAMS · …FORK_SUBAGENT | Subagent model · agent teams · forked subagents on Bedrock/Vertex/Foundry |
| Gateways & platforms | |
| ENABLE_TOOL_SEARCH | Off by default on Vertex AI (v2.1.119+) — opt in with =true; on by default on the direct API |
| …GATEWAY_MODEL_DISCOVERY · …BEDROCK_SERVICE_TIER · …ENABLE_AUTO_MODE | Gateway /v1/models · Bedrock tier · auto mode on Bedrock/Vertex/Foundry (v2.1.158+) |
| …PERFORCE_MODE=1 | Files read-only by default for Perforce/P4 workflows |
| Observability & correlation | |
| CLAUDE_CODE_SESSION_ID | Set in every Bash subprocess; equals the hook-input session_id (v2.1.132+) |
| OTEL_LOG_TOOL_DETAILS · AI_AGENT | Unredact MCP/command names in OTel · subprocess attribution for external CLIs |
| Limits & tuning | |
| MAX_MCP_OUTPUT_TOKENS · …AUTOCOMPACT_PCT_OVERRIDE · …STREAM_IDLE_TIMEOUT_MS | MCP output cap · compaction trigger point · stream idle timeout |
Eight flag combinations are the working vocabulary — and five failures cover most bad days
Combinations to memorize
| Quick code review | cat file | claude -p "review" |
| Structured output | claude -p --output-format json "query" |
| Safe exploration | claude --permission-mode plan |
| Autonomous + safety | claude --enable-auto-mode --permission-mode auto |
| CI/CD integration | claude -p --max-turns 3 --output-format json |
| Budget-capped run | claude -p --max-budget-usd 2.00 "analyze code" |
| Resume work | claude -r "session-name" |
| Minimal mode | claude --bare "quick query" |
When it breaks
| command not found | Install globally · check PATH for npm's bin · try npx claude |
| auth failed | export ANTHROPIC_API_KEY=… · check credits and model permissions |
| session not found | List sessions for the right name/ID · sessions can expire after inactivity · -c grabs the most recent |
| malformed JSON | Use --output-format json — not just asking for JSON in the prompt — and --json-schema to enforce structure |
| permission denied | Check --permission-mode, then the allow/disallow lists; --dangerously-skip-permissions only with caution |
Quality-of-life since v2.1.112: an Auto theme matches your terminal's light/dark, and read-only Bash/Glob permission prompts got quieter.
The CLI is where Claude Code stops being an app and becomes infrastructure
One binary (native since v2.1.113), three lanes: the REPL for conversation, print mode for single-shot scriptable calls, resume for continuity — with forks for branches and claude project purge for the residue. The flags compose: --model + --fallback-model for reliability, three system-prompt flags (one print-only), three permission verbs, and --output-format json + --json-schema + jq to turn Claude into a typed function with an exit code. In CI, the guardrails ride along — --max-turns, --max-budget-usd, ultrareview as a drop-in merge gate. --agents defines a team inline; claude agents supervises the fleet; ~45 env vars tune everything underneath.
And that closes the series: slash commands → memory → skills → subagents → MCP → hooks → plugins → checkpoints → autonomy & surfaces → the CLI — every layer you've configured in chapters 1–9 is reachable from the command on this page.