Chapter 10 · CLI Reference

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.

01 · The Map

One command, three lanes — and output formats belong to only one of them

claude
claude "explain this project"
Interactive REPL (default)
Multi-turn conversation · tab completion · history · slash commands — everything in chapters 1–9 lives here
Claude API → output
Interactive / resume
Rendered transcript in the terminal
Print mode only
text · json · stream-json → stdout, ready to pipe
claude -p "query"
cat logs.txt | claude -p "explain"
Print mode (the SDK)
Single query, then exit — scriptable, pipeable, the lane this chapter is really about
claude -c  most recent
claude -r "auth-refactor"
Session resume
Loads prior context first, then continues — interactively, or in print mode with -c -p
The CLI is the front door every chapter has been walking through. What's new here: the second lane — -p turns the same engine into a single-shot, pipeable function call.
02 · Runtime & Packaging

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.aiDownload host (v2.1.116+) — native-binary artifacts ship from https://downloads.claude.ai/claude-code-releases
proxy allowlistsCorporate 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.131Pin a specific native-binary version — accepts stable, latest, or an explicit version string
JS bundleStill produced for Windows and pinned environments — those installs keep Glob/Grep as first-class tools (the native-build difference lands on section 08)
If claude update suddenly fails on a corporate network, it's almost always the new download host missing from the proxy allowlist — not a broken install.
03 · Daily Commands

Nine invocations cover the daily loop — interactive, print, piped, and resumed

claudeStart 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 -cContinue 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 updateUpdate to the latest version
/doctorDiagnose 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
Print mode chains like any Unix tool: claude -p "list todos" | grep "URGENT"stdin in, stdout out, composable on both ends.
04 · The Toolbelt

The CLI grew a toolbelt — plugins, auth, state purging, and headless review are subcommands now

claude mcp · mcp serveConfigure 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 · statuslogin 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 agentsOpen the multi-session Agent View (Research Preview, v2.1.139+) — full treatment on section 15
claude remote-control · auto-mode defaultsStart the Remote Control server (Chapter 9B) · print auto-mode default rules as JSON (Chapter 9A)
The pattern: anything you'd do around a session — install, authenticate, release, clean up, review — now has a scriptable subcommand, with exit codes where automation needs them.
05 · Core Flags

Most flags are chapters you've already read — the CLI is where they all meet

Identity & place
-n, --name · -v · -w · --tmuxSession name · version · isolated git worktree (Ch. 4) · tmux session for it
--add-dir ../apps ../libExtra working directories
Config sources
--settings · --setting-sourcesSettings from file/JSON · which scopes load; /config changes persist to ~/.claude/settings.json since v2.1.119
--mcp-config · --strict-mcp-configMCP servers from JSON · only those servers (Ch. 5)
--plugin-dir ./my-pluginPlugins from a directory, repeatable (Ch. 7)
Surfaces (Ch. 9B)
--remote · --rc · --teleportWeb session on claude.ai · Remote Control · pull a web session local
--from-pr · --channels · --chrome · --idePR-linked sessions (GitHub, GitLab, Bitbucket since v2.1.119) · channel plugins · browser · IDE
Stripping things out
--bareMinimal mode — skips hooks, skills, plugins, MCP, auto memory, CLAUDE.md
--disable-slash-commands · --no-session-persistenceNo skills or slash commands · don't save the session (print mode)
--exclude-dynamic-system-prompt-sectionsDrop dynamic prompt sections for better cache hits
Lifecycle & debug
--init / --init-only · --maintenanceRun init hooks · run maintenance hooks and exit
--debug "api,mcp" · --verbose · --enable-lsp-logging · --betasFiltered debug · verbose · LSP logs · beta API headers
Reading rule for this chapter: a flag you don't recognize is new material; a flag you do recognize is a cross-reference — the CLI table is the index of the whole series.
06 · Model Selection

Pick the model per invocation — and give unattended runs a fallback

--model opusShort name (sonnet, opus, haiku) or full ID like claude-sonnet-4-6-20250929
--model opusplanThe split alias — Opus plans, Sonnet executes
--fallback-model sonnetAutomatic fallback when overloaded — the reliability flag for print-mode automation
--agent my-custom-agentPick a named agent for the session
--effort xhighThinking 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.

The flag pair that matters in scripts: --model picks capability, --fallback-model buys resilience when the first choice is overloaded — there's no human at the keyboard to retry.
07 · System Prompts

Three flags rewrite who Claude is — but only two of them work interactively

--system-promptReplaces the entire default system prompt — interactive ✅ · print ✅
--system-prompt-fileReplaces with a file's contents — interactive ❌ · print only
--append-system-promptAppends 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"
The trap is the file flag: --system-prompt-file is print-mode only — in an interactive session, use --system-prompt or --append-system-prompt instead.
08 · Tools & Permissions

Restrict, allow, block — three different verbs, three different flags

--tools "Bash,Edit,Read"Restrict which built-in tools exist at all
--allowedToolsAllow without prompting"Bash(git log:*)" "Read"
--disallowedToolsRemove from context"Bash(rm:*)" "Edit"
--permission-mode planBegin in a specific permission mode (Ch. 9A)
--permission-prompt-toolDelegate permission prompts to an MCP tool — the headless answer to "who clicks yes?"
--dangerously-skip-permissionsSkip 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
Keep the verbs straight: --tools shrinks the toolbox, --allowedTools pre-answers the prompt, --disallowedTools deletes the option entirely.
09 · Output & Format

JSON output plus a schema turns Claude into a typed function

--output-formattext (default) · json · stream-json — print mode
--input-formattext · stream-json — print mode
--include-partial-messagesStreaming events as they arrive — requires stream-json
--json-schema '{…}'Validated JSON matching your schema — structure is enforced, not requested
--max-budget-usd 5.00Hard spend cap for a print-mode run
--verboseVerbose 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"
The escalation ladder: text for humans → json for scripts → stream-json for real-time consumers → --json-schema when downstream code must get the shape it expects.
10 · jq Integration

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.

The pattern worth stealing is jq -e: it sets the exit code from the query result, so a Claude judgment becomes an if branch in any shell script.
11 · CI/CD Integration

In CI, flags are the guardrails — turns, budget, schema, and an exit code to gate the merge

PR / checkout
GitHub Actions, Jenkins — npm install the CLI, set ANTHROPIC_API_KEY from secrets
claude -p "Review this PR…"
One prompt states the rubric: security · performance · quality
--output-format json
review.json
Structured findings — an 'issues' array, not prose
jq / github-script
Parse and post review comments
Gate
exit 0 → merge
exit 1 → block
--max-turns 1 · caps the loop--max-budget-usd · caps spend
Or the one-liner claude ultrareview ${PR_NUMBER} --json > review.json — a drop-in PR gate since v2.1.120: exit 0 on a clean review, 1 when findings are reported; --timeout ‹minutes› overrides the 30-minute default.
Unattended runs get no second chances — so every CI invocation carries its own limits: --max-turns against runaway loops, --max-budget-usd against runaway spend, a schema against malformed output.
12 · Piping & Batch

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.

Two disciplines make batch work pay: pick the cheap model (--model haiku) for high-volume passes, and redirect to files so the loop's output is reviewable, not ephemeral.
13 · Session Management

Sessions are branches — name them, fork them, and purge the residue when you're done

claude -cContinue 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-sessionBranch — 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+).

One session per task is the hygiene rule — and --fork-session is its escape hatch: branch the timeline instead of contaminating it.
14 · Agents Configuration

--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

1CLI-defined (--agents) — session-specific, overrides everything below
2Project-level (.claude/agents/) — current project
3User-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.

Same precedence instinct as everything else in the series: the closer to the invocation, the higher the priority — CLI beats project beats user.
15 · Agent View

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-dirPer-dispatch workspace, settings, MCP and plugin config (v2.1.142)
--permission-mode · --model · --effortPin the mode, model, and effort per dispatched session (v2.1.142)
--dangerously-skip-permissionsNo 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.

The mental model shift: sessions stop being terminal tabs and become a fleet you supervise — dispatch with flags, monitor by status, pin the ones that must survive.
16 · Models & Effort

Three models, five effort levels — and the defaults have been moving up

Opus 4.8claude-opus-4-8 · 1M tokens · most capable; effort low → max, default high (v2.1.154)
Sonnet 4.6claude-sonnet-4-6 · 1M tokens · balanced; Pro/Max default effort raised medium → high in v2.1.117
Haiku 4.5claude-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
Match cost to task: Haiku for volume, Sonnet for the daily loop, Opus + effort for architecture — and opusplan when you want Opus thinking at Sonnet prices for execution.
17 · Environment Variables

If a behavior exists, an environment variable probably governs it — ~45 in this chapter alone

Auth, models & reasoning
ANTHROPIC_API_KEY · ANTHROPIC_MODELAuthentication · model override (+ per-tier Opus/Sonnet/Haiku defaults)
MAX_THINKING_TOKENS · CLAUDE_CODE_EFFORT_LEVELThinking 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_UPDATESBlocks all update paths incl. manual — stricter than DISABLE_AUTOUPDATER (v2.1.118+)
Tasks & agents
…ENABLE_TASKS · …TASK_LIST_IDTask list · named task dir shared across sessions
…SUBAGENT_MODEL · …EXPERIMENTAL_AGENT_TEAMS · …FORK_SUBAGENTSubagent model · agent teams · forked subagents on Bedrock/Vertex/Foundry
Gateways & platforms
ENABLE_TOOL_SEARCHOff 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_MODEGateway /v1/models · Bedrock tier · auto mode on Bedrock/Vertex/Foundry (v2.1.158+)
…PERFORCE_MODE=1Files read-only by default for Perforce/P4 workflows
Observability & correlation
CLAUDE_CODE_SESSION_IDSet in every Bash subprocess; equals the hook-input session_id (v2.1.132+)
OTEL_LOG_TOOL_DETAILS · AI_AGENTUnredact MCP/command names in OTel · subprocess attribution for external CLIs
Limits & tuning
MAX_MCP_OUTPUT_TOKENS · …AUTOCOMPACT_PCT_OVERRIDE · …STREAM_IDLE_TIMEOUT_MSMCP output cap · compaction trigger point · stream idle timeout
Debugging prior: when Claude Code behaves oddly only in one environment, diff the env vars first — the chapter's full table is the checklist.
18 · Quick Reference

Eight flag combinations are the working vocabulary — and five failures cover most bad days

Combinations to memorize

Quick code reviewcat file | claude -p "review"
Structured outputclaude -p --output-format json "query"
Safe explorationclaude --permission-mode plan
Autonomous + safetyclaude --enable-auto-mode --permission-mode auto
CI/CD integrationclaude -p --max-turns 3 --output-format json
Budget-capped runclaude -p --max-budget-usd 2.00 "analyze code"
Resume workclaude -r "session-name"
Minimal modeclaude --bare "quick query"

When it breaks

command not foundInstall globally · check PATH for npm's bin · try npx claude
auth failedexport ANTHROPIC_API_KEY=… · check credits and model permissions
session not foundList sessions for the right name/ID · sessions can expire after inactivity · -c grabs the most recent
malformed JSONUse --output-format jsonnot just asking for JSON in the prompt — and --json-schema to enforce structure
permission deniedCheck --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 JSON one bites everyone once: asking for JSON in the prompt is a request; --output-format json is a guarantee.
19 · Recap

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.

Try it now: claude -p --output-format json "summarize this repo" | jq '.result' — one pipe, and everything this series taught is scriptable.
Sid Dani · June 2026