Claude Code CLI Flags: The Ones Worth Knowing by Job

Run it non-interactively with the print flag and set an output format. JSON returns the result, session ID, usage and cost as one object; stream-json emits each message as it happens, which is what you want for a long run. There is also a flag that validates the output against a JSON Schema you supply.
Give it a maximum number of agentic turns and a maximum dollar spend at launch. Both stop the run rather than letting it continue indefinitely. The effort flag and the model choice change the per-turn cost, and the auto-compact window decides when history is summarised, which drives most of the growth in a long session.
The bare flag skips auto-discovery of hooks, skills, commands, subagents, plugins and MCP servers, so the session starts minimal. Safe mode starts with all customisations disabled for troubleshooting. Both remove variables when something misbehaves, and both are better first steps than deleting configuration you will want back.
Use the setup-token subcommand to generate a long-lived OAuth token intended for CI and scripts, rather than putting an API key in a pipeline secret. Pair it with a turn limit and a budget ceiling so a stuck run ends quietly, and consider strict MCP config so the run only uses the servers you passed.
Run the doctor subcommand first. It prints installation and settings diagnostics, including which settings files are in play and how they resolved, which answers most configuration questions outright. Add the debug flag, which accepts a category filter, and a debug file path so the output survives past the session.

Key Takeaway
Most of the Claude Code CLI surface is worth ignoring until you need it, and about fifteen flags are worth learning on purpose. They fall into five jobs: shaping what a session is, restricting what it can reach, making non-interactive output parsable, bounding what a run may spend, and finding out why something is broken.
I spent an embarrassing amount of time debugging a session that was picking up a plugin I had disabled everywhere I could think of, before learning that one flag starts Claude Code with every customisation off. Thirty seconds of reading a reference page would have saved an hour, which is the usual arithmetic with command-line tools and the reason this post exists.
The official reference lists everything alphabetically, which is right for a reference and wrong for learning. This post groups the same surface by what you are trying to do: the subcommands people do not know exist, the flags that shape a session, making a non-interactive run readable by a script, restricting what a run may touch, spending less, and diagnosing a broken install.
Claude Code is not only the interactive session. Roughly two dozen subcommands sit alongside it, and several answer questions people usually solve by guessing. Two of these are worth committing to memory now: the diagnostics command, which prints your installation and settings state, and the token command, which mints a long-lived credential for CI so you never put a raw key in a pipeline.
claude doctor # installation + settings diagnostics
claude auth status # who am I signed in as, as JSON
claude setup-token # long-lived OAuth token for CI and scripts
claude import codex # bring config over from another agent
claude import gemini
claude project purge . # delete ALL local state for a project
claude update # update to latest
claude install [version] # install or reinstall the native binary
claude agents # agent view: monitor and dispatch
claude attach <id> # attach to a background session
claude logs <id> # recent output from one
claude stop <id> / claude respawn <id> / claude rm <id>
claude daemon status # background-session supervisor state
claude daemon stop --any
claude auto-mode defaults # print the built-in classifier as JSON
claude auto-mode reset
claude mcp / claude plugin # configure servers and plugins
claude ultrareview [target] # run a deep review non-interactivelyThese are the flags that decide what the session is before it starts, and they group cleanly into three questions: what the session is, what it can reach, and what it says. Anything you set here beats what the settings files say, which makes them the right tool for a one-off and the wrong tool for a habit — a flag you type every time belongs in a settings file instead.
# What the session IS
--model opus | sonnet | haiku | fable | <full name>
--fallback-model <model> # when the primary is unavailable
--effort low|medium|high|xhigh|max|ultracode
--agent <name> # start as a subagent definition
--agents '<json>' # define subagents inline
--permission-mode plan|acceptEdits|auto|manual|…
--name auth-refactor # findable later
--session-id <uuid>
# What it can REACH
--add-dir ../shared-lib # extra working directories
--tools Read,Edit,Bash # restrict the built-in tools
--allowedTools / --disallowedTools
--mcp-config ./servers.json # plus --strict-mcp-config to use
# ONLY those servers
--plugin-dir ./my-plugin # load a plugin for this session
--settings ./ci-settings.json # path OR inline JSON
--setting-sources user,project,local
# What it SAYS
--system-prompt / --system-prompt-file # replace it
--append-system-prompt / --append-system-prompt-file
--append-subagent-system-promptOne flag deserves a specific warning: the one that skips permission prompts entirely. It exists for containers and sandboxes where the blast radius is already bounded, and it is a genuinely bad idea on a machine holding credentials or a repository you care about. Its safer relative merely adds the bypass mode to the mode cycle, so you can enter it deliberately rather than starting there.
Non-interactive mode is where the CLI earns its place in a pipeline, and the difference between a useful run and an unreadable one is four flags. Plain text output prints nothing until the run ends, which makes a long run look hung; the streaming JSON format emits each message as it happens. And when you want the result in a shape your script can rely on, there is a flag that validates the output against a JSON Schema.
# Four flags turn a run into something a script can read.
claude -p "summarize the diff" --output-format json
claude -p "…" --output-format stream-json --verbose
claude -p "…" --input-format stream-json
claude -p "…" --json-schema ./schema.json # validated output
claude -p "…" --include-partial-messages # token-level events
# Bound it before you automate it:
--max-turns 12 # stop after N agentic turns
--max-budget-usd 5 # stop at a dollar amount
--no-session-persistence # write nothing to disk
# For CI, mint a token instead of shipping an API key:
claude setup-tokenFor anything running in CI, generate a long-lived OAuth token with the token subcommand rather than putting an API key in a secret. It is one command, it produces a credential intended for exactly this, and it means the pipeline's access can be revoked without touching anything else. Pair it with a turn limit and a dollar ceiling so a stuck run cannot become an invoice.
The permission system does the heavy lifting, but several flags narrow a run at launch, which is what you want for automation. They compose, and knowing which one is the blunt instrument saves you from reaching for the blunt one first.
Narrowing a run:
| Flag | What it does |
|---|---|
| The tools flag | Restricts which built-in tools exist for the session at all — the strongest of the three, because a tool that is not there cannot be requested |
| Allowed and disallowed tools | Allow-listed tools run without a prompt; deny rules block them. These shape prompting rather than existence |
| The permission mode flag | Starts in plan, accept-edits, auto, manual or another mode, which decides how much is asked in the first place |
| Strict MCP config | Uses only the servers from the config you passed, ignoring everything otherwise configured — the flag that makes a CI run reproducible |
| Turn and budget limits | A maximum number of agentic turns and a maximum dollar spend. Both are how a runaway run ends quietly rather than expensively |
Three levers change cost more than anything else you can do from the command line, and they are worth setting deliberately rather than accepting whatever the defaults give you:
Debugging a misbehaving install is mostly about removing variables, and there are two flags for that with an important difference between them. One skips auto-discovery of hooks, skills, commands, subagents, plugins and MCP servers. The other starts with all customisations disabled for troubleshooting. Reach for them before you start deleting configuration you will want back.
Run the diagnostics subcommand first, every time. It prints where the binary came from, which settings files are in play and what they resolved to — which answers most configuration questions outright and turns the rest into a much better bug report. Pair it with the debug flag, which takes an optional category filter, and a debug file path so the output survives the session.
Four more are worth reading once now so you recognise them later, because each one is the answer to a question you will eventually ask:
Learn the diagnostics subcommand and the two troubleshooting flags today, because they turn a confusing afternoon into a five-minute answer. Put anything you type more than twice into a settings file rather than your shell history. And before you automate a run, give it a turn limit and a budget ceiling — not because you expect it to run away, but because the version of you debugging at midnight will be grateful the failure mode was a stopped run rather than a surprise.
Sources & further reading