Roman Kryvolapov Engineering Blog

Claude Code — commands, settings, flags

Hi!

This is a reference. Not a story about how to work with the agent properly — I have a separate article for that — but a list: what you can type, what you can put in the settings, what each of those does and how it looks in practice.

Current as of August 2026. The lists of commands, keys and flags were taken off build 2.1.251, and whatever could be checked by running it was checked on 2.1.252. For a technical article the version matters more than usual: between adjacent builds commands vanish, get renamed and swap places. If you're on a different version, /help and claude --help are always right, and I'm only right as of the time of writing.

The console output in the examples is real: it was either taken off a running build or from the official documentation. Where I couldn't find real output, there is none at all, and what happens after a command is described in words — there will be no invented screens in this article.

Three places where commands are entered

Before you page through the tables, it helps to understand that there are three surfaces and they don't overlap.

Slash commands are typed inside a running session, with a / at the start of the line. They drive the conversation: switch the model, compact the context, roll back edits, kick off a review. In the terminal they do nothing.

settings.json is a file on disk. It defines how Claude Code starts up: which model, what permissions the tools get, which hooks, what to show in the status line. A large share of the settings exist only here and have no command equivalent.

Terminal claude commands are typed in an ordinary shell, before a session or alongside it: installation, authentication, MCP servers, plugins, background agents, non-interactive runs for scripts.

The split isn't decorative. Half of the "why isn't this working" questions come down to someone typing /model in the terminal or --effort in the settings file. There is, though, one pleasant exception: in non-interactive mode claude -p slash commands do work inside the prompt text — more on that separately below.

Slash commands

Typed inside a running session, with a / at the start of the line. For every command below everything is gathered in one place: the arguments with all their values, the fine print and examples.

Markers: [Skill] — a built-in skill, that is, a ready-made prompt scenario; [Workflow] — a built-in multi-agent workflow; [extra cost] — paid for in credits separately from the subscription; [not on every plan] — availability depends on the plan, the organization or the provider; [undocumented] — present in the build, but not described in any public source.

About the examples. The blocks show what you actually type, with real arguments, not the bare command name. Output is shown where I could take it off a running build or from the official documentation; it's in English, because that's how it prints. Where there was no trustworthy output, there is none here either, and what will appear on screen and what you'll have to choose between is told in words in the command's description. There will be no invented screens in this article.

Commands that are disabled or removed entirely in this build get no sections of their own — they're collected in a table at the end of this section.

Sessions and the conversation

The four commands in this group do similar things, and people mix them up constantly. The difference is what gets copied and where the result shows up:

CommandWhat gets copiedWhere the work happensWhere the result lands
/branchthe whole conversationright here, you carry on in the branchin the branch; the original is left untouched
/forkthe whole conversationin a background session, in parallel with youin a separate session you attach to later
/subtaskthe whole context, one-offin a subagentback into this same conversation, as a single message
/backgroundnothing gets copiedthis very session moves to the backgroundthe same one, when you come back to it

/clear [name]

Start a new conversation with a clean context. Aliases: /reset, /new. You reach for it when moving on to a different task: the old context stops helping and starts getting in the way — the model keeps dragging details of the previous job into its answers.

The old conversation isn't deleted — it stays on disk and opens through /resume. The optional argument labels it in the list: without a label, a week later you'll be staring at a dozen nameless rows.

If you cleared by accident, it can be undone within the same process: the /rewind menu has an entry for the previous session, and it looks like /resume <id> (previous session).

Worth remembering the price too: /clear costs nothing, whereas /compact is a big request carrying the whole context. If the conversation is no longer needed, clearing is cheaper than compacting by the entire window.

/clear # a new conversation with a clean context
/clear queue experiment, didn't pan out # same, but the old conversation is labelled with this phrase

/resume [id or search phrase]

Go back to an earlier conversation. Alias: /continue. You need it when work got interrupted and you'd rather not start from scratch but keep all the context you'd built up — or when you need to dig up an old discussion to recall where you left off.

What you passedWhat happens
nothingAn interactive list of this folder's recent sessions opens
a session idIt opens straight away, with no list
arbitrary textA search across the contents of your conversations; you pick from the matches

The list is tied to the working folder: a conversation from another project won't appear in it. By id, though, a session opens from any folder on the machine — before version 2.1.223 the search covered only the current project and its worktrees. That's handy for scripts: grab session_id out of claude -p --output-format json and carry on from anywhere.

Transcripts are cleaned up according to cleanupPeriodDays, thirty days by default. If you expect to come back to old conversations, raise the value in advance — there's nowhere to restore deleted ones from.

Terminal equivalents: claude -c continues the folder's last conversation with no picker (skipping background sessions), claude -r opens the same picker before the session starts, claude -r <id> --fork-session continues an old conversation under a new id, leaving the original untouched.

In the list you pick which past conversation to continue: each row is a separate session of this folder, with its own label and time. The one you pick opens in full, with all the messages and context, and you carry on writing into it as if nothing had happened.

/resume # pick from this folder's recent conversations
/resume 8f3c1d2e-4b5a-... # open straight away by id, no picker
/resume deadlock in pool # search by content; pick from the matching conversations

/branch [name]

Branch the conversation off the current point; the original is kept whole.

This is "save before the boss fight". You're at a point where it's unclear which of two approaches is better; you branch off, try the first, and if it didn't work out you go back to the original through /resume and try the second, without dragging the failed attempt along in the context. The name is optional, but with one it's easier to find the right branch in the list later.

After the command you end up in the branch and write on inside it; the original conversation stays intact and opens through /resume.

/branch # branch off from the current point
/branch try-via-the-queue # same, with the branch labelled with this name

/fork [task]

Copy the conversation into a background session that works on the task in parallel with you.

This is "let somebody else deal with that while I get on with mine". The copy inherits all the context you've built up; you collect the result by attaching to it with claude attach or from the claude agents screen. Starting with 2.1.221 the copy is also told to create its own git worktree before touching code — so two agents don't step on each other's toes in one tree.

Careful with advice written elsewhere. In versions from 2.1.161 through 2.1.211, what is now called /subtask was called /fork, and the names swapped places in 2.1.212. An article or a script written before that means exactly the opposite. Plus one special case: if the agents screen is disabled, /fork falls back to the old behaviour and acts as a subagent.

Mind the spend as well: the copy is a full second session with its own context, and while it runs your limit is being burned by both at once.

The copy is created immediately and gets its own id — which is what you'll need to attach to it later. Given a task it gets to work at once; without one it simply waits for instructions.

/fork put together release notes from the commits since the last tag # the copy works in parallel with you
/fork # the copy waits for instructions

/subtask <task>

Send off a subagent carrying your context; the result comes back into this same conversation.

This is "go and have a look, then come back". The difference from /fork is fundamental: the noisy part of the work — reading twenty files, walls of output — stays in the subagent's context, and only the answer reaches you. The main way to keep recon from clogging your main context.

Requires version 2.1.212; before that this command was called /fork. Unavailable when the agents screen is disabled.

What it saves is your context window, not your spend: the subagent reads and thinks on your own limit, it just leaves no litter in the conversation.

The conversation doesn't stall: while the subagent reads you carry on writing, and when it finishes a single message from it appears in the thread with the result.

/subtask find every call to this method # recon without littering the context
/subtask read a month of migrations and tell me what changed in the order schema # same for a long read

/background [prompt]

Move the current session into the background and free up the terminal. Alias: /bg.

Nothing gets copied — this very session goes to the background and the work carries on. With an argument you also hand it a task for the road. To come back later — claude attach or the claude agents screen; to stop it — /stop or claude stop <id>. You reach for it when the task is long and you need the terminal right now.

The terminal is freed immediately, while the session lives on in the background under its own id — and that's what you use to get back to it.

/background # go to the background and free the terminal
/bg catch up with the build and fix the linter # same, plus a task for the road

/rename [name]

Rename the session. Alias: /name [undocumented]. The point is purely practical: once you have a lot of open and background conversations, you tell them apart by their label, not by their id.

The name is visible in the input line, in the /resume list and in the terminal tab's title. Without an argument it's generated from the topic of the conversation.

Three things happen to a name you type in: control and invisible characters are replaced with spaces, the length is trimmed to two hundred characters, and if nothing is left after the cleanup the name is rejected as empty. If that name is already taken by another live session on this machine, a variant of it is applied — not an error, the name just ends up slightly different.

The terminal title changes if terminalTitleFromRename is on (it is by default); to forbid touching the title altogether, use the CLAUDE_CODE_DISABLE_TERMINAL_TITLE variable.

/rename # the name is made up from the topic of the conversation
/rename payment refactor # the name is set by hand

/cd <path>

Move the session to a different working folder. Handy when the work has moved to a neighbouring service or repository and you don't want to abandon the conversation.

The new folder's settings, hooks, MCP servers, skills and agents take effect immediately rather than after a restart, and the new folder's env block is layered over the old one. That's what makes /cd different from /add-dir, which grants access to files but not to configuration.

/cd ../backend # move to the neighbouring repository along with its configuration

/recap

Squeeze the whole session into a one-line summary — a quick way to recall what it was about. Useful after a break and in a long conversation where the beginning has scrolled off the screen. The context isn't touched: this is just a short digest in a reply, not the compaction of the conversation that /compact does.

/recap # what this conversation is about and what it arrived at

/btw [question]

Ask a short side question without polluting the main context: the answer isn't mixed into the work that follows. This is for "hang on, what is this thing even called" in the middle of a task — so that ten messages later the model isn't building its reasoning around a question you asked in passing.

With no question it opens your past side questions so you can page through the answers; before version 2.1.212 the question was mandatory.

/btw how is grpc-web different from grpc # the answer is for you, but bypasses the rest of the context
/btw # go back to past side questions

/export [file]

Dump the conversation to a file or to the clipboard. Usually what you want in order to attach the exchange to a ticket, forward it to a colleague, or save an analysis you'll come back to.

With no argument the whole conversation goes to the clipboard; with an argument it's written to a file; ~ is expanded. The format is text, with the roles marked up: it's a transcript for a human or for handing to another tool, not a machine format for importing back.

/export # the whole conversation to the clipboard
/export ~/logs/session.md # same, but to a file

/copy [N]

Copy a single reply to the clipboard: with no argument the last one, with a number the Nth from the end. You need it when you want to lift a chunk out of a big answer into an editor or a ticket and don't fancy selecting half a screen with the mouse.

What gets counted is assistant replies, not lines on the screen, so /copy 2 means "the reply before last". Little known: if the reply contains code blocks, a picker opens — you can take a single block instead of the whole message. And right there the w key writes the selection to a file instead of the clipboard; over SSH, where the clipboard is useless, that's the only thing that works.

The choice in that list is between the whole message and any single code block from it; the selection goes straight to the clipboard, or with w to a file.

/copy # the last reply to the clipboard
/copy 2 # the one before last; if it has code, you'll be asked to pick a block first

/stop

Stop the current background session. The transcript and the worktree are kept. You need it when the background work went off the rails or is no longer wanted: the session really does stop working, rather than merely detaching as with /exit. From outside, claude stop <id> does the same thing.

/stop # stop the background session; the transcript and the worktree stay

/exit

Quit the CLI. Alias: /quit. In a background session it detaches, and the session itself carries on working.

/exit # quit the CLI; in a background session it only detaches

Context and memory

/context [all]

Shows what's filling the context as a colored grid, plus hints about what you could unload. The all argument expands the details: exactly which files, and how much each takes. Worth reaching for when the session has grown noticeably heavy or is about to slide into auto-compaction: the command shows who exactly ate the window, and the cure depends on that. Don't confuse it with /usage: that one is about your plan's limits, this one is about the current session's window.

Every cell of the grid is a slice of the context window, colored by source. The point isn't decoration: different sources behave differently, and each is cured differently.

What it showsWhere it comes fromHow to shrink it
System promptClaude Code itselfalmost nothing does; --bare and --restricted trim it
Tool descriptionsbuilt-ins plus MCP serversturn off the servers you don't need
Skill listingdescriptions of every available skillskillOverrides, skillListingBudgetFraction
Memory filesCLAUDE.md and auto-memoryshorten them, or exclude via claudeMdExcludes
Conversation historyyour messages and the replies/compact, /clear
Files read and command outputtools/clear, and hand the exploration to /subtask

The practical value is in all: there's almost always a file or two, or one chatty MCP server, that ate more than all the useful work put together.

Then comes the fork. History bloated — /compact. File reads bloated — /clear and start over. Tool and skill descriptions bloated — that's cured by settings, not by commands: the next session would start out exactly as swollen.

/context # what's taking up the context right now
Context Usage
Opus 5 (1M context)
claude-opus-5[1m]
138.8k/1m tokens (14%)
Estimated usage by category
System prompt: 4.4k tokens (0.4%)
System tools: 21k tokens (2.1%)
MCP tools: 265 tokens (0.0%)
Memory files: 3.2k tokens (0.3%)
Skills: 6.2k tokens (0.6%)
Messages: 104.2k tokens (10.4%)
Free space: 860.7k (86.1%)
MCP tools · /mcp (loaded on-demand)
└ 126 tools · 265 tokens
Memory files · /memory
└ 1 file · 3.2k tokens
Skills · /skills
└ 48 skills · 6.2k tokens
/context all to expand
Suggestions
ℹ File reads using 76.1k tokens (8%) → save ~22.8k
If you are re-reading files, consider referencing earlier reads.
Use offset/limit for large files.
/context all # the same, broken down file by file

The output above is a verbatim snapshot of a real session on Opus 5 with a million-token window.

/compact [instructions]

Compacts the conversation history into a summary, freeing up room. The argument isn't a flag and isn't a filter — it's an instruction to whoever writes the summary: what to pay attention to, what must not be lost. You need it when the window is nearly full but it's too early to drop the conversation: work continues from the same place, but from here on it leans on a retelling.

Compaction is loss. The summary is written by the model, it's inevitably shorter than the original, and anything left out of the emphasis is reproduced approximately or disappears. A thought-out argument isn't politeness — it's how you control what exactly you agree to lose.

The command asks nothing, folds up the history and reports in a single line; the summary itself is collapsed by default and expands with a separate keypress. With an argument nothing changes on the outside — the difference is only in what the summary held on to.

Compaction is itself an expensive request: the entire context goes into it. /clear costs nothing. If you no longer need the conversation, the second command is cheaper than the first by a whole window.

The threshold at which the context compacts itself is controlled by /autocompact.

/compact # compact the history however it comes out
⎿ Compacted (ctrl+o to see full summary)
/compact keep the DB schema decisions # compact, but don't lose this thread
/compact keep only what concerns the payment module

The report line is quoted verbatim, captured on build 2.1.220.

/autocompact [auto|<tokens>]

Sets how full the context has to get before it starts compacting itself. The command appeared in 2.1.221. The threshold is a trade-off: the higher it is, the longer the full history survives, but the closer you are to the ceiling of the window; the lower it is, the more often the conversation turns into a retelling. You reach for the command when compaction fires at the wrong moment — too early and it carries off what you needed, too late and it slams into the ceiling.

ArgumentWhat it does
no argumentShow the current value
autoThe threshold is picked automatically
a number from 100000 to 1000000Compact once that many tokens are reached

Values outside the range are rejected. The persistent equivalent is the autoCompactWindow key; auto-compaction is switched off entirely with autoCompactEnabled: false, and there's a launch flag --autocompact taking the same values. A separate setting, precomputeCompactionEnabled, prepares the compaction ahead of time while ordinary work goes on — so when the threshold is reached the pause is shorter; it only works with auto-compaction enabled.

The command opens no dialog: with no argument it just shows the threshold in force, with an argument it accepts a new one or refuses if the number falls outside the allowed range.

/autocompact # check the current threshold
/autocompact auto # let it pick for itself
/autocompact 400000 # compact on reaching 400k tokens

/memory

Opens the memory files for editing and lets you manage them. Memory is mixed into the context of every session, so it's both the main lever on the agent's behavior and a standing tax on the window: everything sitting there is paid for on every single request. First you pick which file to edit — the project one or your personal one — and it opens in the editor.

What exactly gets loaded out of them is shown by /context, and /doctor knows how to tidy them up: it clears out duplicates, moves rarely needed material into separate files loaded on demand, and cuts whatever the agent would work out from the code anyway.

/memory # open the memory files for editing

/init

Creates CLAUDE.md: the agent looks the repository over and describes its structure and commands. [Skill] Worth reaching for on a repository the agent hasn't worked with yet; an already existing file is usually faster to fix by hand through /memory than to regenerate.

CLAUDE.md is an instructions file that gets mixed into the context of every session.

On success the command prints nothing. The documentation suggests checking the result in the next session: call /context and make sure CLAUDE.md has shown up under Memory files.

A little-known variable: CLAUDE_CODE_NEW_INIT=1 turns on an interactive version that walks you through not only the project instructions but skills, hooks and personal memory files as well. And if the folder turns out to hold another coding agent's configuration that /import knows how to carry over, you'll be offered to take it.

/init # generate CLAUDE.md from the repository
Terminal window
CLAUDE_CODE_NEW_INIT=1 claude # interactive /init with skills and hooks

/add-dir <path>

Adds another working directory so the agent can see files outside the project folder. You need it when the work doesn't fit into one repository: a neighboring service, a shared schema, an extracted library — without this the agent simply won't read them.

An important subtlety: it grants access to files, not to configuration — that folder's hooks and settings are not picked up. The single exception is skills and commands: those are taken from the added folder. Moving the session into another folder wholesale, along with its settings and hooks, is /cd, not /add-dir.

/add-dir ../shared-protocol # let the agent into a neighboring repo

/rewind

Rolls the code and/or the conversation back to a checkpoint, or compacts a chunk of the conversation. Aliases: /checkpoint, /undo. You need it when a run of edits went the wrong way and untangling what exactly the agent changed takes longer than stepping back.

The first thing to know: the command doesn't always work. Copies of files are taken before an edit only if fileCheckpointingEnabled is on. Off — and there's nothing to restore from.

Second: the menu doesn't open only from the command. A double Esc on an empty input line does the same thing. If the line has text in it, a double Esc clears the text — so clear the line first.

The menu has six items, and half of them aren't about rolling back:

ItemWhat it does
Restore code and conversationA full return to the state at the checkpoint
Restore conversationThe history comes back, the files stay as they are
Restore codeThe files come back, the conversation stays whole
Compact from hereCompact the conversation from the chosen point onward
Compact up to this pointCompact everything that came before the chosen point
CancelDo nothing

The two compaction items are essentially a targeted /compact: free up context, but from one specific chunk of the conversation rather than all of it. The line has an optional field for saying what to pay attention to while compacting, and a marker is left where the compacted part was.

The choice here is two-step: first the point you're returning to, then one of six actions on it. Of the rollbacks, the one you want most often is "restore code": the edits went astray, but the discussion they grew out of is valuable and it would be silly to lose it.

Limits worth knowing before you need them. The last hundred checkpoints are kept, and they're deleted along with the session after thirty days — the same cleanupPeriodDays. Not restored: whatever the shell commands you ran did, most subagent edits, changes made from outside, and anything living behind symbolic and hard links. Which means a database wiped by a migration won't come back, a git reset won't be undone, installed packages will stay. This is an undo for recent edits, not a version control system and not a substitute for commits.

Restoring code isn't always complete: if a file's type or directory changed since the checkpoint, it gets skipped, and the session tells you separately how many files it left alone.

/rewind # the rollback and compaction menu

Model and performance

/model [model]

Switches the model and remembers the choice. [extra cost] it isn't the command itself that costs, it's part of what you can pick with it: on a number of plans, Fable 5 and the million-token-context variants are charged against credits on top of your subscription, and without credits enabled those rows in the list don't work. With no argument it opens the list of what's available. You reach for the command when the character of the work changes: a heavy investigation is worth running on the strongest model, while a stream of small edits belongs on a fast, cheap one.

What you passedWhat happens
nothingThe list of available models opens
a family alias — opus, sonnet, haiku, fableThe current model of that family is taken
defaultThe default model for your plan
bestFable 5 where the organization has access, otherwise the newest Opus
opusplanPlanning on Opus, execution on Sonnet
opus[1m], sonnet[1m]The same model with a million-token context window
a version prefix, e.g. opus-5Resolves to a specific model
a full identifierExactly that one is taken

The choice is remembered and survives a restart — that's how /model differs from the ANTHROPIC_DEFAULT_MODEL variable, which it overrides.

The picture as of August 2026. The current models are Opus 5, Sonnet 5, Fable 5 and Haiku 4.5. There is no Haiku 5: the haiku alias still points at 4.5, and that regularly misleads people reading examples with fallbackModel.

What stands behind an alias depends on the provider, and that's a non-obvious detail for anyone working through a cloud. On Anthropic's own API sonnet is Sonnet 5, on Amazon Bedrock and Google Cloud it's Sonnet 4.5, and on Microsoft Foundry opus is Opus 4.6 outright. The very same config gives you different models on two providers.

All of this is configured in three ways. What the aliases stand for — through ANTHROPIC_DEFAULT_OPUS_MODEL and its relatives (there's no such variable for best). The picker list itself — through the modelPicker key: you append your own labeled rows there, Bedrock and Vertex identifiers included, and replaceBuiltInOptions replaces the built-in list entirely. Over the top of all that sits the corporate availableModels; since version 2.1.205 a family alias isn't rejected by it but resolves to the newest permitted model.

fallbackModel lives on its own — a list of models Claude Code will switch to by itself if the main one is overloaded. It doesn't change your choice, it's insurance for however long something is unavailable.

What exactly gets billed separately. For Fable 5, whether it draws on credits depends on the plan and on the type of seat in the organization; where it does, that row in the list carries a note that credits are required, and before the first such request Claude Code asks for confirmation once. In non-interactive mode (-p) and through the Agent SDK there's no such question — the charge happens silently. With the million-token window the picture is different: on Sonnet 4.6 it requires credits on any subscription plan, Max included; on Opus only on Pro, while on Max, Team and Enterprise it's part of the plan with no configuration at all. On Sonnet 5 through Anthropic's own API the million-token window is always on and needs no credits.

In the list you choose between families and specific versions: you can see what's available on your plan and which rows carry a credits requirement. With an argument the list doesn't open — the model changes right away. The chosen model applies to the current session and stays chosen next time.

/model # pick from the available list
/model opus # by alias
/model opusplan # plan on Opus, execute on Sonnet

/effort [level|auto|status]

The effort level sets how much the model thinks about a turn. It isn't the same as picking a model: the model decides who thinks, the effort decides how much. The practical point is trading time and token spend for the quality of the turn: on an obvious edit, deep reasoning only slows things down, while on a tangled defect, skimping on it ends in a wrong diagnosis.

ValueWhat happensWhen it makes sense
lowMinimal reasoning, an answer almost immediatelyMechanical edits, renames, questions with an obvious answer
mediumThe normal modeEveryday work
highNoticeably more reasoning before actingTasks where a mistake costs more than the wait
xhighThe most reasoning available in normal modeDesign work, digging into a tangled defect
maxThe same, with the emphasis on thoroughnessRarely; before irreversible changes
ultracodexhigh plus permanent workflow orchestrationLarge decomposable jobs where cost isn't the priority
autoThe level is matched to the taskThe default, if you haven't intervened
statusChanges nothing, shows the current level

Four non-obvious things.

max can't be saved in the settings. The effortLevel key accepts values only up to xhigh. Maximum is set for a session — by the command or the --effort max flag — and deliberately doesn't stay on forever. ultracode works the same way: the command and the flag work, but it isn't among the values listed in the schema; permanently it's switched on by a separate boolean key, ultracode.

The level is remembered per model. Since version 2.1.248 every model has its own saved level: switch to another one and you get its setting, not your last one.

Other commands override it. /code-review high raises the effort for that turn, /code-review low lowers it, even if the session was running on xhigh.

The word ultracode works right inside the prompt text — by default that's enough to turn orchestration on for one turn; workflowKeywordTriggerEnabled is what governs it. If it fired by accident, it's cancelled on the spot with Alt+W (Option+W on macOS). To start out with it: claude --effort ultracode.

A word on what ultracode spends. It isn't billed on top of your plan, but one request of yours unfolds into several workflows in a row, and every workflow spawns agents — your plan's limit melts noticeably faster than in an ordinary session. The large-run warning Claude Code shows when more than 25 agents are planned or the forecast passes a million and a half tokens is not displayed in ultracode mode: by turning it on you've already agreed to large runs. On the Pro plan, workflow orchestration first has to be enabled in /config.

One more thing, fixed in 2.1.251, an edge case that's easy to hit: Opus 5 refused to work with xhigh and max when thinking was turned off. Now in that combination the effort is simply sent as high.

With an argument the level switches on the spot, for the current session; status changes nothing and only shows the level in force.

/effort status # what the level is right now
/effort low # cheap and fast
/effort ultracode # xhigh plus permanent workflow orchestration

/fast [on|off]

Fast mode: the same model, but with accelerated output. [extra cost] it has no free allowance — the mode is always paid for with credits on top of the subscription, even if your plan's limit hasn't been used up yet, and until credits are enabled the command will tell you they're needed and switch nothing. You reach for it where waiting costs more than paying: conversational debugging, a long run of small edits, a live demo. It isn't a different model and isn't a different effort level — it's an output mode.

The price of the speed-up on Opus 5 and Opus 4.8 is 10 dollars per million input tokens and 50 per million output, the same across the whole million-token window; that's more than the usual Opus rates. There's an unpleasant subtlety about switching it on partway through a conversation: the entire accumulated context is recharged at the full fast-mode input price, so it's cheaper to turn it on at the start of a session than on the hundredth turn. If credits run out mid-work nothing breaks — Claude Code retries the rejected requests at normal speed and normal price. In the Claude Console there are no credits at all: the organization pays for the tokens along with the rest of its API spend. On Amazon Bedrock, Claude Platform on AWS, Google Cloud Agent Platform and Microsoft Foundry the mode doesn't exist.

The neighboring settings keys: fastMode turns it on permanently, while fastModePerSessionOptIn makes every session start without it, even if you switched it on last time.

/fast on # accelerated output
/fast off # back to normal

/brief

"Brief only" mode: maximally compressed answers with no expanded explanations. The command takes no arguments. Useful when you're driving the work yourself and what you want from the agent is a result or a short fact, not a walkthrough with examples. It affects neither the amount of actual work nor the depth of reasoning — only what gets printed to you is shortened; depth is /effort's job.

/brief # answer as briefly as possible

/advisor [model|off]

The advisor: a stronger model prompts the main agent at key moments. [not on all plans] it needs access to Anthropic's own API — by subscription or through the Console; on Amazon Bedrock, Claude Platform on AWS, Google Cloud Agent Platform and Microsoft Foundry there is no advisor, and it requires feature-flag fetching to be enabled. The point is not to pay for a strong model across the whole session, but to call it in at specific spots. The feature is experimental, and it's too early to run real work on it.

The second model doesn't step in constantly, only at key points — when the main agent is making a decision where a mistake is costly. The argument is an alias or a full model identifier; off turns it off. With no argument a picker opens. There's also a launch flag, --advisor <model>, which, by the way, isn't in the output of claude --help.

The advisor's usage comes out of your ordinary plan limit — with one exception: if Fable 5 is appointed advisor, its work is paid for with credits wherever ordinary Fable 5 usage is paid for with credits. Until you've consented to that charge through /model fable, Claude Code simply won't appoint Fable as advisor.

With no argument the same model list opens, but what you're choosing in it isn't the working model, it's the helper: the main model stays as it was, and the one you pick is attached on top of it.

/advisor # pick an advisor from the list
/advisor opus # hints from Opus
/advisor off # turn the advisor off

/plan [open|share|description]

Planning mode: the agent reads, analyzes and proposes a plan, but changes nothing — file edits and dangerous commands are unavailable. The way out is accepting the plan; after that the session returns to normal mode and starts carrying it out. You want it where the cost of a misunderstood task is higher than the time spent agreeing on it: before a big rework, in unfamiliar code, when an edit spreads across a dozen files.

ArgumentWhat it does
nothingJust enter planning mode
the task textEnter and start planning it right away
openOpen the file of the session's current plan
sharePublish the plan as a separate page you can share

Plan files live in ~/.claude/plans/ unless plansDirectory is set — people use it to move them into the project repository, so the plan is discussed and versioned along with the code.

The plan-acceptance dialog has a "clear context" option: the plan stays, and all the exploration it was built on is thrown away. It only shows up with showClearContextOnPlanAccept, which is off by default, and on long tasks it's one of the most useful settings — execution starts with a clean window.

The mode is available right from the start too: claude --permission-mode plan. And it's worth knowing separately that auto mode is in effect by default inside planning as well; that's switched off with the useAutoModeDuringPlan key.

The finished plan is shown together with the acceptance dialog, and there you pick among three options. "Yes, and use auto mode" — accept and continue in auto mode; where auto mode isn't available the same row reads "Yes, auto-accept edits", and in a session started with permissions bypassed it reads "Yes, and switch to BYPASS PERMISSIONS (no further prompts) for this session". "Yes, manually approve edits" — accept, but confirm every edit by hand. "No, keep planning" — stay in planning and say what to fix. That's how the documentation describes it.

/plan # enter planning mode
/plan split payments into a service # enter with the task right away
/plan share # share the plan

/goal [condition|clear]

Sets the condition under which the work counts as finished; the agent keeps going by itself until it's met, instead of stopping after every turn. That changes the rhythm: the turn doesn't come back to you at every step, and you only have to step in if something went off the rails. It makes sense on long mechanical work — pushing a build through to green, carrying the same edit across the whole project.

ArgumentWhat it does
the condition textSet the goal
clear, stop, off, reset, none, cancelDrop the active goal — any of the six words
nothingShow the current goal, or the last one reached

The condition has to be checkable — a command, a file's state, a marker in the output. A vague "until it's good enough" turns into endless work, because there's nothing to check it against.

A separate cost item few people think about: while a goal is active the agent periodically wakes up and checks on stuck background work, and every such check is a full turn with the full context. The frequency is set by CLAUDE_CODE_GOAL_CHECKIN_MINUTES, zero disables the checks entirely; since version 2.1.246 there are no more than three of them per goal.

/goal until all the tests are green # work until the condition is met
/goal # show the current goal
/goal clear # drop the goal

Code review and quality

The first three commands all look at the same diff and are therefore easy to confuse; the fourth doesn't analyze anything at all:

CommandWhat it looks at
/code-reviewcorrectness bugs and code cleanliness; only edits with --fix
/simplifycleanliness only — and applies what it finds right away
/security-reviewonly vulnerabilities in the branch's changes
/diffdoesn't look for anything, just shows the changes

/code-review [level|ultra] [--fix] [--comment] [--post|--no-post] [target]

Reviews the diff for bugs and simplifications [Skill]. Alias: /review. An ordinary local review counts against your plan's limits, but the cloud ultra mode is [costs extra]: three free runs each on Pro and Max, after that it's charged to credits, usually five to twenty-five dollars per review, and if credits aren't set up a paid run is simply blocked. That same ultra is also [not on every plan]: it needs a claude.ai login, and it isn't there on third-party providers or in organizations with zero data retention.

The most configurable of the built-in commands: an effort level, four flags, a review target and a separate cloud mode — and each is parsed by its own rules. The full form is /code-review [low|medium|high|xhigh|max|ultra] [--fix] [--comment] [--post|--no-post] [<PR#>|<branch>|<path>|<note>], and everything in it is optional: a bare /code-review is a valid call.

What it looks for. Two different things. Correctness bugs: an inverted condition, an off-by-one, a null dereference, a forgotten await, a check that was dropped, an error swallowed in a catch, broken callers of a changed function, the classic traps of the particular language. And cleanliness: new code that repeats something already in the repository; needless complexity and dead code; needless work such as repeated computations or independent operations run one after another; the "wrong level of fix", where a patch goes in the spot where the general mechanism should have been fixed; direct violations of the rules in your CLAUDE.md.

Correctness bugs always outrank cleanliness findings: if there are more findings than the level allows, the latter get cut first. The review itself changes nothing until --fix is passed.

Where it runs. Usually in a background agent: the session isn't blocked, and the findings arrive as a separate message. In three cases the review takes over the whole session: if you started it again while the previous one is still running; if you're in non-interactive -p mode or in the SDK; and if CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 is set, which disables background tasks entirely.

Who can start it. Not just you. Ask "take a look at my changes" in plain text and the agent will start the review itself, and a scheduled task with /code-review in the prompt will fire too. If that gets in the way, you can keep the command typeable but forbid the agent and the scheduler from running it:

.claude/settings.json
{
"skillOverrides": { "code-review": "user-invocable-only" }
}

The cloud mode is the exception: the agent never starts ultra, neither on its own nor on a schedule.

Argument order. Three rules that make a call behave differently than you expected:

  1. ultra is only understood as the first word. /code-review ultra --fix is a cloud review, while /code-review --fix ultra is an ordinary local one in which the word ultra is read as the target.
  2. The level is the first word left once the flags have been stripped from the line. That's why /code-review --fix high works, and the level will be high.
  3. Flags can go anywhere: at the start, at the end, between the level and the target. The only exception is rule 1.

And a fourth one, separate: this command "eats" the command typed after it. Normally several skills chain in one message, and /write-tests /fix-issue 123 will load both. But since 2.1.218 /code-review /fix-issue 123 reads /fix-issue 123 as target text rather than as a second command. Before 2.1.218 it was the other way around.

Effort levels.

LevelHow it searchesFindingsWhen to use it
lowA single pass over the diff: no subagents, no reading whole files, no re-verification of findings; test files aren't looked atup to 4, on some models up to 8A quick, cheap read-through before a commit
mediumEight independent search angles — three on correctness, three on cleanliness, one each on the level of the fix and on the CLAUDE.md rules — then verification of every findingup to 8An ordinary review
highThe same eight angles, but the verification leans toward completeness: a finding stays unless it can be disprovedup to 10When a missed bug costs more than extra noise
xhighTen angles with eight candidates each, verification, and a separate final "what did we miss" passup to 15A large or risky diff
maxThe same as xhigh, with maximum emphasis on completenessup to 15Before a release, a migration — anything hard to roll back
ultraNot a level but a mode of its own: a multi-agent review in the cloudA whole pull request you'd like a second pair of eyes on

The numbers in this table were read off the binary: the official documentation describes the levels qualitatively — "low levels return the most confident findings, high ones broaden coverage and may include less confident ones" — and nowhere publishes how many search angles there are or what the cap on findings is.

The exact pipeline depends on the session's model, so the table is about what the levels mean, not about a guaranteed number of agents. On Opus 5, medium and high currently collapse into a single careful pass with a cap of fifteen findings, and the differences start at xhigh; on Sonnet 5, at high, xhigh and max the number of search agents is picked from the size of the diff — anywhere from two to eight.

There's no separate charge for the upper levels, but every search agent carries its own context, so xhigh and max burn through your plan's limit noticeably faster than low. Running max on every little fix is the easiest way to be out of your weekly limit by Wednesday.

Remembering the level. If no level is given, the one you typed last time is used: it survives across sessions, and the report opens with a line like "using high, the level from last time". Two exceptions: a level passed in a non-interactive -p run remembers nothing, and ultra neither reads the remembered level nor changes it. If you've never typed one, the current session's effort level is used. The level you type also sets the model's effort for the turn, including downward: /code-review low in a session on xhigh will lower it.

A typo doesn't break the call: /code-review higher gets you a warning that the value wasn't recognized, plus the previous or default level. The shorthand med is accepted as medium.

Flags.

FlagWhere it worksWhat it does
--fixlocally and with ultraAfter the report, apply the findings to the working tree
--commentlocally, if the target is a pull request on GitHubPost every finding as a separate line comment
--postultra only, repository on github.comPost the summary as one ordinary comment from your account
--no-postultra onlyRemove the offer to post from the launch dialog — which is the default behavior anyway

--fix fixes what was found right in the working tree, both bugs and cleanliness. A finding is skipped if the fix would change intended behavior, require changes far beyond the diff that was reviewed, or looks like a false positive; at the end you're told what was skipped and why. With ultra the fixes are applied locally the moment the cloud returns its result.

--comment requires the target to be a pull request. If it isn't, the flag is ignored, the findings are simply printed, and the agent tells you so. Comments go out through the GitHub integration, or through gh api if the session doesn't have one.

--post is not the same as --comment: one shared comment instead of per-line remarks, and only for a cloud review. In an interactive session the launch dialog will still ask for confirmation; in non-interactive mode it posts on the flag alone. Passed to an ordinary local review, it's ignored — you'll be reminded that posting there is --comment's job.

--no-post is for not seeing the offer to post at all. Passing both at once is pointless: the command only reads --post, so --post --no-post will still offer to post.

The review target. With no target, your current work is reviewed: the branch's commits above its upstream plus uncommitted changes. That's why the command makes sense before a commit, too.

In a local review the target is handed to the model as a string, and it decides for itself what it is: a pull request number, a branch name, a path to a file or a folder — or just a hint about where to look first. In ultra the target is parsed strictly:

What you passedWhat happens
nothingThe current branch is reviewed against the base one
1234, #1234, PR 1234, a link to /pull/1234That pull request is loaded and reviewed
the name of an existing branchTaken as the base, and the diff is computed against it
anything elseRecorded as a note for the review: the cloud agent doesn't see it and reviews the branch diff anyway, but when the findings come back they'll be tied to what you asked for

Reviewing in the cloud: what it needs, what it costs, where the ceiling is. ultra launches a background agent in Claude Code on the web: it clones the repository into a cloud sandbox, runs a multi-agent search over the diff and sends the findings to your session as a notification. It takes minutes, and you can keep working the whole time.

You need a git repository and a GitHub remote, a claude.ai account with GitHub connected, and for a private repository the Claude app installed on the owner. It's unavailable on third-party providers, with optional requests turned off, in organizations with zero data retention, and when the organization forbids it. An important detail: when the mode is unavailable, /code-review ultra doesn't fail — it quietly runs an ordinary local review, so if you were expecting the cloud one, it's worth making sure it actually started.

The diff ceiling is up to five hundred changed files and eight thousand changed lines. A pull request that's too big is rejected, and the rejection names the limits in force, the size of your diff and the biggest files; an empty diff is rejected too.

The price: three free runs each on Pro and Max — granted to the account once, never refreshed — and none at all on Team and Enterprise. After that it's credits, usually five to twenty-five dollars per review depending on the size of the changes. A run counts from the moment the cloud session starts: a review you stop or that crashes still spends a free run, while a paid one is charged only for the part it worked through. If credits aren't set up, a paid run is simply blocked.

What you confirm before it starts. A paid cloud run doesn't go off silently: first you're shown a dialog with a cost estimate and asked to agree to the credit charge — once per conversation. In the same place, if --post was passed, you decide whether to post the summary as a comment in the pull request or keep the findings to yourself. Until you confirm, the cloud session doesn't start.

From CI. Since 2.1.218 the cloud review can be started non-interactively:

Terminal window
claude -p '/code-review ultra'

The command starts the review, prints a link for following along, and doesn't wait for the result. But if the review is going to spend credits, the run stops: confirming payment requires an interactive session. For that case there's a separate subcommand, and the very act of running it counts as your consent to the charge:

Terminal window
claude ultrareview # cloud review of the current branch
claude ultrareview 1234 --post # review a PR, summary as a comment in it
claude ultrareview --json # raw findings instead of a report
claude ultrareview dev --timeout 60 # against branch dev, wait up to an hour

The exit code is 0 if the review finished (with findings or without) and 1 if it couldn't be started. --timeout defaults to thirty minutes.

The canonical form is /code-review ultra; /ultrareview is its alias, it isn't available to every account, and the whole feature is marked as research. Articles often have it the other way around, as if /ultrareview were the main command.

In GitHub Actions. The review has a separate life in CI, and there it's configured by a file rather than by flags. You put a REVIEW.md in the repository root that sets the rules: which paths and branches to skip, which categories of findings to hide, what counts as important, how to behave when the same pull request is reviewed again.

Findings come in three levels: important ones, nitpicks, and ones that were already in the code before these changes. Violations of your CLAUDE.md rules land in the nitpicks. The check always finishes with a neutral status and so never blocks a merge on its own — but its last line prints a finding counter as JSON like {"normal": 2, "nit": 1, "pre_existing": 0}, which you can use to put up a barrier of your own in your own pipeline.

What comes back depends on the mode: an ordinary review sends a report as a separate message, --fix adds fixes in the working tree to it, --comment takes the findings off into comments in the pull request, and ultra first asks for confirmation in the launch dialog and only then gives you a link to the cloud session.

/code-review # current changes, level as last time
/code-review high --fix # deeper, and fix what it finds right away
/code-review medium --comment 1234 # review PR 1234 with comments right in it
/code-review ultra 1234 --post # cloud review of a PR, summary as a comment

/simplify [target]

Find simplifications in the changed code and apply them right away [Skill]. This is cleaning up after yourself once the code already works: the command doesn't look for bugs at all, so it runs faster than a review — but it can't replace one either. It's worth reaching for when a change has grown: near-identical chunks have appeared, your own helpers on top of ones that already exist, extra intermediate layers.

It looks at the same diff as /code-review, but searches only for cleanliness, and does it with four parallel agents: reuse of helpers already written, simplifications, efficiency, and whether this is the right level of abstraction. It doesn't look for bugs on principle — that's a division of labor, not an oversight. And unlike the review, it applies what it finds right away. The argument is an optional target: a path, a folder or a pull request number.

It isn't billed separately, but four agents means four contexts at once, so the command eats through your plan's limit noticeably faster than a single pass.

A historical trap: before version 2.1.147 what is now /code-review was called /simplify, and it applied its fixes by default. An old script that called /simplify to hunt for bugs does something completely different today.

You won't have to choose anything along the way: the command asks nothing, and what comes back is a list of the simplifications applied — by that point the edits are already in the working tree.

/simplify # all the changed code
/simplify src/payments # just this folder

/security-review

Check the branch's changes for vulnerabilities. No arguments. This is a third look at the same diff, but through different optics: not "does it work" and not "is it written neatly", but what could be pulled out of it or broken from the outside. It makes sense to call before the branch heads off to the shared repository — especially if the change touched authentication, parsing of user input, or secrets.

It looks for injections, authorization and authentication problems, data leaks, and unsafe handling of secrets and input.

The one requirement people trip over: you need a remote named origin — the diff is computed against its main branch. Without it the command fails with a git error about an ambiguous argument, and it looks mysterious.

What comes back is a list of what was found: the place in the code, the nature of the problem, and why it's dangerous.

/security-review # vulnerabilities in the branch's changes

/diff

Look through uncommitted changes interactively. No arguments. It analyzes nothing, it's a viewer: uncommitted changes and, more usefully, the diff of each agent turn separately. It comes in handy when the agent has worked through several turns and you need to see which step it went wrong on — so it's a thing to use before /rewind, not after.

Inside it you choose what to look at: all the uncommitted work at once, or one specific agent turn. Leaving the viewer puts you back in the same session and changes nothing in the code — rolling back lives in /rewind, it isn't here.

/diff # look at what's uncommitted

Development and workflows

/run and /verify get mixed up constantly: both are about "checking it live", but they answer different questions.

CommandThe question it answers
/verifyWhether one specific change does what it was meant to do
/runHow the whole app behaves when you bring it up the usual way

/run

Start the project's app and check the change live, not just with tests. [Skill] You reach for it when the diff tells you nothing: a screen changed, a form behaves differently, a command's output moved — you just need to see the app running. Don't mix it up with /verify: that one answers for a single concrete edit, while /run brings everything up as is.

This is about the whole app: start it the way it's started in this project, and let you look. For the agent to know exactly how, it needs a launch skill — /run-skill-generator creates it, once per project. Without one, /run will try to guess from the project type, and on a non-standard build it'll guess badly.

Once called, the usual build and start steps run — the ones written down in the skill or inferred from the project type — and then you look at the app itself: did it come up, and does it do what you brought it up for.

/run # start the app and see it with your own eyes

/verify

Confirm that a change works: build it, run it, watch how it behaves. [Skill] You reach for it right after an edit, when what matters is seeing the result rather than trusting the diff. What gets checked is the change itself, not the whole app — for that there's /run.

The logic is simple: a review checks that the diff reads right, /verify checks that it works right.

Since 2.1.200 the command can write the verification recipe it found into a skill of your own, .claude/skills/verify/SKILL.md, and sitting in the repository root it then replaces the built-in one — so you work out once how to verify this project, and after that it works for everyone.

An important change: since 2.1.215 /verify is launched only by you. The agent used to be able to call it itself. The same happened to /deep-research in 2.1.218. If you've read an article saying the agent will verify itself, it's out of date.

The check runs all the way through on its own — build, run, watch the behavior — and at the end you get a verdict on whether it holds up and what exactly was looked at. If the repository didn't have a verification recipe yet, you'll be offered one to write down along the way.

/verify # build, run, make sure it works

/run-skill-generator

Create a skill that knows how to start this project's app — /run then runs on top of it. [Skill] The command works out how everything here builds and starts, and writes the recipe it found into a skill that lives in the repository and works for everyone.

Done once per project.

The work isn't instant here: the app really is brought up from scratch, while noting which install commands, environment variables and start script actually worked. The result is a skill file in the repository, not text in the terminal.

/run-skill-generator # teach the project the /run command

/batch <instruction>

Plan a large-scale edit and run it in parallel across 5–30 isolated working copies, each opening its own pull request. [Skill] You need it where the same edit has to land in dozens of places and each place is a self-contained piece of work. For one edit in a couple of files it's overkill: the overhead of the fan-out eats the whole gain.

The heaviest of the built-in commands and the only one that spawns dozens of agents by default. The instruction first turns into a plan — a list of the concrete places that need editing — and then each place gets its own agent in its own isolated git working copy, and each of them opens a separate pull request.

Isolation is the key part here. The agents edit files in parallel, and without separate working copies they'd step on each other's toes. Hence the requirements: a git repository, a clean tree and a configured gh, otherwise there's nothing to open a pull request with.

The number of agents runs from five to thirty, and it's derived from the plan rather than set by you: as many places as were found, that many agents, up to the ceiling. If the plan comes out at two places, no fan-out is needed, and the command will say so.

There's no separate charge for it, but it eats your plan's limit many times over: twenty agents means twenty sessions, each with its own context.

A good instruction is one where the boundaries of each place are obvious and the edits aren't tied to each other. A bad one is "refactor the project": the plan comes out of vague items, and thirty agents will independently invent thirty different architectures.

The fan-out's behavior is shaped by the worktree settings: symlinkDirectories saves disk space when the project has heavy dependencies, sparsePaths speeds up checkout in large monorepos, baseRef decides whether to branch off the remote main branch or off your current local state.

The order goes like this: first you're shown the plan and asked to agree — that's the moment where it's decided whether as many places were found as you expected. After approval the agents go off to work in the background, and links to the opened pull requests show up as they're ready.

/batch move all controllers over to the new client # a fan-out of isolated agents, each with its own PR
/batch spread the shared DTOs into the modules that use them # if there are few places, no fan-out is needed — the command will say so

/debug [description]

Turn on debug logs for the session and help you get to the bottom of a problem. [Skill] It comes in handy when it's unclear whose trouble this is — yours or the agent's own: the verbose logs show which tools were called and what they answered. The logs stay on until the end of the session and don't carry over to the next one.

The description is optional — with it you say up front what you're chasing.

Without a description it stops at turning the verbose logs on, and you carry on working as usual. With one, the command gets straight to work on the problem you named, leaning on whatever shows up in those logs.

/debug # turn on debug logs
/debug it only fails on CI, green locally # the same plus a description of the problem

/fewer-permission-prompts

Go through the transcripts, find the frequent safe calls and assemble an allowlist out of them. [Skill] The point is to stop confirming the same harmless read ten times a day. The command looks at your own history rather than a generic list, so the permissions come out fitted to this specific project.

The edit lands in the project settings, which means it takes effect for everyone who works with this repository.

What you get is a proposed list of permissions, sorted by what got confirmed most often; it's up to you whether to accept it whole or strike out the extras before it lands in the project settings.

/fewer-permission-prompts # build an allowlist from your history

/commit [wishes]

Put a commit together: look at the status and the diff, write the message in the accepted format. [Skill] The message format is derived from this repository's commit history rather than from generic rules — in someone else's project your commit will look like the ones next to it. It's useful for exactly one reason: it removes two boring steps — deciding what goes into the commit, and putting into words what you actually did.

The argument isn't flags, it's wishes in plain text; the same goes for /pr. Those wishes affect what ends up in the commit and how the message is written.

What goes into the commit message as attribution is set by the attribution object with its commit and pr fields, where an empty string removes it entirely. You can turn the built-in commit instructions off completely with includeGitInstructions: false — then the agent will use only your own rules.

Before the commit is created you can see what was selected for it and in what wording — that's where you decide whether both suit you. The wishes in the second example narrow the commit down to the schema files; everything else stays untouched in the working tree.

/commit # a commit with a message in the project's format
/commit only the schema changes, leave the rest alone # only the schema files go into the commit

/pr [wishes]

Open a pull request: create a branch, push it, write the description through gh. [Skill] The description is assembled from what's really in the diff, not from your retelling of it. The three steps by hand take a couple of minutes, and the description is usually the part people skimp on; here it writes itself.

A branch is created if you're still on the main one. The wishes set the draft flag, the reviewers, the shape of the description.

The steps run one after another — branch, push, creating the request through gh — and at the end you're holding a link to the opened pull request. Wishes like "as a draft" change what the request opens as, but not the order of the steps.

/pr # branch, push, pull request with a description
/pr as a draft, don't assign reviewers # the same, but the request opens as a draft

/commit-push-pr

All three steps in one go: commit, push, pull request. [Skill] The same as /commit and /pr back to back, but with no pauses in between — for when the work is plainly finished and there's nothing to discuss. If you want to look at the commit before it leaves, you're better off with the two separate commands.

It has one quirk: dangerous git and gh flags are not approved automatically. --force, --amend, --no-verify will still ask for confirmation, even if your permissions are generous. That's deliberate: a chain of three steps runs fast, and a human doesn't have time to notice that history is being rewritten somewhere in the middle.

All three steps run without stopping, and at the end you're left with a link to the request. Exactly one thing can break the chain — a dangerous flag along the way: on that one you will be asked whether to go on.

/commit-push-pr # all three steps at once

/update-config

Change settings: hooks, permissions, environment variables — with settings.json edited for you. [Skill] Its main case is behavior of the "every time that…" kind: only a hook can do that, and no amount of asking or memory will get you there, because it's the program itself that runs them, not the model. Say in plain words what should happen, and the command works out which settings file to write it into and in what shape.

Settings come in project and personal flavors, and those are different files: the project ones are seen by everyone who works with the repository, the personal ones only by you. If the edit is about your own habits rather than the shared way of working, say so up front.

Before anything is changed you'll be told which setting will appear and in which file — and if the wrong file got picked, that's exactly the moment to step in.

/update-config add a hook that formats files after edits

/claude-code-docs [question]

Answers about Claude Code itself: features, settings, the SDK, the Claude API, the Slack app. [Skill] It answers from the documentation rather than from the model's memory — and those are different things, because the program changes from version to version faster than the model's knowledge is updated. Better to ask in a human sentence, the way you'd ask a colleague.

What comes back is a breakdown based on the docs with links to their sections — which are also handy for checking that the answer wasn't invented.

/claude-code-docs how to restrict the agent's access to a folder

/claude-in-chrome

Allow work in your Chrome: clicking, filling in forms, reading the console. [Skill] [not on every plan] — it needs a claude.ai account login: with an API key, and through Amazon Bedrock, Google Cloud and Microsoft Foundry, the extension isn't available. The work happens in your real browser, with your tabs and sessions — which is why it fits where what needs checking isn't code but a live page: reproducing a UI bug, walking through a form, looking at console errors.

Access is granted per site and configured in the extension itself: the agent won't go to a page you haven't allowed.

Once called, the agent connects to your browser and works with the allowed tabs from there. If the site you need isn't among the allowed ones, the choice is simple: grant it access in the extension, or give up on this check.

/claude-in-chrome # allow work in the browser

/plugin-types [folder]

Generate input types for the connected MCP tools. The command reads the tool descriptions and lays them out as types, so that in the plugin's code the calls get checked by the compiler instead of being guessed from memory. The argument is the folder of the plugin to generate for. You need it when developing your own plugin; in ordinary work on a project it won't come up.

There's not much to watch here: the command's result is type files inside the plugin folder you named.

/plugin-types ./my-plugin # MCP tool types for the plugin

/workflow-authoring

A reference on writing scripts for workflows. [Skill] It explains what a script is made of, how resuming after a failure works, and what people usually trip over. You read it before writing your own workflow, not while one is running.

It doesn't authorize running a workflow by itself.

What comes back is the reference itself — how a script is built, resuming, the typical mistakes and worked examples — after which you can sit down and write your own.

/workflow-authoring # how to write workflow scripts

/claude-api [migrate|upgrade|prompt-audit|managed-agents-onboard|cost-optimize]

Help with the Claude API and the SDK. [Skill] The only command in this group with a fixed set of arguments. You need it when you're writing code that calls Claude itself: model identifiers, parameters, streaming, tool calling, caching — all of it checked against the documentation rather than the model's memory.

The argument picks the scenario: without one it's a general reference, with one it's concrete work on your code.

ArgumentWhat it does
no argumentGeneral help with the Claude API and SDK: parameters, streaming, tool calling, caching
migrateMigrating code to a new model: what to change in identifiers, parameters and expectations
upgradeMoving to a new major version of the client library; since 2.1.236
prompt-auditFind instructions written for older models in prompts, skills and tool descriptions, and propose the edit as a diff; since 2.1.221
managed-agents-onboardOnboarding onto server-side agents with a managed sandbox
cost-optimizeA breakdown of your API spend and what to do about it; since 2.1.247

The skill also switches itself on without the command: if the project's code imports the official Anthropic library, it activates on tasks that touch it.

With an argument the command first reads your code and comes back with a list of places and proposed edits — whether to accept them all or one at a time is up to you.

/claude-api migrate # migrate to a new model
/claude-api prompt-audit # find instructions written for older models in prompts

/deep-research <question>

A fan-out of web searches across many sources, fact-checking, and a report with links. [Workflow] You reach for it when one search isn't enough: the question is contested, the sources contradict each other, or you need a cross-checked answer rather than the first one that turns up. The search runs along several independent lines, the findings are matched against each other, and the report shows exactly what the conclusion rests on.

Since 2.1.218 it's launched only by you — the agent used to be able to call it itself.

This is a dynamic workflow: a lot of agents get launched, and a single run eats your plan's limit noticeably faster than an ordinary session. On the Pro plan, dynamic workflows have to be enabled first with the Dynamic workflows entry in /config.

The first thing you're asked for is permission to run the workflow — and that's your only choice along the way. After that everything runs in the background, the session stays free, you can follow the progress through /workflows if you like, and at the end a report with links arrives; claims that couldn't be verified are marked as unverified rather than passed off as fact.

/deep-research how approaches to idempotency in queues differ

Subagents, background tasks, automation

/list-agents

Shows everyone you can message straight from the session: subagents you spawned, teammates, other Claude Code sessions on this machine, and cloud ones. The name in the list is the address: copy it and your message goes to exactly that agent. You don't pull the list up out of curiosity — you pull it up when you need to know who's still alive and how to reach them. Alias: /peers.

Teammates (agent teams) are off by default everywhere and are switched on with the CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 variable — until it's set, there will be no rows for them in the list. And keep the price in mind: a team of agents burns roughly seven times as many tokens as an ordinary session, because every teammate has its own context window and keeps spending until it finishes.

The command only prints the list and offers nothing to pick: you take the name of the agent you need from it yourself and plug it into a message.

/tasks

Shows everything running alongside the conversation: background tasks, spawned processes, their state and how long they've been going. This is also where you manage them — the one place that shows every running build and test run at once. Handy when there are several of them and it's unclear which are still alive and which died long ago. Alias: /bashes.

You pick a specific row in the list: from there you can look at that task's output or stop it, without leaving the conversation and without hunting the process down in the system.

/daemon

Manages Claude Code's background services — the ones that run outside your conversation: assistants, scheduled tasks and remote control. You come here when one of them has to be switched on, switched off, or stopped from firing. Note that some of these services — scheduled tasks and remote control — only exist when you're logged into a claude.ai account; with an API key they simply won't be there.

The choice here is between services, not between tasks: you find the row you need and toggle its state, and everything else happens by itself.

/workflows

The history of workflows — the runs where a task is split across many agents that work in parallel. It shows both the running and the finished ones: how many agents, which step, how it ended. This is where a run is paused and resumed — the only place you can influence a long run without killing it outright. Don't confuse it with background tasks: those are about processes and commands, these are about multi-agent runs.

One such run eats noticeably more tokens than the same work in an ordinary conversation — there are many agents, each with its own context. It's billed as ordinary usage; there's no separate bill. When a run has more than 25 agents or the forecast goes past 1.5 million tokens, Claude Code warns you in advance; in ultracode mode the warning isn't shown — by turning it on you already agreed to big runs. On the Pro plan, workflows themselves have to be enabled first in /config.

/loop [interval] [prompt]

Repeat a prompt or a command on an interval; with no interval the pace is chosen for you. Alias: /proactive. [Skill]

The command takes two things in a row: an optional interval and the thing to repeat. What gets repeated can be either a plain prompt or a slash command.

What you passedWhat happens
<interval> <prompt>The prompt runs on a schedule at that interval
<interval> /commandThe same, but a slash command is what repeats
<prompt>No interval given: the agent decides for itself when to wake up next
nothingAn autonomous loop: the agent picks both the task and the pace

The interval is written as a human shorthand: 5m, 30m, 1h. Take the no-interval mode literally: the agent picks the pause based on what it's waiting for. A build that takes eight minutes it will wait out in a single pause, not in eight one-minute checks.

There's exactly one trap, and it's an expensive one: a loop that wakes up every minute to check on a background task is almost always pointless. You'll be told when background work finishes anyway, and every wake-up is a full request carrying the whole context.

What's already running and how often is shown by /usage: the dedicated command for that, /loops, is disabled in build 2.1.251.

The call starts the loop and hands control straight back: from then on it wakes up on its own, and each wake-up looks like an ordinary request in the session.

/loop 5m /code-review low # every five minutes — a quick review pass
/loop 1h check whether new failing tests appeared, and fix the obvious ones
/loop check if the build is broken # no interval: the pace picks itself

/schedule [description]

Creates, updates and runs an agent that works in the cloud on a schedule. [not on every plan] — it needs a claude.ai account login: with a Console API key, under an Anthropic profile, and through Bedrock, Google Cloud and Foundry the command isn't there, and the closest replacement is /loop. [beyond the plan] — the runs themselves count against the plan's usual limit, but the account also has a daily cap on the number of runs: once you hit that or the plan limit, you can only continue on connected credits, and without them the extra runs are rejected until the window resets. Alias: /routines. [Skill]

The difference from /loop is where it runs. /loop works inside your session, on your machine, for as long as it's open. /schedule sets a task up in the cloud: it runs on schedule whether or not your laptop is on.

The argument is a description in words, and the schedule, the task and the intent are all derived from it: the command can not only create, but also update, list, run out of turn and delete. The rest of the requirements are the same as for everything cloud-based: GitHub connected and no ban from the organization — on Team and Enterprise the owner can turn schedules off for everyone. The default environment comes from the remote setting. The whole feature is marked as research, which means it will change.

There's one thing to remember about spend: a scheduled task wakes up and sends the full context even while you're at the computer busy with your own work. It's the least visible line item of them all.

What ends up on screen depends on what you asked for: all four calls below are the same command parsing your description.

/schedule every morning at 9 collect a failing-test report # create the task
/schedule show my scheduled tasks # what's already set up
/schedule run the morning summary right now # an out-of-schedule run
/schedule delete the task about dependencies # delete

/autofix-pr [prompt]

Starts a cloud session that watches the pull request of the current branch and pushes fixes itself — repairing a failing CI build, for instance. [not on every plan] — it runs through Claude Code on the web, and that needs a claude.ai login: with an API key and through Bedrock, Google Cloud and Foundry there are no cloud sessions. The optional argument narrows the mandate: what may be changed and what must not be touched. Control comes back immediately — after that the session lives in the cloud on its own, and that's where you have to look at it.

/autofix-pr # watch the PR and fix CI failures
/autofix-pr only the linter, don't touch the logic # the same thing, but with a limit

Artifacts, documents and design

An artifact is a page published on claude.ai that you can open, click around in and hand to colleagues to look at. Almost everything below is a built-in skill, and what you get depends on the account: some of it is only enabled for certain subscriptions and organizations.

Publishing exists on Pro, Max, Team and Enterprise: on Team it's on from the start, on Enterprise the organization owner turns it on, and with CMEK, HIPAA or a ban on data retention it's closed off entirely. You need a session logged into claude.ai — with an API key, a gateway token or Bedrock, Google Cloud and Foundry credentials the page won't publish. Artifacts aren't billed separately: generating a page spends output tokens like any other answer.

The official command reference lists only /artifacts, /design, /design-login and /design-sync out of this group; the other fifteen or so are [not in the docs] — not in the changelog, not in search, so what's below is what the build actually has, not what was promised somewhere.

/artifacts

Shows your published artifacts and the ones shared with you: the title, the link, when it was updated. [not on every plan] — like everything in this group, it needs a session logged into claude.ai. The main use is practical: finding the link to a page made in a previous session — without it Claude Code will publish a new one instead of updating the old one. It doubles as an inventory: you can see what's already published and whether anything got lost.

The list is interactive: on the selected row the artifact either opens in the browser or its link is copied to the clipboard — you don't have to leave the terminal for that.

/prototype

Turns an idea into a working prototype — a single self-contained page you can open, poke at and show around. [not on every plan] — publishing requires a claude.ai login. You reach for it when arguing in words costs more than just looking: an interface screen, a flow of several steps, a draft landing page. What sets it apart from the design commands below is that it makes a working thing, not a picture.

Nothing is asked up front: you describe the idea in words, the work then runs through to a finished page, and at the end a link to it is what's left.

/prototype a plan picker page: three plans, a month-year toggle, discount math

/doc

Publishes a working document that's edited right on the page: a note, a cheat sheet, an instruction for the team. [not on every plan] — it needs the same claude.ai login. The point is that the document doesn't stay buried in a chat: it has an address, you can open it, add to it and hand out the link. Worth reaching for when the result is meant for people, not for you alone in the terminal.

What kind of document you need is said right in the command; back comes the address of the published page, and from there you edit it either on the page itself or by asking the agent.

/doc turn the decisions from this conversation into a deploy cheat sheet for the on-call

/plan-artifact

Publishes a plan as a separate page you can share: the stages, what follows what, what's needed from whom. [not on every plan] — publishing requires a claude.ai login. Handy when a plan put together in planning mode has to be shown to people rather than retold. The only thing that separates it from /doc is the template: here it's a plan, not an arbitrary document.

From there you spell out what the plan should contain; the result is a page with the stages and a link to it.

Goes through a pull request and lays the analysis out as a separate page: the verdict, the recommendation, the contentious spots, the blind spots. [not on every plan] — publishing requires a claude.ai login. The argument is a PR number or a link to it. You need it when the analysis has to be shown to the author and everyone else; don't confuse it with /code-review — that one hunts for defects and works in the terminal, while this one makes a readable page with a conclusion.

The work happens in two passes and isn't instant: first the PR is read in full, and only then is the page published, and its link is what you get.

/artifact-pr-review 1234

/artifact-dashboard

Builds a dashboard from a ready-made template: metrics, charts, breakdowns on one page. [not on every plan] — publishing requires a claude.ai login. You use it when you have numbers and need to show them whole: project status, the results of a run, metrics for a period. The template sets the layout and the styling — what's on you is the data and knowing what matters in it.

From there you supply the data and say what matters in it; at the end a link to the finished dashboard is what's left.

/artifact-dashboard weekly queue metrics: length, wait time, share of retries

/artifact-report

A report from a ready-made template: the conclusions on top, the detailed sections below. [not on every plan] — publishing requires a claude.ai login. Good for the outcome of an audit, an analysis or a big run, when the result has to be handed to people whole rather than retold in pieces. The difference from a dashboard: here it's text and reasoning, not tiles with numbers.

From there you say what the report is about; the result is a published page and a link to it.

/artifact-report the load test results for the partner team

/artifact-data-table

Publishes data as a table from a ready-made template — a separate page instead of a wall of text in the terminal. [not on every plan] — publishing requires a claude.ai login. You need it when there are more rows than fit in an answer and you want to walk your eyes over them. The data comes from what you supplied or from what piled up in this session.

From there you supply the rows and the columns; at the end, a link to the page with the table.

/artifact-data-table an SLA-by-service table from the latest report

/artifact-explainer

An explainer page from a ready-made template: one topic or mechanism taken apart step by step. [not on every plan] — publishing requires a claude.ai login. You use it when you have to explain how something works to a colleague or a new person on the team, and the explanation should outlive a single conversation. It differs from a report in its job: a report reports a result, an explainer teaches you to understand.

From there you name the topic; the result is a page with the walkthrough and a link to it.

/artifact-explainer how our order idempotency scheme works

/artifact-components

Pulls in the ready-made reusable components an artifact gets assembled from. The point is simple: don't redraw from scratch every time something that's already built and looks decent. It publishes nothing itself — it works on the page you make in the next step.

Nothing appears on screen after the call: the set of components simply lands in the context.

/artifact-design

The styling rules for artifacts: layout, typography, the dark theme and, more importantly, matching the effort to the task. You load it before making a page so that it looks like a finished thing rather than a draft out of a terminal. It publishes nothing and prints nothing.

/artifact-diagramming

How to draw diagrams that show the real mechanism rather than a set of boxes with arrows: when a diagram is warranted at all, what belongs on it and how to keep it legible in the light and the dark theme. You load it when an artifact needs a diagram. It publishes nothing and displays nothing.

/artifact-capabilities

Describes what a published page can do at runtime: read your data, remember what visitors do (a poll, a checklist, a document edited right on the page), keep shared state, ask Claude. You load it before asking for such a page: without it you'll get ordinary static HTML that remembers nothing. Which capabilities you get depends on the account, and the command shows what's available to you specifically.

/dataviz

The styling rules for charts and dashboards: which chart type suits which data, palettes, axes, labels, accessibility, behavior in the dark theme. You load it before the first line of chart code is written — redoing it later costs more. It works beyond artifacts too: the rules are the same for an image and for code in any library.

The call itself outputs nothing: the rules load and take effect on the next chart.

/whiteboard

A shared whiteboard: you draw by hand and the answers come back onto it. [not on every plan] — the board lives as a published page, which means a claude.ai login is required. Good where explaining in words takes longer than sketching: the arrangement of elements, the structure of a screen, the links between parts of a system.

The board opens as a separate page, and the link to it is what you get back from the call.

/whiteboard sketch the exchange between the orders service and payments

/whiteboard-mp

The same thing, but the board is live, and it isn't only a human drawing on it: the agent adds its own on top of yours, and it turns into work for two. [not on every plan] — like the ordinary board, it requires a claude.ai login. You use it when you don't want to "draw and then ask" but to sketch together.

The page works the same way, with the link in the reply; the difference is that from then on one canvas holds both your strokes and whatever the agent drew in.

/whiteboard-mp let's work out together where idempotency gets lost in this scheme

/workshop

Builds a design together with you, one decision at a time: a question — your answer — the next step, instead of a big page made whole in one go. [not on every plan] — the result gets published, so a claude.ai login is needed. Good when you don't yet know what you want yourself and the answer crystallizes as you go.

The conversation starts with a question and goes on in questions to the end; the finished page with its link appears right at the finish.

/workshop a notification settings screen — one decision at a time

/design [sync|login|consent|revoke|import|export|status|description]

The Claude Design hub — the link between Claude Code and the design system on claude.ai. [not on every plan] — it exists on Pro, Max, Team and Enterprise (on Enterprise it's off by default), it needs a session where artifacts work and a version no lower than 2.1.234; on Bedrock, Google Cloud, Foundry and Claude Platform on AWS the command isn't there. It isn't billed separately: the spend goes into the same shared limit as ordinary work.

Officially this is one command "with a design description", while /design-login and /design-sync are two separate ones. In the binary, /design also understands seven subcommands, and that's documented nowhere. The whole thing showed up in version 2.1.234 and is marked as research — meaning it will change.

SubcommandWhat it does
statusShows the state of the connection to Claude Design
loginLogging in, which is also granting access
consentDocumented nowhere
revokeRevokes the access that was granted
importPulls the design system from there into the project
exportPushes the project's design system there
syncThe same as the separate /design-sync command
descriptionThe ordinary call: you say in words what design you need

The subcommands answer differently: status reports the connection state, login sends you off to the browser to confirm access, and import and export move the design system between the project and claude.ai.

/design status # the state of the Claude Design connection
/design login # log in
/design import # pull the design system from there
/design export # push it there

/design-sync [hint]

Assembles a React project's design system straight from the code and pushes it to claude.ai/design, so that everything drawn there looks like your product and not somebody else's template. [not on every plan] — the same requirements as /design: a claude.ai login and artifact publishing available. The argument is a short hint about what to call the upload or what to look at in the project. If access hasn't been granted yet, start with /design-login.

It all happens in one pass and without questions: the project is taken apart, the design system is assembled and shipped off to claude.ai/design — and that's where you look at it.

/design-sync Acme DS

/design-login

Authorizes access to the design system — the very access an upload needs. [not on every plan] — it works wherever the rest of Claude Design works, and it requires a claude.ai account login. It's split out separately because you log in once and upload many times afterwards. If /design-sync complains about access, this is where to start, and the way to check the result is /design status.

The login is confirmed in the browser; after that the access stays granted, and there's no need to repeat it before every upload.

Configuration and interface

/config [key=value]

The settings panel: with no argument it opens a panel with every setting you can change from the interface. It's the main entry point into the agent's whole behavior — from the theme to the model to the operating modes — and looking in here is easier than remembering key names in the settings file. Alias: /settings.

With an argument the setting is applied right away, no panel: /config theme=dark. The full list of accepted keys is printed by /config --help — don't guess, it's shorter than the list of keys in the settings file.

The direct form landed in 2.1.181, named shorthands like theme and model in 2.1.182. It works in non-interactive mode too, and from a phone over remote control, which makes it the main way to change a setting from a script.

There's exactly one limitation, and it isn't obvious: the key=value form can't turn on a setting that needs your confirmation in the panel. It can turn autoContinueAtUsageLimit off, for instance, but not on — turning it on comes with a dialog, and this form has nowhere to show one.

/config # open the settings panel
/config --help # which keys the key=value form accepts
/config theme=dark # set it right away, no panel
/config model=sonnet # same for the model

/permissions

Rules for allowing and denying tools, plus the auto-mode tab. You come here for two reasons: you're tired of confirming the same harmless command over and over — or, the other way round, you need to cut the agent off from something it shouldn't touch. The rule is written into the settings and applies from then on by itself, without asking. Alias: /allowed-tools.

You pick a list first — allowed, denied, or ask-first — and inside it you add your own rule or drop one you don't need; the changes take effect from that moment, no restart required.

/permissions # permission rules

/theme

Change the interface color theme. The theme only affects how Claude Code draws itself in the terminal — code highlighting in diffs, borders, selections; it doesn't touch the terminal's own settings.

Besides light and dark there are colorblind-friendly variants, ANSI variants for terminals with a palette of their own, and auto, which adapts to the terminal background. Your own themes go in ~/.claude/themes/ or come from plugins; the picker itself has an item for creating a new one.

You choose from a list: the selected theme applies to the whole interface and is remembered in the settings, so the next session starts with the same one.

/theme # pick a theme

/keybindings

Open or create the keyboard shortcuts file — ~/.claude/keybindings.json. In it you override interface shortcuts, including chords of two presses in a row. You need it when a shortcut you're used to gets intercepted by the terminal or the multiplexer and never reaches Claude Code at all. The file opens in an editor; if it didn't exist yet, it's created.

/keybindings # your own keyboard shortcuts

/terminal-setup

Configure terminal shortcuts — Shift+Enter for a line break, for example. The edits go into the terminal's own configuration, not Claude Code's: running it once per machine is enough, but after moving to another terminal you'll have to repeat it.

/terminal-setup # Shift+Enter and other terminal shortcuts

/statusline

Configure the status line: with a script of your own, or generated from your shell prompt. The status line is what Claude Code prints by the input box: usually the directory, the branch and the model, but the contents are entirely yours. The script is called whenever the line is refreshed, and whatever it prints ends up in the line.

The choice here is between two paths: build the line out of your shell prompt so it looks like the prompt you're used to — or point at your own script and decide what goes in it yourself.

/statusline # configure the status line

/voice [hold|tap|off]

Voice input. [not on every plan] — dictation requires signing in with a claude.ai account: with an API key and at third-party providers it isn't there. It comes in handy when you need to dictate a long task statement instead of typing it; which mode you pick depends on how you'd rather keep your hands.

What you passedWhat happens
holdHold the button down to talk
tapTap to talk, tap to send
offTurn voice input off

The argument applies right away, without a dialog: dictation switches to the mode you named.

/voice hold # hold the button down to talk
/voice tap # tap to talk, tap to send
/voice off # turn voice input off

/tui [default|fullscreen]

The interface renderer: fullscreen is full-screen and flicker-free, default goes back to the normal one. Full-screen takes over the whole window and redraws itself, so long output doesn't jump around. The normal one writes into the terminal stream, and the terminal scrolls the history itself — if you copy chunks of output with the mouse or rely on terminal scrollback, stay on it.

Switching won't work in every session: if restrictions are in effect that a restart wouldn't carry over — permissions set for this session only, say — the command refuses and changes nothing.

/tui fullscreen # full-screen renderer, no flicker
/tui default # back again
# the refusal in a session with restrictions a restart doesn't carry over
# (this is how it looks in the docs):
Cannot switch renderers in this session — it has restrictions a restart can't carry over (permission rules set for this session only). Nothing was changed. Running /tui fullscreen in a session started without them switches every later session too.

/color [color|default]

The prompt line color for the current session. This isn't a theme, it's the color of the input line specifically; handy when four terminals are open and you don't want to mix them up.

What you passedWhat happens
a color from the paletteThe prompt line is painted in it until the end of the session
nothingA color is picked at random — that's not a bug, it's on purpose
defaultReset to the normal color

The palette is fixed: red, blue, green, yellow, purple, orange, pink, cyan, plus default to reset. If remote control is connected, the color syncs to the web interface too.

/color purple # prompt line color
/color # random color
/color default # reset

/scroll-speed

Mouse wheel scrolling speed. A purely creature-comfort setting: by default the wheel in a long session either crawls or jumps past the spot you wanted, and this is where you fix it. The command opens a speed picker, and you can check the result right there with the wheel.

/scroll-speed # mouse wheel scrolling speed

/focus

Focus view: only your prompt, the tool summary and the final answer stay on screen. Everything in between — call details, the contents of files that were read, long command output — leaves the screen. You need it when the session has grown and the conversation itself gets lost behind the technical output, and also when you're showing the agent's work to someone else.

/focus # keep only the essentials on screen

/hooks

A view of the hooks configured per event. A hook is your own command that Claude Code runs on an event: before a tool call, after a file edit, at the end of a turn. The panel shows what is wired to which event — it's the first place to look when a hook silently doesn't fire.

/hooks # which hooks are configured

/auto-mode-setup

Tell auto mode about your environment and adjust its rules. Auto mode is work without confirming every step, and by default it plays it safe simply because it knows nothing about your project. The command walks through the environment with you and turns your answers into rules: what can be done here silently, and what must not be touched under any circumstances.

/auto-mode-setup # tell auto mode about your environment

/sandbox [exclude "pattern"|install]

Configure the sandbox for commands. The sandbox limits where a running command can write and how it reaches the network, and it's exactly what lets routine work run without confirming every call. The command is only visible where the sandbox is supported.

What you passedWhat happens
nothingThe sandbox panel opens, with dependencies and overrides
exclude "pattern"A command matching the pattern is taken out of the sandbox
installInstall the sandbox itself (Windows)

exclude is for the case where a build or a container command doesn't work inside the isolation and you deliberately pull it out; the list accumulates in the sandbox.excludedCommands key.

/sandbox # sandbox panel
/sandbox exclude "docker *" # take a command out of the sandbox
/sandbox install # install the sandbox (Windows)

/import [codex|gemini] [--dry-run] [--yes]

Migrate configuration from another coding agent: instruction files, MCP servers, commands, subagents and skills. [not on every plan] — unavailable at third-party providers and when server flag loading is turned off. codex and gemini are supported.

ArgumentWhat it does
codex or geminiWhere to migrate from; without an argument you'll be asked
--dry-runShow what would be migrated, changing nothing
--yesMigrate without the interactive picker

In non-interactive mode the command prints what it found and suggests the line that confirms the import. Requires version 2.1.213 or newer.

What matters is what /import does not do: the AGENTS.md file some other agents use isn't read by Claude Code on its own — but /import can carry the configuration from there over into a form it understands.

Without --yes the choice stays yours: the command shows what it found by kind and asks what exactly to take — you can grab just the MCP servers and leave commands and skills as they are.

/import codex # pull in another agent's configuration
/import gemini --dry-run # see what would be migrated
/import codex --yes # migrate without questions

/cloud-plugins

Whether cloud sessions should use the plugins enabled on this machine. [not on every plan] — cloud sessions themselves require signing in with a claude.ai account and aren't available with an API key or at third-party providers. A cloud session runs on someone else's machine, where your set of plugins doesn't exist: this setting decides whether to drag it over there or make do with what's built into Claude Code.

The choice is simple but has consequences: with plugins a cloud session behaves like your local one; without them it works on a bare configuration, but you aren't dragging extra sources into the cloud.

/cloud-plugins # plugins in cloud sessions

/skills

The list of skills, with control over their visibility.

The descriptions of every available skill sit in the context permanently, every session, whether you use them or not. With a large set of plugins that's a noticeable share of the window — which is exactly what the /skills screen is for.

You type and the list filters by name, description and source. The t key sorts by token count, and this is usually where you discover that half the window is taken up by three skills you've never used once. Space or Enter toggles a skill's visibility for the model and for the menu, Esc saves and closes.

Not everything can be toggled: plugin skills, skills with disable-model-invocation: true in the frontmatter, and ones whose visibility is set in enterprise settings or through --settings won't budge. The permanent equivalent is the skillOverrides key, and /skill-doctor helps find the ones that simply go unused.

/skills # the list of skills and their visibility

/plugin

Managing plugins and marketplaces. A marketplace is the source plugins are installed from; a plugin itself brings commands, skills, subagents, hooks and MCP servers all at once, so a single plugin can noticeably change how a session behaves. Through this panel a marketplace gets connected, and a plugin gets installed, disabled and removed. Aliases: /plugins, /marketplace.

The order of selection is: the marketplace first, then a plugin inside it. Some of the changes don't take effect instantly — /reload-plugins finishes them off.

/plugin # plugins and marketplaces

/reload-skills

Pick up skills and commands changed on disk without restarting the session. You need it when you're writing a skill of your own and don't want to restart on every edit. Only the files are re-read — the conversation and its context stay put.

/reload-skills # pick up skill changes from disk

/reload-plugins [--force]

Activate pending plugin changes — the same as /reload-skills, only for plugins. Handy right after /plugin, when the plugin is installed but the session doesn't see it yet.

The meaning of --force here is the opposite of the intuitive one: it is not "reload harder". If the reload would change the set of loaded MCP tools, it will wipe the prompt cache, and the command warns you and refuses to do it — and --force makes it do it anyway. So the flag overrides a refusal, it doesn't dig deeper.

/reload-plugins # apply pending plugin changes
/reload-plugins --force # same, even if it wipes the prompt cache

MCP and integrations

/mcp [reconnect|enable|disable [<server>|all]]

Managing MCP servers and their OAuth authorization. An MCP server is an external process or service that brings its own tools, prompts and resources into the session: an issue tracker, a database, a browser, an internal API. You come here when a server dies mid-task, when it asks you to log in again, or when its tools are only getting in the way right now — an unneeded server is better switched off than kept around with its descriptions sitting in the context. The servers themselves are declared in the configuration; here you only see their current state.

What you passWhat happens
nothingThe list of servers and their state
reconnect <server>Bring a dead server back up
reconnect allReconnect everything
disable <server>Switch a server off for now
enable <server>Switch it back on

Next to each server the list shows whether it's connected, dead, or waiting for authorization — and that's what you decide from: what to reconnect and what to switch off until the end of the session. For a connected server the panel also shows how many tools it exposes, and it flags separately the one that connected but handed over none.

Servers expose their prompts as commands. They show up in the menu as /server-name:prompt-name — and that's the form worth remembering, because the other one, /mcp__server__prompt, works too but only turns up in old articles. Arguments are passed space-separated and split on spaces: every argument is one token, and there's no way to pass a quoted phrase as a single argument.

A server's resources are pulled in with @. The form is @server:protocol://path, and it's a mechanism separate from tools: not "call a tool" but "put this content into the context".

In a background session with no terminal attached the panel won't open at all: the session goes into the "needs input" state, and you're offered the /mcp enable|disable|reconnect <server> form to manage servers.

/mcp # the list of servers and their state
/mcp reconnect github # bring a dead server back up
/mcp disable jira # switch a server off for now
/jira:create_issue login-bug high # a server prompt, the current form

/ide [open]

IDE integrations and their status. That link is what makes edits visible in the editor as diffs and what puts the fragment you select there into the context, so this is the first place to go when "nothing is happening in the editor" — usually it turns out the connection never came up. With no argument it shows the status of the editor integration; with open it opens the file in the connected IDE.

/ide # status of the editor integration
/ide open # open the file in the connected IDE

/chrome

Claude in Chrome settings. [not on every plan] The extension only works when you're logged into a claude.ai account — with an API key and at third-party providers it isn't there. Claude in Chrome is the agent walking around the pages of your own browser: clicking, reading the page, looking at the console. Permissions are granted per site, and nothing runs without them, which is why you look in here before your first browser task.

/chrome # browser-work settings

Account and authentication

/login

Log into an Anthropic account, or switch accounts. This is also where you choose what pays for the work — a claude.ai subscription or an API key from the Console — and that decides more than the bill: some capabilities (web sessions, the mobile app, credits beyond the plan) exist only on a subscription. Login happens in the browser; once you confirm, control comes back to the terminal.

This is where the "you need to log in again" messages send you too: Not logged in · Please run /login, OAuth token revoked · Please run /login, OAuth token has expired · Please run /login — all three are quoted verbatim from the documentation.

/login # log in or switch accounts

/logout

Log out of the account. The stored credentials are wiped and the session can't work any further until you log back in — you need this when the machine is shared or when you want a clean switch to another account.

/logout # log out

/setup-bedrock

Set up Amazon Bedrock: authentication, region, model pins. You need it where the work goes through AWS rather than through Anthropic directly — usually because of a requirement to keep the traffic inside your own cloud. Visible when Bedrock is on.

Together with /setup-vertex it's an example of commands hidden by state: they only appear once the matching provider environment variable is set. Until it is, they aren't in /help either.

/setup-bedrock # set up Amazon Bedrock

/setup-vertex

Set up Google Cloud: authentication, project, region, model pins. The point is the same as with Bedrock: the traffic goes through your cloud and is billed there. Like /setup-bedrock, it's only visible when the provider environment variable is set.

/setup-vertex # set up Google Cloud

/install-github-app

Install Claude GitHub Actions for a repository. It's the app that makes pull request reviews happen on GitHub's side rather than in your terminal. Installed once per repository; the local /code-review doesn't depend on it and works with nothing installed.

/install-github-app # put CI review on the repository

/install-slack-app

Install the Slack app. [not on every plan] Claude Code in Slack requires a claude.ai login — with an API key and at third-party providers it's unavailable. Once it's installed you can hand over a task straight from a conversation and the answer lands in the same place — handy where the discussion is happening in Slack anyway. In a corporate workspace the install can run into admin rights.

/install-slack-app # install the app into Slack

/privacy-settings

Viewing and changing the privacy settings: what leaves your machine out of your work and how it's allowed to be used. You come here before working on closed or someone else's code — to see the current state instead of guessing at it. On corporate accounts some of the switches are locked by organization policy.

/privacy-settings # what leaves the machine

Usage and cost

/usage

Session cost, plan-limit usage and activity statistics. Aliases: /cost, /stats. You come here in two cases: when you need to know whether you'll make it to the limit reset, and when the spend suddenly jumped and you need to see what's driving it.

The screen shows three things: how much this session has spent, how full the plan limits are, and where the tokens are going — broken down by skills, subagents, plugins and individual MCP servers, plus notes on any behavior accounting for more than ten percent of the spend. The d and w keys switch the window between a day and a week, and since 2.1.242 scheduled tasks get their own lines.

Then come four things worth understanding, and not one of them is obvious.

The breakdown is computed from the local session history. That is, from the transcripts on this machine. Work from another computer or from the web interface doesn't land in it — while the limits themselves are shared across the account. The gap between "I've barely spent anything" and "the limit is nearly gone" is usually exactly this.

There are several limits, and switching models helps against only one of them. The "you've run out of the session limit" and "you've run out of the weekly limit" messages are about windows shared by every model — /model won't save you there. Only after "you've run out of the Opus limit" or "the Sonnet limit" will moving to a model from another family put you back to work. Since 2.1.234 Claude Code can wait out the reset and resume the interrupted task by itself; you turn that on through /rate-limit-options and the autoContinueAtUsageLimit key.

The prompt cache lives for an hour only on a subscription. The moment you start spending credits beyond the plan, the cache lifetime drops from an hour to five minutes — and the same lunch break that cost nothing yesterday today means reprocessing the whole context from scratch. On an API key and at the cloud providers it's five minutes by default.

The session counter resets on /clear. Before 2.1.211 it accumulated across clears, so the numbers in older articles don't line up with today's.

If the limits server is unreachable, the screen shows the last data it loaded with a note and offers a retry on the r key. While credits beyond the plan are switched on, they get a line of their own here.

The invisible spend lines that don't show up in the breakdown but really do burn the limit while you're doing nothing: scheduled tasks wake up and go off with a full context; a message from another of your sessions arrives as a new turn (cured by crossSessionInbound: "hold"); active-goal checks start turns while background work is running; every live teammate spends until it finishes. And /compact is a large request in itself, whereas /clear costs nothing.

/usage # limits, spend, breakdown
# the whole output, as the author of a bug report posted it
Session
Total cost: $86.94
Total duration (API): 1h 31m 17s
Total duration (wall): 1d 22h 35m
Total code changes: 2538 lines added, 312 lines removed
Usage by model:
claude-opus-4-8: 9.0k input, 461 output, 50.4k cache read, 29.9k cache write ($0.3802)
claude-haiku-4-5: 2.0k input, 43 output, 0 cache read, 0 cache write ($0.0022)
claude-sonnet-5: 86.5k input, 448.0k output, 197.4m cache read, 3.4m cache write ($86.55)
Current session: 17% used, resets 1:29pm (Europe/Madrid)
Current week (all models): 19% used, resets Aug 13 at 8:59am (Europe/Madrid)
# a separate line in the same place, starting with 2.1.251, about the prompt cache; this is how it looks in the documentation
Prompt cache (main): 14 requests · 91% of input tokens from cache · 2 misses (last 6m 10s ago, 310.2k tokens re-cached) · 1 expected rebuild (compaction or tool-result clearing) · warm (1h TTL, last activity 40s ago)
/stats # the same, opening straight on the statistics tab
/cost # the same, in the usual view

/usage-credits

Set up credits so you can keep working once you hit the plan limit. [not on every plan] The command only works after logging in with a claude.ai subscription through /login; with API-key authentication it isn't there. Credits are spend paid on top of the subscription at the usual API rates, billed separately from the plan. Without them, a spent limit means simply waiting for the window to reset; with them you get an offer to continue, and the work from there on costs money.

Where exactly the command takes you depends on your role: a Pro or Max subscriber goes to the usage page on claude.ai, a Team or Enterprise member with billing access goes to the admin settings, and a member without that access is asked to confirm and has a request sent to the organization's admins. On the page itself you choose three things: whether credits are on or off, whether to set a monthly spending cap or lift it, and topping up the balance. For people who subscribed through the mobile app, enabling and topping up only work in the web version.

Remember the side effect described above: once you start spending beyond the plan, the prompt cache lives five minutes instead of an hour.

/usage-credits # switch on credits beyond the plan

Remote work and environments

/desktop

Continue the current session in the desktop app. [not on every plan] The app needs a claude.ai login — on an API key and at third-party providers it isn't there. The session moves over together with its context and history: you don't have to state the task again. Useful when the work is easier to continue in an app window than in the terminal. Alias: /app.

/desktop # continue in the app

/teleport

Pull a web session into this terminal. [not on every plan] Web sessions are a research preview for Pro, Max and Team (on Enterprise you need a suitable seat type), require a claude.ai login and are unavailable on Bedrock, Google Cloud and Microsoft Foundry. The context, the history and the state of the work move over to you and from there you work locally — you need this when the task was set from a phone or a browser but finishing it is easier by hand. You pick from your own active web sessions; after the pick, the terminal continues the one you named. There's no separate charge for the cloud machine; it spends the account's usual limits. Alias: /tp.

/teleport # take a web session into the terminal

/remote-control

Open the session up to control from a phone or from the web. [not on every plan] Requires a claude.ai login; with an API key it's unavailable. The work itself stays on your machine — from outside you only send requests and read answers, so access to the repository and the environment goes nowhere. Handy when something long is running and you want to keep an eye on it without sitting at the desk. Alias: /rc.

The refusal is clear enough: if the session isn't running through api.anthropic.com, the command names the reason outright and says which environment variable to unset.

/remote-control # open the session up to a phone
# the refusal when CLAUDE_CODE_USE_BEDROCK is set — this is how it looks in the documentation
Remote Control is only available when using Claude via api.anthropic.com. CLAUDE_CODE_USE_BEDROCK is set, so this session is using Amazon Bedrock — unset it (or run in a shell without it) to use Remote Control.

/session

Show the remote session's address and a QR code for it. You need it after /remote-control, when the link got lost or you're connecting a second device: with a phone it's easier to point the camera than to copy the address by hand. It works wherever remote control does — that is, when logged into claude.ai. Alias: /remote.

/session # the session address and a QR code

/remote-env

The default environment for web sessions and teleport. The point is for the cloud machine to start up already prepared for your project instead of empty: otherwise the very first build or test run trips. Set up once, then applied to every new web session. It only concerns the web side, which needs a claude.ai login.

/remote-env # the default environment for the web

/web-setup

Connect GitHub to Claude Code on the web through the local gh. That is, hand outward the access already configured on your machine instead of authorizing separately in the browser. Done once; without it a web session won't see private repositories. Like everything on the web side, it requires a claude.ai login.

/web-setup # connect GitHub to the web
# this is how it looks in the documentation
Connected as <your-github-username>

Diagnostics and help

/help

Help and the list of available commands. The list is assembled for your session: commands hidden by state (like the cloud-provider setup) or switched off by an admin won't appear in it — which makes it the honest answer to "what do I actually have", unlike the documentation. A good check after installing a plugin: its commands should show up here.

/help # what's actually available

/status

Version, model, account, API connectivity and tool statuses. The first place to go when the behavior doesn't match expectations: the wrong model, the wrong account, a setting that never arrived. It works even while an answer is being generated.

It opens the settings panel on the status tab. Besides the version, model, account and connectivity, there's a line for the kind of session: interactive for an ordinary one, background job · attached or background job · unattended for a background one — depending on whether a terminal is attached to it. The line appeared in 2.1.221.

Plus, since 2.1.243, a line in the same place about skipped sources of enterprise settings: if an admin dropped in a policy file but a different, higher-priority one is in force, you'll see here exactly which one is being ignored. It's the first thing to look at when "the admin's setting never arrived".

Per the documentation, the same tab can carry lines for the profile, the login method, the API key, the host address and the proxy, and behind a corporate gateway — provider lines with its base address.

/status # version, model, account, connectivity
# lines from the status tab, as the author of a bug report posted them (build 2.1.199)
Version: 2.1.199
Session ID: 352ea81c-819d-4028-bba5-daef515d0815
Login method: Claude Enterprise account
Model: claude-fable-5[1m] (claude-fable-5)
Setting sources: User settings, Enterprise managed settings (remote)

/doctor

Diagnosing the installation and putting the configuration in order. Alias: /checkup. You come here when CLAUDE.md has grown and every request drags along kilobytes of instructions, or when something behaves oddly after an update.

Since 2.1.205 this isn't a screen with a report but a full skill that edits your configuration. What it does: clears out duplicates between the local and the committed CLAUDE.md; trims the committed one, throwing away what the agent would work out from the code anyway; moves permanently loaded instructions into skills and nested files loaded on demand; offers to make auto mode the default and to pre-approve the safe commands you've been denying most often. It shows the findings first, then makes the changes.

The check picks up what's next to it as well: the health of the installation, broken settings files, unused extensions and same-named subagents in one folder — every finding comes with a proposed fix.

The terminal claude doctor is still diagnostics with no edits and no session start; it reads the settings files in the current folder without asking you to trust it.

The command stays available even when the bundled skills are switched off entirely: it's specifically marked as surviving disableBundledSkills. You can hide it with the DISABLE_DOCTOR_COMMAND variable or a "doctor": "off" entry in skillOverrides.

/doctor # check and fix the configuration

/feedback [report]

Send feedback about Claude Code. You can pass the text right in the argument or type it into the field that opens. It fits "it doesn't work the way I expected" and wishes; for a concrete breakage with the conversation attached there's /bug.

/feedback # send feedback
/feedback edits are applied but never show up in the diff

/bug [report]

Report a bug or share the conversation. It's also what you use when you just want to hand someone a whole session turn. Before attaching the conversation it's worth remembering what's in it: internal service names, pieces of private code and everything that landed in the context go along with it. Alias: /share.

Before sending, the command asks whether to attach the conversation.

/bug # report a bug

/heapdump

Take a memory dump — for diagnosing high memory use. Hidden.

It writes a memory snapshot and a consumption analysis to the desktop (to the home folder on Linux without a desktop). The command is hidden not by a server flag but by not being shown in the menu: type it out in full and it works. An important warning: when you contact support, attach only the analysis file — the snapshot itself contains your whole conversation and your credentials, and must not be shared.

/heapdump # memory dump to the desktop

/insights

An analysis report on your sessions: areas of the project, work patterns, points of friction. It's a look at habits, not at money — how much was spent is what /usage shows. Worth looking at once every few weeks: the report usually surfaces something that should long since have been moved into CLAUDE.md or into a skill.

One run analyzes up to two hundred sessions it hasn't seen yet; very short ones are skipped. If anything was left out, the report header carries the total next to the analyzed count — for example, 200 sessions (412 total).

/insights # an analysis of my sessions

/skill-doctor

Which of the loaded skills go unused and take up context for nothing. Every enabled skill costs room in the window: its description is always loaded, its body only when it fires, and a dozen forgotten skills noticeably narrows the useful context. From the results you decide what to switch off and what to rewrite so that it fires when it should.

/skill-doctor # which skills hang in the context for nothing

/explain-usage

Where this session's tokens went, in plain language. [Skill] Unlike /usage, with its numbers and breakdown, here you get an analysis with conclusions: which turns came out expensive and why. Useful when the limit is melting faster than expected and the table doesn't make it clear what to do about it.

/explain-usage # where the tokens went

/install [version] [--force]

Install a native build right from the session — no package manager, no leaving for the terminal. Useful for moving off an npm install onto the native one, or for rolling back to a specific version when a fresh one broke something important. The argument is the version: stable or a concrete number; --force installs it over the current one.

/install stable # install the stable build
/install 2.1.236 --force # a specific version, over the current one

Information and documentation

/release-notes

The list of changes by version: what appeared, what got fixed, what got switched off. Worth reading after every update — a noticeable share of Claude Code's behavior changes from build to build, and "it worked yesterday" is most often explained right here.

A nice detail: the notes are printed into the transcript but don't land in the model's context. That wasn't always the case, and showing all the changes used to mix the whole changelog into every subsequent request.

/release-notes # what changed, version by version

/powerup

Short interactive lessons on the features. The point is that much of this doesn't find you on its own: plans, skills, background tasks, hooks. A lesson runs right inside the session and takes a couple of minutes — it's a way to learn about one thing rather than read the whole documentation.

/powerup # a short lesson on the features

/mobile

A QR code for installing the mobile app. The app is there for working away from your desk: set a task on the move and check how it ended. Aliases: /ios, /android.

/mobile # the mobile app's QR code

/radio

The Claude FM lo-fi radio in the browser. Exactly what it looks like: background music, nothing to do with the agent's work.

/radio # background music

/passes

Share a free week with friends and get credits. Not everyone sees the command: it only appears on accounts that have it available — so someone else's /help may not have it.

/passes # share a free week

/upgrade

Move up to Max: higher limits, more Opus. You usually land here straight from a message about a spent limit. If what you're hitting is a specific model rather than the plan, it's cheaper to try /model first — switching model family is exactly what clears that case.

/upgrade # move up to Max

/stickers

Order stickers. Nothing to do with the agent's work: an order form opens.

/stickers # order stickers

/team-onboarding

Generate a team onboarding guide from your usage history. The point is not having to write such a document from scratch: it's assembled from how you actually work, not from generic advice. What comes out is text you edit by hand and put in the repository.

/team-onboarding # a team guide from my history

Removed and disabled commands

They have no sections of their own — there is no point typing them. The table is here because half the articles on the internet still recommend them, and when a command "doesn't work", this is the easiest place to look.

Removed entirely:

CommandWhat happened to it
/vimRemoved in 2.1.92. The key mode is switched in /config with the "Editor mode" field, or with the editorMode key.
/pr-commentsRemoved in 2.1.91. Just ask the agent to show you the pull request comments.
/output-styleDeprecated in 2.1.73 and removed in 2.1.91. The reply style is set with the outputStyle key.
/ultraplanRemoved. Use planning mode instead, /plan.
/agentsFormally still there, but all it does is tell you that subagents are created as files in .claude/agents/. Background agents are claude agents in the terminal.
/extra-usageRenamed to /usage-credits in 2.1.144.
/init-verifiersNever existed — if you met it in somebody's article, it's an invention.
--enable-auto-modeThe flag was removed in 2.1.111. Use --permission-mode auto instead.

Disabled from the inside in build 2.1.251: registered, but they don't work and don't show up in the menu.

CommandWhat to use instead
/versionThe session version is shown by /status, the binary version by claude --version.
/update (alias /restart)To update, run claude update in the terminal.
/loopsWhat is running and how often is shown by /usage; the loops themselves are created by /loop.
/wellbeing (aliases /breaks, /break-reminder, /downtime)The settings themselves work: the breakReminder and quietHours objects in the settings file.
/pause-memory (aliases /memory-pause, /toggle-memory)Auto-memory is turned off with the autoMemoryEnabled key.

There are also commands that appear depending on state, and you won't see them until that state arrives: /limit-reset and /low-priority — when you've hit the session limit, /rate-limit-options, /pro-trial-expired, /design-consent and /design-revoke, while /setup-cowork only lives in Cowork mode. Plus two entirely internal entry points, __remote-workflow and workflow-launch-exec, through which the server hands a ready-made workflow to the session.

And a category of its own — model-only skills: keybindings-help, memory-types, cowork-plugin. The agent pulls them in by itself; you can't type them. The mechanism is general and available to you too — it's the user-invocable: false field in a skill's frontmatter.

Two stubborn misconceptions to finish with. There is no /alias command: what sits in the binary under that name is a description of the system alias utility, used for completing commands entered with !. And there is no .claudeignore file either — to make the agent ignore files, use .gitignore, which is respected by default, or .ignore.

How the menu finds a command

A small thing that saves your nerves. Since version 2.1.236 the menu highlights a command if the letters after / match its name or one of its aliases — from the start of the name or from the start of a word inside it, with the separators :, _ and - ignored during the comparison. That's why /adddir highlights /add-dir, and /new highlights /clear through its alias.

What changed at the same time and matters more: a typo is no longer guessed. Enter on a non-existent command used to launch a similar one. Now nothing is highlighted after a typo, the close matches stay in the list and are picked with the arrows or Tab, but Enter sends your text as-is and reports an unknown command.

Unavailable commands simply vanish from the menu — you'll see "no commands match your query". Some answer with their own unavailability message instead: /schedule on an API key, for example, will say it requires an account. And you can't drag a hidden command out by a partial name — you have to type it in full.

Your own commands

Your own slash command is a SKILL.md file in a skill folder. There used to be a separate entity for this in .claude/commands/; commands and skills are now merged into one, and the old files keep working and give you exactly the same command.

Where to look and where to put them:

LocationScopeCommand name
~/.claude/skills/<name>/SKILL.mdpersonal, in every project/<folder name>
<project>/.claude/skills/<name>/SKILL.mdproject-level, committed/<folder name>
.claude/commands/<name>.mdthe old form, still works/<file name>
a pluginwherever it was installed from/<plugin>:<name>

The command name comes from the folder name, not from the name field. For personal and project skills, name is only the label in the list. For plugin ones it's the other way round: name replaces the last segment, so my-plugin/skills/review/ with name: fancy gives /my-plugin:fancy. The short form /fancy works too, as long as nobody else has taken that name.

The simplest example:

.claude/skills/fix-issue/SKILL.md
---
name: fix-issue
description: Work through an issue by number, find the cause and propose a fix
argument-hint: <issue number>
allowed-tools: Bash(gh issue view:*), Bash(gh pr create:*)
---
Take issue number $0 from this repository.
The current state of the branch:
!`git status --short`
Read the description, find the cause in the code, propose the minimal fix
and explain why it is minimal.

You call it as /fix-issue 4821. Here $0 is the first argument, that is 4821, and the line with ! runs before the text reaches the model and is replaced with its own output. More on both below.

Frontmatter fields

There are twenty of them. It's useful to know they exist at all — half of them solve problems people otherwise solve with hacks.

FieldWhat it sets
nameThe name; for personal and project skills, only the label
descriptionThe description the model uses to decide whether the skill fits
when_to_useA clarification of when to pick it
argument-hintThe argument hint in the menu
argumentsA list of named arguments mapped positionally onto $name
disable-model-invocationForbid the model from invoking the skill by itself
user-invocablefalse — the skill is model-only, you can't type it
allowed-toolsWhat to pre-approve for this turn
disallowed-toolsWhat to forbid
modelThe model for the rest of the turn; accepts inherit
effortThe effort level: from low to max
contextfork — run the skill in a subagent
agentWhich agent type to take with context: fork
backgroundfalse — wait for the forked skill's result
hooksHooks that live together with the skill
pathsRestrict automatic activation to these paths
shellWhat to run embedded commands with: bash or powershell
metadataArbitrary data
licenseThe license
compatibilityCompatibility requirements

Three limitations people trip over. Frontmatter is read only if the opening --- is the very first line of the file. The description and when_to_use fields are cut down to fifteen hundred characters in the listing — anything longer the model won't see when it's choosing a skill. And in the old files in .claude/commands/ the same frontmatter works, except for name and paths — those are ignored there.

A separate word about allowed-tools: it's a pre-approval for one turn, not a restriction. The permission is dropped with your next message, though the skill's content stays in the context. And it has an unpleasant property worth knowing for anyone who runs the agent in someone else's repository: folder trust does not hold it back. A project skill applies its allowed-tools even in a folder you never marked as trusted, non-interactive runs included. Which means a skill sitting in a repository can grant itself broad rights — read this field in other people's repositories before you run anything.

Arguments: numbering starts at zero

The most unexpected corner of the whole topic, and one worth memorising word for word.

SubstitutionWhat gets substituted
$ARGUMENTSThe whole argument string exactly as you typed it
$ARGUMENTS[N]The argument at that index, indexing starts at zero
$NThe short form: $0 is the first argument, $1 the second
$nameAn argument from the arguments list in the frontmatter, by position

Yes, $0 is the first argument, not the command name as in a shell. The off-by-one here is the most common mistake.

Indexed arguments are parsed with quoting in mind: in /my-skill "hello world" second the value of $0 is hello world as a whole. An indexed substitution that ran out of arguments stays in the text as-is; a named one turns into an empty string. An argument value that itself contains $1 or $ARGUMENTS is inserted literally and not expanded a second time. Escaping uses a single backslash: \$1.00. And if no substitution in the body got any arguments at all, the line ARGUMENTS: <value> is simply appended at the end.

Embedded shell commands

The form !`command` runs before the content reaches the model and is replaced with its output. That's how a skill gets the current state fed into it: the branch, the diff, the list of failing tests. Which shell runs it — bash or powershell — is set by the shell field in the frontmatter.

There are two rules that save you half an hour of head-scratching. The form is recognised only if the ! stands at the start of a line or right after a space — in KEY=!`cmd` it stays text and doesn't run. And the substitution pass goes over the file once: a command's output is not scanned again, so a command can't print another substitution and count on a second pass.

For a multi-line script, open a code block with an exclamation mark after the three backticks.

All of this is switched off with the disableSkillShellExecution key: every command is replaced with a stub saying it's forbidden by policy. It applies to user, project and plugin skills and to skills from added folders; built-in and enterprise ones are left alone. Skills synced from claude.ai never run such commands locally, whatever the setting says.

Path variables

Inside a skill's body and inside allowed-tools rules these get substituted: ${CLAUDE_SKILL_DIR} — the skill's own folder, ${CLAUDE_PROJECT_DIR} — the project root, ${CLAUDE_SESSION_ID}, and in plugin skills also ${CLAUDE_PLUGIN_ROOT} and ${CLAUDE_PLUGIN_DATA}.

The fact that they work in both places isn't a detail, it's a working trick: it's how a skill runs its own script without a single question about permissions.

.claude/skills/render/SKILL.md
---
name: render
description: Render a diagram from its source
allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/render.sh *)
---
Run `${CLAUDE_SKILL_DIR}/scripts/render.sh $0` and show the result.

The rule allows exactly the command the body tells it to run — no wider, no narrower.

Small things worth knowing

Skills stack. You can put up to six commands at the start of one message: /write-tests /fix-issue 123 loads both skills and passes 123 to both as arguments. Before version 2.1.199 only the first one was loaded and the rest counted as text. The exception is /code-review, which takes the rest of the line for itself.

ultrathink in a skill's body asks the model to think harder when the skill fires. It works as a plain word in the text.

Built-in command names are reserved, even if they're unavailable in your session: a skill with a conflicting name that arrives from sync will be skipped.

You can validate a skill without a plugin: claude plugin validate <path> works on an ordinary folder of skills and agents too. And to turn a folder of skills into a plugin, it's enough to drop .claude-plugin/plugin.json into it.

Settings: settings.json

Next come the keys of the settings file, experimental and enterprise ones included, with types and examples. The list is merged from two sources: the official settings reference, which currently holds about two hundred and twenty entries, and the validation schema inside the CLI itself. They don't match: the schema has keys the documentation doesn't, and the other way round — the documentation has keys the schema knows nothing about, because they live in a different file. More on that separately below.

Notation: [exp] — an experimental or internal key, may change or disappear; [admin] — takes effect only from an enterprise source; [deprecated] — deprecated; [global] — lives not in settings.json but in ~/.claude.json.

Where the file lives

There aren't four levels, or five, but more than is usually written about. Let's start with the ordinary ones:

LevelFilePurpose
User~/.claude/settings.jsonPersonal settings across all projects
Project<project>/.claude/settings.jsonTeam settings, committed to the repository
Local<project>/.claude/settings.local.jsonPersonal, for one specific project, in .gitignore
Command line--settings <file or JSON>For a single run only
Policydepends on the systemEnterprise policy
Global config~/.claude.jsonSettings that are ignored in settings.json

That last row is the one almost nobody mentions. Some settings live only in ~/.claude.json, and if you write them into settings.json they're silently ignored. That's also where Claude Code keeps your login session, the MCP server configuration and folder trust decisions. Normally this file writes itself and people rarely go into it by hand — but you need to know it exists, because "I set the key and nothing happened" is most often explained by exactly this.

Enterprise policy isn't a single thing either. There are four sources, and they're ranked:

RankSource
1Server-side settings from claude.ai or an enterprise gateway
2Operating system policy: the managed settings domain on macOS, the HKLM\SOFTWARE\Policies\ClaudeCode registry key on Windows
3The managed settings file: /Library/Application Support/ClaudeCode/managed-settings.json, /etc/claude-code/managed-settings.json, C:\Program Files\ClaudeCode\managed-settings.json
4The same registry key, but in HKCU — writable by the user themselves, and therefore not counted as administrative and applied only where nothing above it exists

The system policy and HKCU are re-read every half hour, the server-side settings once an hour. By default the sources do not add up: the highest-ranked one applies and the rest are dropped. You can change that with the managedSourcesBehavior: "merge" key, but it has to be set in the highest of the deployed sources — a lower one can't ask itself into the merge, and HKCU is never merged.

If an admin put something in place and it "didn't arrive", look at /status: since version 2.1.243 there's a line there about skipped sources that says outright which file was ignored.

The format: strict JSON

Here I have to correct myself, because I used to think otherwise and the internet repeats it often.

Settings files are strict JSON. A // comment or a trailing comma is a syntax error, and on the next run the file will be flagged as broken as a whole. No JSONC. (The confusion comes from JSONC really being in the product elsewhere — /terminal-setup, for example, parses the editor configuration with comments in it.)

The easiest way to check your file is to run it: settings errors are printed at startup. claude doctor will show them broken down.

A useful habit is the $schema line:

.claude/settings.json
{
"$schema": "https://json.schemastore.org/claude-code-settings.json"
}

Your editor will start suggesting key names and underlining typos, and a typo in a key name is the most common reason a setting "doesn't work": unknown keys are silently ignored. One caveat: the schema sometimes lags behind the product. teammateDefaultModel, for instance, is still in it, but it was removed from Claude Code in 2.1.234 and affects nothing.

Who overrides whom

The order of the levels is the one in the table above. But "overrides" isn't true for everything, and here are the three exceptions that break the intuition.

Lists add up, they don't replace. If permissions.allow is set both in the user file and in the project one, you get the union of the two. An upper level cannot remove an entry from a lower one — the only thing that can is the enterprise allowManagedPermissionRulesOnly. Any priority table that says "each next one overrides the previous" is wrong for lists.

Four lists behave differently: fallbackModel is taken whole from the highest file that defines it (it's an ordered chain, and mixing it makes no sense); modelPicker — whole from the highest among the enterprise source, --settings and the user file, while in the project and local files it's ignored; availableModels from the admin applies as-is, without picking up your additions; modelSettings is resolved separately for each model.

For seven keys, a stricter value from below beats the enterprise one. Normally policy is absolute — not even --settings overrides it. But for these keys the stricter variant from any level wins, because nobody is going to stop you from forbidding yourself more than you have to: disableClaudeAiConnectors with the value true, enableArtifact with the value false (and disableArtifact: true), isolatePeerMachines with the value true, remoteControlAtStartup with the value false from a project or local file, crossSessionInbound with a stricter value on the "accept — hold — reject" scale, useAutoModeDuringPlan and syncClaudeAiSkills with the value false.

Project permissions wait for folder trust. permissions.allow and permissions.additionalDirectories from the project file only start working once you've confirmed trust for that folder. deny and ask take effect immediately — they only restrict.

And what comes next is the most important part, worth reading for everyone who runs claude -p in someone else's repository. In non-interactive mode the trust dialog isn't shown, so the project's permissive rules are dropped with a warning on the error stream — but that repository's hooks do run, its env block is applied, its authentication helper scripts are launched, the allowed-tools field of its skills takes effect, and the servers from its .mcp.json connect without asking. What gets dropped is the permissions, not the executable parts.

A safe run in an unvetted folder is --setting-sources user, --bare, --restricted or --settings '{"disableAllHooks": true}'. Simply setting disableAllHooks in your own user file is not enough: the project file ranks higher and will turn it back on.

Environment variables aren't a level

Another thing that's usually drawn wrong. Environment variables don't sit "between" the settings levels: who overrides whom is decided separately for each variable-and-key pair.

  • ANTHROPIC_MODEL from the shell overrides the model key from any file.
  • ANTHROPIC_DEFAULT_MODEL only takes effect if model isn't set anywhere.
  • --model and /model override ANTHROPIC_MODEL.
  • And CLAUDE_CODE_EFFORT_LEVEL works the other way round and overrides --effort and /effort.

And separately: a value from the env block in the settings beats an export from the shell, not the other way round as people tend to assume. Claude Code writes every entry of the block into the process environment on top of the inherited value. You can't delete a variable from the settings file — you can set it to an empty string, which counts as "not set" when a provider is being chosen (though child processes will get the empty value). Shell variables are read once at startup, while values from env are re-read when the file changes — except in subsystems that are only configured at launch, like telemetry.

The skeleton of the file

Scalars like model, theme, numbers and flags are written at the top level. Grouped settings — permissions, env, hooks, statusLine, worktree, voice, sandbox, sshConfigs — are nested objects.

.claude/settings.json
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"model": "opus",
"outputStyle": "default",
"theme": "dark",
"autoCompactEnabled": true,
"cleanupPeriodDays": 30,
"includeCoAuthoredBy": false,
"env": {
"CLAUDE_CODE_USE_POWERSHELL_TOOL": "1",
"DISABLE_TELEMETRY": "1"
},
"permissions": {
"allow": ["Bash(npm run build)", "Edit(src/**)"],
"ask": ["Bash(git push:*)"],
"deny": ["Read(./.env)"],
"defaultMode": "acceptEdits",
"additionalDirectories": ["../shared-lib"]
},
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{ "type": "command", "command": "npm run lint" }]
}
]
},
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh",
"padding": 1
},
"worktree": {
"symlinkDirectories": ["node_modules"],
"baseRef": "fresh"
},
"enabledPlugins": {
"formatter@anthropic-tools": true
}
}

Authentication and providers

SettingTypeWhat it does
apiKeyHelperstring, path to a scriptA script that prints the authorization value to standard output. Handy for temporary and rotated keys.
proxyAuthHelperstring, command[experimental] A command that prints the proxy authorization header value.
awsCredentialExportstring, pathA script that exports AWS credentials for Bedrock.
awsAuthRefreshstring, pathA script that refreshes AWS authentication before it expires.
gcpAuthRefreshstring, commandA command that refreshes Google Cloud authentication.
otelHeadersHelperstring, pathA script that prints HTTP headers for telemetry export.
policyHelperobject[admin] An executable that computes policy settings at startup: path, timeoutMs, refreshIntervalMs.
policyHelpersobject keyed by OS[admin] The same, but separately for macOS, Linux, Windows and WSL.
forceLoginMethodclaudeai, console, gatewayPin the login method: subscription, billing through the Console, or a corporate gateway.
forceLoginOrgUUIDstring or array[admin] Allow login only into the named organization, or into any one from the list.
forceLoginGatewayUrlstring, URL[admin] Mandatory corporate gateway address for login.
forceRemoteSettingsRefreshboolean[admin] Block startup until fresh policy settings have been pulled.
parentSettingsBehaviorfirst-wins, merge[admin] How the parent layer coming from the SDK combines with the admin one.
xaaIdpobject[experimental] Hooking up an external identity provider: issuer, clientId, callbackPort.

The gateway value of forceLoginMethod is only honoured from a source that lives on the machine itself: the policy file, the macOS settings domain, or the HKLM branch. In user, project, local and HKCU settings it counts as unset — otherwise corporate login could be redirected from a repository.

Model, thinking, effort

SettingTypeWhat it does
modelstringThe default model: an alias or a full identifier.
availableModelsarray of strings[admin] Model allowlist. An empty array means the default model only.
enforceAvailableModelsboolean[admin] Apply the allowlist to the "default" entry in the model picker as well.
modelOverridesobject[admin] A mapping from Anthropic identifiers to provider identifiers.
modelPickerobjectYour own list in /model: entries of {model, label, description}; replaceBuiltInOptions replaces the built-in one.
modelSettingsobjectSettings tied to a specific model — right now, the effort level.
modelPricingobject[admin] Your organization's rates instead of the price list: a discount multiplier and per-unit prices.
advisorModelstringThe model for the advisor.
agentstringThe agent name for the main thread: its system prompt, its restrictions and its model.
alwaysThinkingEnabledbooleanfalse turns thinking off.
showThinkingSummariesbooleanShow thinking summaries in the conversation and in the transcript.
effortLevellow, medium, high, xhighThe saved effort level. The schema does not accept max.
ultracodeboolean[experimental] xhigh plus permanent workflow orchestration.
fastModebooleanWhether fast output mode is on.
fastModePerSessionOptInbooleanDon't carry fast mode over between sessions.
autoCompactEnabledbooleanCompact the conversation automatically as the context fills up.
autoCompactWindownumber, 100000–1000000The size of the auto-compaction window, in tokens.
precomputeCompactionEnabledbooleanPrepare the compaction ahead of time, while work is still going on.
switchModelsOnFlagbooleanSwitch to a different model when a safety filter fires. Defaults to true.
fallbackModelarray of stringsModels to fall back to when the primary one is overloaded; tried in order.
promptCacheTtl5m, 1hThe prompt cache lifetime for the main conversation.
subagentPromptCacheTtl5m, 1hThe same for subagents; five minutes by default.

Three defaults that change behaviour and that hardly anyone writes about.

switchModelsOnFlag is on. Which means that when a safety filter fires, the model quietly changes so the conversation isn't interrupted. Turn it off and an interactive session will stop and ask you, while a non-interactive run will fail the request with an error — which is often the better choice for scripts, because a silent model swap in CI looks like an unexplained change of behaviour.

promptCacheTtl picks itself: an hour on a subscription, five minutes otherwise. The environment variable overrides it.

effortLevel refuses max deliberately, so that the maximum level never stays switched on forever; you set it for one session with a command or a flag.

Tool permissions

The most practically important part of the file — and the most underrated for the sheer number of gotchas in it. The nested permissions object:

FieldTypeWhat it does
allowarray of rulesWhat's permitted without asking.
denyarray of rulesWhat's forbidden always.
askarray of rulesWhat always requires confirmation.
defaultModesee belowThe default mode.
disableBypassPermissionsMode"disable"Forbid the permission-bypass mode.
additionalDirectoriesarray of pathsExtra directories inside the access scope.

Alongside them sit top-level keys: skipDangerousModePermissionPrompt and skipAutoPermissionPrompt remember that you've already accepted the corresponding warning; allowManagedPermissionRulesOnly [admin] tells it to honour only the lists coming from policy; disableAutoMode turns auto mode off; useAutoModeDuringPlan allows it inside plan mode, and defaults to yes.

Modes

ModeWhat it does
defaultThe usual one: ask when it needs to. The alias is manual, accepted in settings too since 2.1.200
acceptEditsAccept file edits automatically
planAnalysis only, change nothing
autoA classifier makes the call
dontAskAutomatically refuse anything that would have needed a question
bypassPermissionsAccept everything

dontAsk doesn't mean "don't bug me about the small stuff". It's the most dangerous misunderstanding in the whole permissions topic, and I've made it myself. The mode doesn't loosen things, it tightens them: everything that would raise a question in normal mode is automatically denied. Only what made it into allow, the built-in set of safe read commands, and whatever a hook approved will run. Your own ask rules don't ask in this mode, they refuse; a question from the agent to you gets rejected as well, even when it's permitted.

One more subtlety: the auto value has no effect from project and local settings — it has to be set in the user file. And sessions launched from the VS Code extension read only the user file, the enterprise one, and --settings.

Rule format

A rule is written as Tool(specifier): Bash(npm run build), Edit(src/**), Read(~/.zshrc).

.claude/settings.json
{
"permissions": {
"allow": ["Bash(npm run:*)", "Edit(src/**)", "Read(~/.config/**)"],
"ask": ["Bash(git push:*)"],
"deny": ["Read(./secrets/**)", "Read(./.env)"],
"defaultMode": "acceptEdits",
"additionalDirectories": ["../shared", "/tmp/workspace"]
}
}

Looks simple. What follows is twelve rules of behaviour, each of which explains one popular "why doesn't my rule work" question.

The order of checks: deny first, then ask, then allow

Rules are checked in a fixed order — deny, then ask, then allow — and the first match wins, not the most specific one. Two consequences follow from that, and both break expectations.

A broad deny overrides a narrow allow: a deny of Bash(aws *) will block an allow of Bash(aws s3 ls). There are no exceptions to a deny — there's no "forbid everything except" mechanism here.

A matching ask asks even when a more specific allow exists. That isn't a bug, it's how you say "I always confirm this command by hand", and it works on top of any permission.

Between settings layers it's the same story: a deny in the user file beats an allow in the project file and vice versa, because every deny from every layer is checked before any allow.

Another small thing with large consequences: a bare tool name in deny removes the tool from the context entirely. An entry of "Bash" in the deny list means the agent never even learns that the tool exists. Bash(rm *), by contrast, leaves the tool visible and forbids only the matching calls.

Protected paths are checked before your rules

There is a list of paths whose writes are checked before anything looks at allow. Which is why Edit(.claude/**) in any settings file does precisely nothing — and it's the single most common source of "why is my permission being ignored" questions.

The protected directories: .git, .config/git, .vscode, .idea, .husky, .cargo, .devcontainer, .yarn, .mvn and all of .claude except .claude/worktrees. Among the files — .gitconfig, .gitmodules, every shell profile and startup file, .envrc, .npmrc, .yarnrc*, .pnp.cjs, bunfig.toml, .bazelrc, .pre-commit-config.yaml, lefthook.*, gradle-wrapper.properties, .ripgreprc, pyrightconfig.json, .mcp.json and .claude.json.

The logic is clear enough: these are all files whose contents change how your own machine behaves on the very next command, up to and including what gets executed instead of git commit. What happens on an attempt depends on the mode: normal and acceptEdits ask, plan allows it only if a bypass is available, auto hands it to the classifier, dontAsk refuses, bypassPermissions allows. The dialog also carries a separate option — permit edits to your own settings for this session.

The safety catch on deletion

rm and rmdir aimed at critical paths cannot be approved by anything: not by an allow rule, not by a hook that returned permission.

The critical paths are the filesystem root and any of its immediate children, the home folder, the drive roots on Windows and their first-level directories, the current working folder and its parents, and glob patterns inside added directories.

The interesting part is the table by mode, because it isn't laid out the way anyone expects:

ModeWhat happens
normal, acceptEdits, planAsks
autoHands it to the classifier
dontAskRefuses
bypassPermissionsAsks

So the "skip every confirmation" mode is stricter here than auto mode: --dangerously-skip-permissions will still stop on a deletion like that.

Things that look harmless count too: rm -rf "$DIR"/* falls under the safety catch, because an empty variable turns it into a deletion starting at the root. Hiding the command in a substitution, in backticks, or in a process substitution won't help — the check sees through all of them.

Four path anchors

Read and Edit rules use .gitignore syntax, and it has four different ways to anchor a path. People mix them up constantly.

FormAnchored to
//pathThe filesystem root
~/pathThe home folder
/pathThe settings source, not the drive root
path or ./pathThe current working folder

The third row is the trap. A single leading slash does not mean an absolute path: it anchors the rule to the settings file the rule is written in. Read(/secrets/**) in ~/.claude/settings.json means ~/.claude/secrets/**, and not secrets in your project at all. In project settings that same slash counts from the main working folder, in --settings from the folder of the file you named, and rules from local settings have, since 2.1.211, been anchored to the session's working folder rather than the repository root — so in a separate working copy Edit(/src/**) lands in that copy's own src.

A bare filename behaves exactly as it does in .gitignore and matches at any depth: Read(.env) is the same thing as Read(**/.env). Read(//**/.env), on the other hand, is anchored to the filesystem root.

On Windows, paths are converted to POSIX form before comparison: C:\Users\alice becomes /c/Users/alice. So a rule covering every drive is written //**/.env, and one covering a particular drive //c/**/.env.

The same rule catches different depths in allow and in deny

A single-segment relative folder pattern behaves asymmetrically, and that's on purpose.

Edit(src/**) in allow matches only the src folder at the root of the working directory. The very same rule in deny or ask matches a src folder at any depth — so it will catch vendor/pkg/src/lib.js too.

The reasoning is clear: a permission should be narrow, a prohibition broad. Every other form behaves identically in any kind of rule: Edit(/src/**) and Edit(src/components/**) match only where they're written, Edit(**/src/**) matches everywhere. The behaviour changed in 2.1.214: before that, Edit(src/**) caught any depth in permissions as well.

The colon works only at the end, and the space before the asterisk matters

The form Bash(ls:*) is exactly the same thing as Bash(ls *). But it's only recognized at the end of the pattern: in Bash(git:* push) the colon is an ordinary character, and the rule won't match anything at all.

The space before the asterisk is part of the rule. Bash(ls *) requires a space and therefore doesn't match lsof; Bash(ls*) does. A trailing asterisk also catches the bare command with no arguments, but only when it's the only asterisk in the rule: Bash(ls *) will match ls, while Bash(* --help *) will match npm --help x and won't match npm --help.

Everything before the first asterisk is compared literally. Hence an unpleasant surprise: Bash(git * main) permits any git subcommand, -c with arbitrary configuration included. Since 2.1.246 a warning is printed at startup for allow rules with an asterisk in front of the subcommand.

Compound commands

The separators Claude Code understands: &&, ||, ;, |, |&, & and a newline. Every part has to match a rule on its own — there's no blanket permission for the whole line.

A special case: if an operator ends up at the end with nothing after it — npm test &&, say — the command counts as unparseable and isn't split at all. And then not even Bash(npm *) will approve it.

When you answer "yes, and don't ask again" to a compound command, a separate rule is saved for each part that needed one. Stepping into a subfolder will spawn its own read rule. No more than five rules get saved out of one command.

Output redirections >, >>, 2> are checked as a file write — against your Edit rules, the protected-path list and the working directories. /dev/null is excluded from the check; a target that starts with ~ or contains a glob always requires confirmation.

Which wrappers get stripped and which don't

Before matching against the rules, these get stripped from the command: timeout, time, nice, nohup, stdbuf, the built-in command and builtin, zsh's noglob, and a bare xargs — that last one only without flags, since xargs -n1 grep is parsed as the command xargs.

A leading assignment to a known safe variable is stripped too, so Bash(npm test *) will match NODE_ENV=test npm test. An allow rule won't get past an assignment to any other variable; a deny rule gets through any of them.

The list is fixed and not configurable. And there isn't a single environment launcher on it: npx, docker exec, direnv exec, devbox run, mise exec are not stripped. The practical upshot: Bash(devbox run *) is a permission for devbox run rm -rf ., because as far as the check is concerned the command is devbox, not rm.

Separately, there are commands that can never be approved by a prefix rule: watch, setsid, ionice, flock, and find with -exec or -delete. In normal mode they always ask.

Rules for Write, Glob, NotebookEdit and MultiEdit are accepted and do nothing

File permissions are checked only against Edit(...) and Read(...) rules. A rule like Write(docs/**) or Glob(docs/**) will be parsed, saved, shown in /permissions — and never used. Since 2.1.210 a warning is printed at startup for one of these.

Write Edit(...) instead of Write, NotebookEdit and MultiEdit, and Read(...) instead of Glob. A bare tool name with no path does work, though: you can forbid Write wholesale.

A useful consequence: a Read deny rule on a path blocks editing and writing there as well — but not NotebookEdit.

Every file access is checked against two paths at once: the link itself and wherever it points. And the rules are asymmetric about it.

A permission applies only when both paths match. So a link inside a permitted folder that points outside it will still ask.

A prohibition applies when at least one matches. So a link to a forbidden file is forbidden itself.

In practice: if Read(./project/**) is allowed and Read(~/.ssh/**) is denied, then ./project/key pointing at ~/.ssh/id_rsa will be blocked.

Rules on tool parameters

A little-known family. Deny and ask rules can match on a scalar field of the tool's input:

.claude/settings.json
{
"permissions": {
"deny": ["Agent(model:opus)", "Agent(isolation:worktree)", "Bash(run_in_background:true)"]
}
}

One parameter per rule, nested fields aren't supported, * stands in for the value. A parameter the model didn't pass never matches — meaning Agent(model:opus) won't catch a call where no model was specified at all. The value is compared against what actually arrived, before normalization: the alias opus will match, the full identifier of the same model won't.

The tool's main field deliberately isn't matched this way: command, file_path, path, notebook_path, url are excluded. A Bash(command:rm *) rule is ignored with a warning — it would be far too easy to get around with a compound command.

For MCP tools, parameter rules work only through the --disallowedTools flag: any rule with mcp__ and parentheses in a settings file is skipped and ends up in the list of invalid settings and in the claude doctor output.

Wildcards in the tool name

In deny and ask rules the tool name can be given as a pattern, and the pattern has to cover the whole name: "*" means every tool, "mcp__*" every MCP tool.

In allow rules a pattern is permitted only after a literal mcp__<server>__ prefix, and the server name itself must be wildcard-free. So mcp__github__get_* works, while "*", "B*" and "mcp__*" in allow are skipped with a warning and permit nothing.

And one more trap: the tool name on screen can differ from the canonical one. What's shown as "Stop Task" is canonically called TaskStop, and only the canonical name works in rules and in hook filters.

WebFetch — two different rules that look alike

A bare WebFetch and WebFetch(domain:*) are not the same thing, because the second form also edits the sandbox's domain list.

RuleWhat it does
allow: WebFetchFetches pages without asking, but doesn't widen the sandbox — curl from inside the sandbox to that same host will still ask
allow: WebFetch(domain:*)Plus grants the sandbox network access
deny: WebFetchRemoves the tool entirely
deny: WebFetch(domain:*)The tool stays, every fetch is rejected, the sandbox's network is closed

Wildcards in a domain: *.example.com catches subdomains at any depth, but not example.com itself. In any other position the asterisk matches only the text between two dots — example.* will catch example.org and won't catch example.evil.com.

And a sober note: as long as the agent has shell access, WebFetch permissions restrict network access in no way whatsoever.

The built-in set of safe commands

Some commands run without a question in any mode, and that list is hardcoded: ls, cat, echo, pwd, head, tail, grep, find, wc, which, diff, stat, du, cd and the read-only forms of git. You can't extend it; you can only override it with your own ask or deny rule.

Even it will ask, though, if: an unquoted glob turns up in a command that has write or execute flags (find, sort, sed, git — the glob could expand into -delete); docker has -H, --context, --url or --connection; file has -m, --magic-file, -f or --files-from; there's a Windows network path among the arguments; the command runs longer than ten thousand characters or doesn't parse. Plus cd together with git will ask if the folder really changes — the new folder may have git hooks of its own.

PowerShell

PowerShell rules are built the same way, are compared case-insensitively, and canonicalize the popular aliases: PowerShell(Get-ChildItem *) will match gci, ls and dir alike. The command is parsed into a syntax tree and split on | and ;, and on version seven on && and || as well; each part is checked separately.

Remove-Item has a check of its own, stricter than the one for rm: system paths and targets with a glob — a bare *, anything ending in /* or \*, $dir/* included — are forbidden in every mode without a question, before the classifier even gets a look. Only the "working folder or its parent, recursively" case goes through the normal mode rules, and that one does come off with a permissions bypass.

And a Windows-specific note: any command with a network path of the form \\server\share\file among its arguments will ask for confirmation even when it's harmless in every other respect — a path like that can walk off with your Windows credentials.

Auto mode

Since 14 August 2026 this is the default mode for new sessions on Pro, Max and Team. Every action is decided by a classifier rather than a list of rules, and it's configured through a separate autoMode object.

FieldTypeWhat it does
autoMode.environmentarray of stringsWhat the classifier needs to know about your environment. This is exactly what /auto-mode-setup fills in.
autoMode.allowarray of stringsWhat it lets through.
autoMode.soft_denyarray of stringsWhat it asks you about.
autoMode.hard_denyarray of stringsWhat it forbids without asking.
autoMode.classifyAllShellbooleanWhether to run every single shell command through the classifier. Off by default.

Three things here matter more than the table itself.

The "$defaults" entry is almost always mandatory. In any of the four lists it mixes in the standard set of rules. Leave it out and the entire built-in list for that section silently disappears — together with the soft blocks on force-push, on curl | bash, on deploying to production and on bypassing auto mode itself, and with the hard block on data exfiltration. Your rules are supposed to extend the set, not replace it.

Narrow permissions bypass the classifier. A rule like Bash(npm test) stays in force under auto mode and is resolved before the classifier. Only broad permissions for arbitrary execution are suspended — Bash(*), interpreters with a wildcard — along with every rule that names the monitoring tool. Which means a narrow rule can wave through a destructive argument nobody ever looked at. The fix is classifyAllShell: true, and then every shell allow rule is switched off for the duration of auto mode.

The classifier doesn't read project settings. It takes autoMode only from the user file, the enterprise one and --settings. Otherwise a repository could hand itself permissions; local settings were read up until version 2.1.207, but not any more.

You can inspect and pick apart the configuration from the terminal:

Terminal window
claude auto-mode config # what's in effect and where it came from
claude auto-mode defaults # the standard rules of all four lists
claude auto-mode defaults --label 'Git Destructive' # the full text of a single rule
claude auto-mode critique # the model's review of your rules
claude auto-mode reset --yes # reset to the standard set without asking

The critique subcommand is underrated: it asks the model to go through your own rules and point out the ones that are ambiguous, redundant, or bound to produce false positives.

The mode is turned off with disableAutoMode, and there's a trap here: the value must be the string "disable". The schema will accept an array or true without complaining, but the code compares against that exact string, and the mode quietly stays on. You can hide the setup wizard with "auto-mode-setup": "off" in skillOverrides; disableBundledSkills doesn't switch it off, because it's a built-in command rather than a skill.

MCP servers

SettingTypeWhat it does
enableAllProjectMcpServersbooleanAutomatically approve every server from the project's .mcp.json.
enabledMcpjsonServersarray of namesExplicitly approved servers from .mcp.json.
disabledMcpjsonServersarray of namesExplicitly rejected servers.
allowedMcpServersarray of objects[admin] Allowlist: by name, by command or by address. An empty array means none are allowed.
deniedMcpServersarray of objects[admin] Blocklist. Takes precedence over the allowlist.
allowManagedMcpServersOnlyboolean[admin] The allowlist is read from policy only.
allowAllClaudeAiMcpsboolean[admin] Load the cloud connectors alongside the managed list.
managedMcpServersarray of objects[admin] The servers themselves, pushed out by an administrator: transport, connection and the map of allowed tools.

That last row corrects a widespread claim I used to repeat myself: "servers are only ever defined in .mcp.json, and settings hold nothing but the permissions for them". True for you, but not for an administrator: managedMcpServers in enterprise settings holds actual server configurations and is rolled out to everyone through the policy file or a device management system.

Ordinary servers, though, are defined in .mcp.json or via claude mcp add.

Hooks

Hooks deserve an article of their own, and I have one: it covers every event, the exchange formats and working examples. Here — the settings keys, and what breaks most often.

hooks is an object of the form "event → array of matchers". A matcher has a matcher filter and a list of handlers.

.claude/settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "npm run lint" },
{ "type": "command", "command": "echo", "args": ["done"] }
]
}
]
}
}

There are thirty-three events. For tools: PreToolUse, PostToolUse, PostToolUseFailure, PostToolBatch. For the conversation: UserPromptSubmit, UserPromptExpansion, Stop, StopFailure, Notification, MessageDisplay. For the session: SessionStart, SessionEnd, Setup, InstructionsLoaded, ConfigChange. For compaction and model switching: PreCompact, PostCompact, PreModelSwitch, PostModelSwitch. For permissions: PermissionRequest, PermissionDenied. For subagents and tasks: SubagentStart, SubagentStop, TeammateIdle, TaskCreated, TaskCompleted. For files and folders: FileChanged, CwdChanged, DirectoryAdded, WorktreeCreate, WorktreeRemove. And two for MCP forms: Elicitation, ElicitationResult.

A handler comes in five kinds, set by the type field: command runs a program or a shell line, prompt asks a small fast model, agent dispatches a full-blown agent, http pokes a URL, mcp_tool calls a tool on an MCP server. The shared optional fields are if with a condition, timeout, statusMessage for the spinner, once to run it a single time per session, and async with its relative asyncRewake.

SettingTypeWhat it does
hooksobjectThe hooks themselves.
disableAllHooksbooleanTurn off every hook, and the status line command with them.
allowManagedHooksOnlyboolean[admin] Run only the hooks that come from policy.
allowedHttpHookUrlsarray of strings[admin] Allowlist of addresses for HTTP hooks.
httpHookAllowedEnvVarsarray of stringsWhich environment variables HTTP hooks may interpolate into headers.
disableSkillShellExecutionbooleanForbid inline shell calls in skills and in your own commands.

Three reasons a hook "runs but does nothing"

Exit code 1 blocks nothing. Only code 2 blocks, and only on about a third of the events. A 1 — or any other non-zero code — is on most events just a non-blocking error in the log. And code 2 outranks your own JSON: even if you returned an "allow" decision, the 2 denies.

Where a 2 blocks: PreToolUse, UserPromptSubmit (wiping the prompt), UserPromptExpansion, Stop, SubagentStop, TeammateIdle, TaskCreated, TaskCompleted, ConfigChange, PostToolBatch, PreModelSwitch. Where it's ignored: PermissionRequest and PermissionDenied — the JSON fields decide there — and StopFailure. On PostToolUse a 2 doesn't block, it gets shown to the model. On WorktreeCreate any non-zero code aborts. And one more asymmetry: an expired timeout on PreToolUse doesn't block, while on PreModelSwitch it does.

The model almost never sees a hook's output. Plain text on standard output with exit code 0 lands in the debug log, not in the conversation. It's shown to the model on exactly four events: UserPromptSubmit, UserPromptExpansion, SessionStart and PostModelSwitch. The error stream is never shown anywhere, ever. On the remaining events the only way to pass something to the model is a structured response — the additional-context field or a system message. And the JSON is parsed only if the output starts with { and ends with }.

The filter is sometimes ignored entirely, and sometimes a regular expression. "*", an empty string, or no field at all all mean "everything". A filter made up only of letters, digits, _, -, spaces, commas and | is an exact match or a list of them. Any other character turns it into a regular expression, matched without anchors at either end unless you wrote them yourself. Case matters.

And the filter isn't always about a tool name. On SessionStart it's compared against how the session started, on SessionEnd against the reason it ended, on compaction against manual or auto, on ConfigChange against which settings file changed, on FileChanged against the file name, on a model switch against the model's canonical name. Whereas UserPromptSubmit, PostToolBatch, Stop, CwdChanged, TeammateIdle, the task events, the worktree events and MessageDisplay take no filter at all and silently ignore the one you wrote.

The default timeouts aren't uniform: command, http and mcp_tool get ten minutes, except thirty seconds on UserPromptSubmit and on the model-switch events, and ten on MessageDisplay; prompt gets thirty seconds, agent a minute; all the SessionEnd hooks together are given a second and a half. Async ones aren't limited at all.

On Windows it's worth remembering the form with a separate argument list: it runs without a shell and needs a real executable — .cmd and .bat wrappers require either the string form or launching through an interpreter.

Git: commits, pull requests, attribution

SettingTypeWhat it does
attributionobjectThe attribution text in commits and descriptions; an empty string hides it. The sessionUrl field controls the link to the session.
includeCoAuthoredByboolean[deprecated] Add co-authorship. Better to use attribution.
includeGitInstructionsbooleanInclude the built-in commit instructions in the system prompt. On by default.
prUrlTemplatestringTemplate for the pull request link: {host}, {owner}, {repo}, {number}, {url}.
doneMeansMergedboolean[experimental] "Done means merged": the agent keeps going until the pull request is ready to merge.
.claude/settings.json
{
"attribution": { "commit": "", "pr": "" },
"includeGitInstructions": true
}

Interface and terminal

SettingTypeWhat it does
themesee belowColor theme.
editorModenormal, vimKey mode in the input box. Replaced the /vim command, which is gone.
keybindingFlavorclassic, readlineHow the word-wise keys behave. readline is like Bash: delete back to a space, move by words, punctuation splits words.
vimInsertModeRemapsobjectYour own ways out of insert mode, for example {"jj": "<Esc>"}.
emojiCompletionEnabledbooleanEmoji autocompletion in the input box. On by default.
wheelScrollAccelerationEnabledbooleanScroll acceleration with the mouse wheel. Fullscreen mode only.
defaultViewchat, transcriptWhich view a session opens in.
axScreenReaderbooleanFlat output for screen readers.
tuidefault, fullscreenThe interface renderer.
viewModedefault, verbose, focusTranscript view mode at startup.
verbosebooleanFull tool output instead of shortened summaries.
autoScrollEnabledbooleanAuto-scroll the conversation down. Fullscreen mode only.
syntaxHighlightingDisabledbooleanTurn off syntax highlighting in diffs.
prefersReducedMotionbooleanReduce or remove animations.
showTurnDurationbooleanShow how long each turn took.
showMessageTimestampsbooleanStamp messages with the time they arrived.
terminalProgressBarEnabledbooleanReport progress on long operations through terminal escape sequences.
terminalTitleFromRenamebooleanLet /rename change the tab title. On by default.
spinnerTipsEnabledbooleanShow tips in the waiting spinner.
spinnerVerbsobjectYour own spinner verbs: added to the standard ones, or replacing them.
spinnerTipsOverrideobjectYour own tips: as a list, from a file, or with your own heading instead of "Tip".
footerLinksRegexesarray of objectsYour own link badges in the footer, driven by a regular expression. Five at most.
spellcheckobjectUnderline typos in the input box. Needs a checker installed: aspell, hunspell or ispell.
companyAnnouncementsarray of stringsAnnouncements at startup; if there are several, a random one is shown.
todoFeatureEnabledbooleanTurn on the task tracking panel.

Values for theme: auto (follows the terminal background), dark, light, light-daltonized, dark-daltonized, light-ansi, dark-ansi, plus custom:<name> for a theme from ~/.claude/themes/ and custom:<plugin>:<name> for one that comes from a plugin.

Some of these keys are read only from the user file, --settings and policy: spinnerTipsOverride with a tips file, footerLinksRegexes and spellcheck. A project file can't override them — otherwise a repository could paint an arbitrary link into your interface.

Settings that live in ~/.claude.json

These keys are silently ignored in settings.json. Claude Code or /config normally writes them for you, but they're worth knowing about.

SettingTypeWhat it does
permissionExplainerEnabledboolean[global] Ctrl+E on a permission dialog shows a breakdown of the command: what it does, what for, and what could go wrong, with a risk rating. On by default.
diffToolauto, terminal[global] Where to show the edit diff when an IDE is connected. In the IDE by default.
autoConnectIdeboolean[global] Connect to a running IDE automatically when started from an external terminal. Off by default.
autoInstallIdeExtensionboolean[global] Install the extension automatically when launched from the VS Code terminal. On by default.
externalEditorContextboolean[global] When you edit the prompt in an external editor via Ctrl+G, show the previous answer as comments at the top of the buffer.
skippedMarketplacesarray of strings[global] Marketplaces whose installation you declined.
skippedPluginsarray of strings[global] Plugins whose installation you declined.

The first key is worth finding out about: Ctrl+E on a prompt asking to run a command gives you a human explanation of what that command does — without running it. On an unfamiliar command out of someone else's repository, that's exactly the button you've been missing.

The status line

SettingTypeWhat it does
statusLineobjectYour own status line at the bottom, drawn by an external script.
subagentStatusLineobjectA status line for each subagent in the agents panel.

Fields of statusLine: type with the value "command", command with the script, padding, refreshInterval — recompute once every so many seconds — and hideVimModeIndicator if the script draws the vim mode itself.

.claude/settings.json
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh",
"padding": 1,
"refreshInterval": 5
}
}

The script gets JSON on its input with the session context: model, folder, cost, how full the context is. It prints one line. This is probably the most underrated setting of them all: spend figures permanently in view change behavior more than any instruction about saving tokens ever will. Just bear in mind that disableAllHooks turns this off too.

Context, memory, sessions

SettingTypeWhat it does
cleanupPeriodDaysnumber from 1How many days to keep transcripts. Thirty by default. It also sets how long checkpoints live.
desktopSessionCleanupPeriodDaysnumber from 0The ceiling on the exception that lets desktop app sessions survive the usual cleanup.
crossSessionInboundaccept, hold, refuseWhat to do with messages from your other sessions.
dialogExpiry60s, 5m, 10m, neverHow long before an unanswered dialog goes stale. Five minutes by default.
askUserQuestionTimeoutthe same valuesThe same, for the agent's questions to you. They don't expire by default.
autoContinueAtUsageLimitbooleanContinue the session once the plan's limit resets. On by default.
autoMemoryEnabledbooleanAutomatic project memory.
autoMemoryDirectorystring, a pathThe folder auto-memory is stored in. Read from any settings level.
autoDreamEnabledbooleanBackground memory consolidation.
fileCheckpointingEnabledbooleanSnapshot files before edits so that /rewind can restore them.
outputStylestringThe style of the assistant's answers.
languagestringPreferred language for answers and voice input, for example "russian".
promptSuggestionEnabledbooleanShow prompt suggestions.
awaySummaryEnabledboolean[experimental] A session summary when you come back after being away for more than five minutes.
showClearContextOnPlanAcceptbooleanOffer to clear the context when a plan is accepted. Off by default.
plansDirectorystring, a pathFolder for plan files, relative to the project root.
claudeMdstring[admin] CLAUDE.md-style instructions as organizational memory.
claudeMdExcludesarray of patternsWhich CLAUDE.md files not to load. The policy file can't be excluded.
respectGitignorebooleanThe file picker respects .gitignore. On by default; .ignore is always respected.
fileSuggestionobjectYour own source of file suggestions for @ mentions.

Two things are worth knowing about autoContinueAtUsageLimit: it's on by default, and it's read only from the user file, --settings and policy — meaning a project or local file that sets it isn't ignored, it turns the feature off.

Skills

SettingTypeWhat it does
skillOverridesobjectA skill's visibility: on, name-only — the name without the description, user-invocable-only — hidden from the model but still callable by name, off — hidden entirely.
skillListingMaxDescCharsnumberCharacter limit on a skill's description in the listing. 1536 by default.
skillListingBudgetFractionnumber 0–1Share of the context given to the whole skill listing. One percent by default.
disableSkillShellExecutionbooleanForbid inline shell calls in skills and in your own commands.
disableBundledSkillsbooleanDon't load the built-in skills. /doctor is the exception.
syncClaudeAiSkillsbooleanWhether to pull skills synced with claude.ai. Only the value false is taken into account.
syncClaudeAiPluginsbooleanThe same for plugins.

skillOverrides is worth knowing about for anyone with a lot of skills: their descriptions sit in the context permanently, and name-only on the rarely needed ones frees up a noticeable chunk. The same key is also how you stop the agent from running a particular command on its own while keeping it available to you: the value user-invocable-only.

Plugins and marketplaces

SettingTypeWhat it does
enabledPluginsobjectWhich plugins are enabled; the key is plugin@marketplace.
pluginConfigsobjectConfiguration for each plugin. Ignored in project settings.
extraKnownMarketplacesobjectAdditional marketplaces for this repository.
strictKnownMarketplacesarray of sources[admin] Only these sources may be added. Supports owner/* — a whole organization.
blockedMarketplacesarray of sources[admin] Blocked sources.
pluginSuggestionMarketplacesarray of strings[admin] Whose plugins may show up in install suggestions.
strictPluginOnlyCustomizationboolean or array[admin] Forbid customization outside plugins for skills, agents, hooks, mcp.
pluginTrustMessagestring[admin] Extra text added to the warning shown before installation.
disableCommandPluginSourcesboolean[admin] Forbid marketplaces of the "a local command prints the path to a plugin" kind.
disableSideloadFlagsboolean[admin] Forbid slipping plugins in through flags.

Workflows, agents, teammates

SettingTypeWhat it does
enableWorkflowsbooleanTurn workflows on or off.
disableWorkflowsbooleanTurn workflows off.
workflowKeywordTriggerEnabledbooleanThe word "ultracode" in a prompt turns workflows on for that turn. On by default.
skipWorkflowUsageWarningboolean[experimental] The warning about the cost of multi-agent workflows has been acknowledged.
workflowSizeGuidelineunrestricted, small, medium, largeA guideline for fan-out size: fewer than five agents, fewer than fifteen, fewer than fifty, or no hint at all.
disableAgentViewboolean[admin] Turn off the agents screen, background launching and the background service.
disableAutoMode"disable"Turn off auto mode. Only as that string.
teammateModein-process, tmux, iterm2, autoHow teammates are displayed. in-process by default.

The auto value of teammateMode is defined precisely: split panes if the session is running inside tmux, or inside iTerm2 with its command-line utility available, or if tmux is installed at all; otherwise everything runs inside the process. The iterm2 value means native iTerm2 split panes, and it showed up in 2.1.186.

The teammateDefaultModel key is still in the schema, but it was removed from the product in 2.1.234 and affects nothing.

Worktrees

The nested worktree object controls how separate working copies get created for sessions and background agents.

FieldTypeWhat it does
symlinkDirectoriesarray of stringsWhat to symlink from the main repository so the disk doesn't balloon. Nothing by default.
sparsePathsarray of stringsWhich paths to include via a sparse checkout. A huge speed-up in monorepos.
baseReffresh, headWhat new copies branch off: the remote main branch or your local state.
bgIsolationworktree, noneIsolation for background sessions. By default a background agent doesn't touch the main tree.
locationstring, a pathWhere the desktop app creates copies for SSH sessions. The CLI doesn't read it yet.
.claude/settings.json
{
"worktree": {
"symlinkDirectories": ["node_modules", ".cache"],
"sparsePaths": ["packages/app", "packages/shared"],
"baseRef": "fresh",
"bgIsolation": "worktree"
}
}

Remote control, SSH, environments

SettingTypeWhat it does
disableRemoteControlboolean[admin] Turn off remote control entirely.
remoteControlAtStartupbooleanBring up the remote control bridge in every session.
isolatePeerMachinesbooleanRequire confirmation before a message goes to a session on another machine.
autoUploadSessionsbooleanMirror local sessions to the web, for viewing only.
daemonColdStarttransient, askWhen the background service isn't there: bring it up for the session, or offer to install it permanently.
remoteobjectThe default environment for remote sessions.
sshConfigsarray of objects[admin] Preconfigured SSH connections: id, name, sshHost, sshPort, sshIdentityFile, startDirectory.
sshHostAllowlistarray of patterns[admin] Restrict the app's SSH sessions to these hosts. * — any, *.example.com — the domain and its subdomains.
disableDesktopLocalSessionsboolean[admin] Forbid sessions on the machine itself in the desktop app: work over SSH only.
browserExternalPageTools"disabled"[admin] Forbid the agent to read or touch external pages in the app's browser. Local previews still work.
disableBrowserExternalNavigationboolean[admin] Forbid external navigation in the app's browser, for the agent and the human alike.
disableMobileSimulatorToolsboolean[admin] Take the iOS simulator tools away from the agent; the human keeps the panel.
requireCoworkFullVmSandboxboolean[admin] Run tools inside an isolated virtual machine.
channelsEnabledboolean[admin] Allow channel notifications.
allowedChannelPluginsarray of objects[admin] Allowlist of channel plugins.

Three of these keys accept only a genuine boolean true: the string "true" or a 1 will be ignored, with a warning in the log. They are disableDesktopLocalSessions, disableBrowserExternalNavigation and disableMobileSimulatorTools. The terminal CLI doesn't read them at all — they're about the desktop app.

requireCoworkFullVmSandbox has an important side effect: inside a full virtual machine there is neither a device policy nor an enterprise settings file — you'll have to get them in there some other way.

.claude/settings.json
{
"remote": { "defaultEnvironmentId": "env-123" },
"sshConfigs": [
{
"id": "prod-box",
"name": "Prod",
"sshHost": "deploy@prod.example.com",
"sshPort": 22,
"startDirectory": "~/app"
}
]
}

Notifications, voice, breaks

SettingTypeWhat it does
preferredNotifChannelauto, iterm2, terminal_bell, iterm2_with_bell, kitty, ghostty, notifications_disabledWhich channel to send system notifications through.
inputNeededNotifEnabledbooleanA push to your phone when a confirmation or a question is waiting.
agentPushNotifEnabledbooleanLet the agent send proactive mobile pushes.
voiceobjectVoice input: enabled, mode with the value hold or tap, autoSubmit.
voiceEnabledbooleanDictation when signed in through claude.ai, if the organization's policy allows it. Not the same thing as voice.enabled, which overrides it.
breakReminderobject[experimental] A reminder to take a break after a long stretch of uninterrupted work. Never blocks.
quietHoursobject[experimental] Quiet hours: one gentle hint per session inside a given window of local time.
.claude/settings.json
{
"voice": { "enabled": true, "mode": "hold", "autoSubmit": true },
"breakReminder": { "enabled": true, "intervalMinutes": 120 },
"quietHours": { "enabled": true, "start": "22:00", "end": "07:00" }
}

Sandbox and network

The sandbox object controls what processes inside the isolation are allowed to do. It's the longest section of the schema and the least used — but if you let the agent run in a mode where it doesn't ask for permissions, this is exactly the part you need to read.

Let me fix a common structural mistake right away: read and write paths live not directly in sandbox, but in sandbox.filesystem. A rule like "sandbox": {"denyRead": [...]} will do nothing.

FieldTypeWhat it does
enabledbooleanTurn the sandbox on.
enabledPlatformsarray of macos, linux, wsl, windows[admin] Limit the whole configuration to these systems. On the rest it's inert in its entirety.
autoAllowBashIfSandboxedbooleanAutomatically allow commands when they run inside the sandbox.
allowUnsandboxedCommandsbooleanAllow a blocked command to be retried outside the sandbox. Defaults to true.
failIfUnavailablebooleanFail if the sandbox couldn't be brought up, instead of quietly starting without it.
excludedCommandsarray of stringsCommands taken out of the sandbox; set by /sandbox exclude.
ignoreViolationsobjectWhich violations not to show.
filesystem.allowWritearray of pathsAdditional paths that are writable.
filesystem.denyWritearray of pathsPaths that can't be written to, including ones inside an allowed folder.
filesystem.denyReadarray of pathsPaths that can't be read.
filesystem.allowReadarray of pathsExceptions that re-allow reading inside denied areas.
filesystem.allowManagedReadPathsOnlyboolean[admin] Read paths come from policy only.
filesystem.disabledbooleanTurn off the filesystem half of the sandbox. Not from project settings.
network.allowedDomainsarray of stringsAllowed domains.
network.deniedDomainsarray of stringsDomains that are always blocked.
network.allowManagedDomainsOnlyboolean[admin] Allow only domains from policy.
network.strictAllowlistbooleanAllow only explicitly listed domains.
network.allowUnixSocketsarray of stringsAllowed Unix sockets. macOS only.
network.allowAllUnixSocketsbooleanAllow all Unix sockets.
network.allowLocalBindingbooleanAllow binding local ports.
network.allowMachLookuparray of stringsAllowed Mach services. macOS only, and a wildcard is allowed only at the end.
network.httpProxyPortnumberPort of the sandbox's internal HTTP proxy.
network.socksProxyPortnumberPort of the internal SOCKS proxy.
network.tlsTerminateobject[experimental] Terminate TLS with your own certificate authority — needed to mask secrets.
credentials.envVarsarray of objectsWhat to do with secrets in variables: deny or mask, plus extraction and parsing.
credentials.filesarray of objectsThe same for files holding secrets.
credentials.awsPairsarray of objectsAWS variable pairs that the sandbox re-signs.
credentials.sigv4objectWhat to do with the AWS request shapes that can't be re-signed: streaming uploads, presigned URLs and asymmetric signing. Each field is deny or passthrough; everything is denied by default.
credentials.allowPlaintextInjectbooleanAllow secrets to be injected in plaintext. Off by default.
allowAppleEventsbooleanAllow Apple Events. macOS only.
enableWeakerNetworkIsolationbooleanWeakens protection. Weaker network isolation on macOS.
enableWeakerNestedSandboxbooleanWeakens protection. Allow a weaker nested sandbox.
bwrapPathstring, absolute path[admin] Your own bubblewrap binary on Linux.
socatPathstring, absolute path[admin] Your own socat binary.
ripgrepobjectYour own ripgrep for the sandbox. Project settings don't override it.

Three things are worth singling out.

allowUnsandboxedCommands is on by default. Which means the agent can retry a command the sandbox blocked outside it, through a special parameter. If you turned the sandbox on for isolation, that's most likely not what you wanted — switch it off with an explicit false.

enabledPlatforms makes the configuration inert in its entirety. On a system that isn't in the list there's no sandbox, no automatic permissions, no warning at startup, and no failure from failIfUnavailable. Silent, as if the section weren't there.

Secret masking doesn't work everywhere. On macOS and Windows the mask mode degrades into deny: there's nothing there to substitute the value on the fly. Masking entries also have an onExtractNoMatch field — what to do when the regular expression finds nothing: warn (the default) lets the variable through unmasked, deny removes it inside the sandbox, error stops the run.

.claude/settings.json
{
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": true,
"allowUnsandboxedCommands": false,
"network": {
"allowedDomains": ["api.example.com", "*.githubusercontent.com"],
"deniedDomains": ["telemetry.example.com"]
},
"filesystem": {
"denyRead": ["~/.ssh", "~/.aws"],
"denyWrite": ["~/.config"]
}
}
}

Updates and everything else

SettingTypeWhat it does
autoUpdatesChannellatest, stable, rcAuto-update channel.
minimumVersionstringKeeps you from dropping below the given version when switching channels.
requiredMinimumVersionstring[admin] Below this version the organization won't let you work.
requiredMaximumVersionstring[admin] The organization's version ceiling.
managedSourcesBehaviorfirst-wins, merge[admin] How several policy sources add up.
wslInheritsWindowsSettingsboolean[admin, Windows] WSL reads policy from the full Windows policy chain.
processWrapperstring[admin] What to wrap spawned processes in.
allowManagedPermissionRulesOnlyboolean[admin] Honor permission rules from policy only.
defaultShellbash, powershellThe shell for commands typed with !. Defaults to bash on every platform.
respondToBashCommandsbooleanRespond to commands entered with !. Defaults to yes.
feedbackSurveyRatenumber 0–1Probability of showing a session-quality survey.
feedbackDraftsnotify, quiet, offWhether the agent may draft feedback on its own. You still send it yourself.
enableArtifactbooleanArtifact publishing. Turning it off in any layer wins.
disableArtifactboolean[deprecated] Its inverted predecessor: true turns it off, false is ignored.
disableClaudeAiConnectorsbooleanDon't load cloud connectors.
skipWebFetchPreflightbooleanSkip the blocked-address check in strict corporate environments.
$schemastringA link to the settings schema: autocomplete and validation in your editor.

The schema accepts a few more housekeeping keys: modelProposedGoals, totalTokensReminder with its relatives, and disableDeepLinkRegistration. They're internal, never show up in the interface, and aren't described anywhere.

Environment variables

The env block in settings is a "name → value" object. All values are strings: numbers and flags go in quotes, "PORT": "3000", a flag is "1".

An honest caveat about completeness: the official documentation lists three hundred and forty-nine variables by name, including per-region ones for every model at every provider, plus the whole telemetry set. Retelling them here is pointless. Below are the ones actually used, plus the behavior of the env block, which isn't gathered in one place anywhere.

.claude/settings.json
{
"env": {
"CLAUDE_CODE_USE_POWERSHELL_TOOL": "1",
"ANTHROPIC_MODEL": "claude-opus-5",
"BASH_DEFAULT_TIMEOUT_MS": "120000",
"DISABLE_TELEMETRY": "1"
}
}

How the env block behaves

It beats an export from the shell. The value from the settings file is written into the process environment on top of the inherited one. That's exactly the opposite of what people usually expect.

You can't delete a variable — you can only set it to an empty string. When a provider is being picked, an empty value counts as unset, but child processes will get exactly that empty string.

Values are re-read on the fly when the file changes — except for subsystems configured only at startup, like telemetry. And since 2.1.246 /cd layers the new folder's env on top of the old one.

Project and local settings aren't allowed everything. Three groups are dropped: variables that set where files live (CLAUDE_CONFIG_DIR, CLAUDE_CODE_TMPDIR, HOME, TMPDIR, TMP, TEMP, XDG_*); variables that turn on dumping session contents (OTEL_LOG_RAW_API_BODIES, ENABLE_BETA_TRACING_DETAILED, BETA_TRACING_ENDPOINT); and variables affecting startup and syncing (CLAUDE_CODE_PROCESS_WRAPPER, CLAUDE_CODE_SYNC_SKILLS, CLAUDE_CODE_SYNC_PLUGINS, the plugin cache and seed folder). The list grew in 2.1.251, as it happens. The warning about it is only visible under debug.

A few more variables are ignored in any file and read only from the launch environment: CLAUDE_CODE_REMOTE, CLAUDE_CODE_ACCOUNT_UUID, the cross-session exchange socket and token, CLAUDE_CODE_PROJECT_DIR_NAME and CLAUDE_CODE_RESTRICTED.

And the other direction, which almost nobody writes about: Claude Code sets variables for child processes itself. They're visible from hooks and from any script you run: CLAUDECODE=1, CLAUDE_CODE_CHILD_SESSION=1, CLAUDE_CODE_SESSION_ID, CLAUDE_PID — its own process id, CLAUDE_EFFORT with the current effort level (ultracode mode shows up as xhigh), and in cloud sessions CLAUDE_CODE_REMOTE=true plus the remote session id. A hook that needs to know the effort level, or to tell a child session from the main one, takes it from here instead of guessing.

Providers and authentication

VariableWhat it does
ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKENAnthropic API key and token.
CLAUDE_CODE_OAUTH_TOKENSubscription token — sign in without an interactive login.
ANTHROPIC_BASE_URLYour own API base URL: a proxy or a gateway.
ANTHROPIC_CUSTOM_HEADERSExtra HTTP headers on API requests.
ANTHROPIC_BETASBeta headers in requests.
CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEXTurn on Amazon Bedrock or Google Cloud as the provider.
ANTHROPIC_BEDROCK_REGION_PREFIXWhich cross-region profile to prefer instead of the one derived from the AWS region.
ANTHROPIC_BEDROCK_BASE_URL, ANTHROPIC_VERTEX_BASE_URLYour own provider URLs.
AWS_BEARER_TOKEN_BEDROCK, ANTHROPIC_VERTEX_PROJECT_IDBedrock credentials and the Google Cloud project.
CLAUDE_CODE_SKIP_BEDROCK_AUTH, CLAUDE_CODE_SKIP_VERTEX_AUTHSkip provider auth when a gateway handles it.
HTTPS_PROXY, HTTP_PROXY, NO_PROXYProxies for outbound traffic.
NODE_EXTRA_CA_CERTSYour own root certificate for a corporate proxy.

There aren't two or three providers, by the way: besides the Anthropic API, Amazon Bedrock and Google Cloud, Microsoft Foundry and Claude Platform on AWS are supported too, and each has its own set of variables and its own mapping of aliases to models.

Models, context, limits

VariableWhat it does
ANTHROPIC_MODELThe main model. Overrides the model key from the files.
ANTHROPIC_DEFAULT_MODELThe model for new sessions; applies only if model isn't set anywhere.
ANTHROPIC_DEFAULT_OPUS_MODEL and the same for sonnet, haiku and fableWhat the aliases stand for.
ANTHROPIC_SMALL_FAST_MODEL[deprecated] The small fast model. Replaced by ANTHROPIC_DEFAULT_HAIKU_MODEL.
CLAUDE_CODE_SUBAGENT_MODELThe model for subagents.
CLAUDE_CODE_EFFORT_LEVELEffort level. Overrides --effort and /effort.
MAX_THINKING_TOKENSToken limit for thinking.
CLAUDE_CODE_MAX_OUTPUT_TOKENS, MAX_MCP_OUTPUT_TOKENSThe output token limit and the MCP output limit.
CLAUDE_CODE_DISABLE_1M_CONTEXTDon't use the million-token window.
CLAUDE_CODE_MAX_CONTEXT_TOKENSYour own ceiling for the context window.
CLAUDE_CODE_AUTO_COMPACT_WINDOW, CLAUDE_AUTOCOMPACT_PCT_OVERRIDEThe auto-compaction window in tokens and in percent.
DISABLE_AUTO_COMPACTTurn off auto-compaction.
DISABLE_PROMPT_CACHINGTurn off prompt caching.
API_TIMEOUT_MS, CLAUDE_CODE_MAX_RETRIESAPI request timeout and the number of retries.

Behavior and environment

VariableWhat it does
CLAUDE_CONFIG_DIRA different configuration folder entirely.
CLAUDE_CODE_PROJECT_DIR_NAMEThe short name of the project's transcript and auto-memory folder. Set only together with CLAUDE_CONFIG_DIR and only from the launch environment.
CLAUDE_CODE_TMPDIRDirectory for temporary files.
CLAUDE_CODE_USE_POWERSHELL_TOOLUse the PowerShell tool instead of bash.
CLAUDE_CODE_GIT_BASH_PATHPath to Git Bash on Windows.
CLAUDE_CODE_SHELL, CLAUDE_CODE_SHELL_PREFIXThe shell and a prefix for shell commands.
CLAUDE_ENV_FILEA script run before every shell command in the same process — that's how virtualenv activation survives across calls.
CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIRReturn to the original folder after every command: a cd inside a call isn't kept.
BASH_DEFAULT_TIMEOUT_MS, BASH_MAX_TIMEOUT_MSThe default and maximum command timeouts.
BASH_MAX_OUTPUT_LENGTHLimit on the length of a command's output.
CLAUDE_CODE_TOOL_MEMORY_LIMITMemory limit for commands, via control groups. Linux only.
MCP_TIMEOUT, MCP_TOOL_TIMEOUTTimeouts for server startup and for a tool call.
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSHow many subagents run at once. Twenty by default.
CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHSubagent nesting depth. Three by default; one disables nesting.
CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCYHow many parallel read-only calls. Ten by default.
TASK_MAX_OUTPUT_LENGTHCeiling on subagent output in characters: 32000 by default, 160000 maximum.
CLAUDE_CODE_ENABLE_TASKSWhich task tools to hand out: the new ones by default, zero brings back the old single tool.
CLAUDE_CODE_ENABLE_TODO_TOOLSBring the task tools back on models where they were removed.
USE_BUILTIN_RIPGREPUse the bundled ripgrep.
CLAUDE_CODE_WEBFETCH_CACHE_TTL_MSHow long fetched pages stay in the cache. Fifteen minutes by default.
CLAUDE_CODE_DISABLE_BACKGROUND_TASKSTurn off background tasks.
CLAUDE_CODE_DISABLE_CLAUDE_MDSDon't load CLAUDE.md files.
CLAUDE_CODE_SAFE_MODE, CLAUDE_CODE_RESTRICTED, CLAUDE_CODE_SIMPLEThe same as the launch flags of the same names.

Three traps in this table are worth spelling out.

The MCP timeouts differ by five orders of magnitude. Server startup is thirty seconds. A tool call, by default, is about twenty-eight hours — effectively no limit at all. On top of that, HTTP servers and cloud connectors cap each request at a minute, and that's a separate limit.

CLAUDE_CODE_PROJECT_DIR_NAME doesn't work on its own — only together with CLAUDE_CONFIG_DIR, and only from the environment, not from a settings file.

Safe mode takes away more than it looks like. CLAUDE_CODE_SAFE_MODE isn't only instructions and skills: plugins, hooks, MCP servers, custom commands and agents, output styles, workflows, themes, keybindings, the status line, the file-suggestion source, language servers and auto-memory don't load either. All that's left is corporate policy, including the hooks and status line it sets. It's a debug mode meaning "turn off everything I configured", and for tracking down a broken configuration it's perfect.

Rendering and accessibility

In one line, because there are a lot of variables and they're rarely needed. CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN brings back the classic renderer, and it's stronger than both CLAUDE_CODE_NO_FLICKER and the tui setting. There are separate switches for the mouse and clicks, scroll speed, virtual scrolling, full repaints, the native cursor, syntax highlighting, hyperlinks and truecolor in tmux. For accessibility there's CLAUDE_AX_SCREEN_READER and its relatives.

Privacy, telemetry, updates

VariableWhat it does
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFICA single switch for all non-essential outbound traffic.
DISABLE_TELEMETRY, CLAUDE_CODE_ENABLE_TELEMETRYTurn telemetry off and on.
DO_NOT_TRACKThe widely adopted variable with the same meaning.
DISABLE_GROWTHBOOKDon't pull server-side feature flags.
DISABLE_ERROR_REPORTINGDon't send error reports.
DISABLE_AUTOUPDATER, DISABLE_UPDATESTurn off auto-updates.
DISABLE_COST_WARNINGSHide cost warnings.
DISABLE_FEEDBACK_COMMANDHide feedback submission. The old name DISABLE_BUG_COMMAND is accepted too.
DISABLE_DOCTOR_COMMANDHide /doctor.
The OTEL_* familyExporting metrics, logs and traces.

Three things here catch people out.

DISABLE_BUG_COMMAND isn't a separate switch. It's the old name of DISABLE_FEEDBACK_COMMAND, and that one variable turns off /feedback, the feedback drafts, and /bug with /share, because they all go out over the same channel.

A value of 0 doesn't turn it back on. For CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, the variable being present at all — including as 0 or false — disables the traffic. To get it back you have to remove the variable entirely.

Turning off telemetry turns off features too. Along with the feature flags, these stop working: the default auto mode, /auto-mode-setup, remote control, /import, /schedule, the advisor, artifact comments, the new MCP client, and the PowerShell tool as the default on Windows. It's a deliberate trade-off rather than an incidental defect, but it's worth knowing before you spend half an hour looking for where remote control went.

What "all non-essential traffic" actually covers: auto-updates, telemetry, error reports, feedback submission, release notes, refreshing a gateway's model list, and availability checks. Plus — unexpectedly — running local plugin-source commands in the background, because they can drag a dependency install along with them. What it doesn't cover is the auto-install of the official marketplace; that one has its own variable.

Terminal commands and flags

Everything you type outside a session, in an ordinary shell. Each subcommand below gathers it all in one place: its own subcommands and flags, the fine print and the examples.

The important part first, and this is the official wording rather than my own observation: claude --help does not list every flag. A flag missing from the help is not a flag that does not exist. Below I mark what the help leaves out — there are at least a dozen such flags, and some of them are perfectly useful things like capping the number of turns.

Misspell a subcommand and you get the nearest match suggested and an exit, with no session started: claude udpate gets you a question asking whether you meant claude update.

Subcommands

claude [prompt]

Start an interactive session in the current folder — the ordinary way to begin work. A prompt in the argument does not change the mode: the session stays interactive, it just takes the first turn right away instead of waiting for input. Handy when the task is already formulated and you would rather not type it separately. Don't confuse this with -p: that one prints an answer once and exits.

The same splash screen opens either way: version, account and model, current folder, tips and recent activity. With a prompt in the argument it still shows up, but nothing waits for input — the first turn starts immediately.

Terminal window
claude # interactive session
# this is how the start screen looks in a user's report, build 2.0.26
╭─── Claude Code v2.0.26 ─────────────────────────────────────────────────────╮
Tips for getting started
Welcome back ksmith! Ask Claude to create a new appor c…
│───────────────────────────────────────│
▐▛███▜▌ Recent activity
▝▜█████▛▘ No recent activity
▘▘ ▝▝
Sonnet 4.5 · Claude Max
/Users/ksmith/claude-context-test
╰─────────────────────────────────────────────────────────────────────────────╯
claude "fix the failing test in orders" # session, straight into the task

claude -p "<prompt>"

A non-interactive run: Claude Code works through one prompt, prints the result to standard output and exits. This is the main mode for scripts, pipelines and CI — the output can be piped onward or saved to a file. The session itself is a full one: the same tools, the same permissions, the same project settings, there is just nobody around to ask. Hence a subtlety: if you have picked a model or a mode that draws on credits, you will not be shown the one-time consent for the charge — an interactive session asks, -p and the Agent SDK charge silently.

All that appears on screen is the answer itself: no splash screen and no input line in this mode.

Terminal window
claude -p "what does this script do?" # answer and exit

claude auth login|logout|status

Log in, log out, and check the authorization status. The status prints as JSON — a convenient way for a script to check that the machine is logged in at all before running anything on it. Some capabilities hinge not on an API key but specifically on being logged into a claude.ai account, so an inexplicable "feature unavailable" is best investigated starting here.

Logging in offers a choice of which account pays: your claude.ai subscription or Console billing. The --console flag picks the second one outright, without asking. After that a browser opens and waits for confirmation; logout deletes the stored credentials from the machine.

Terminal window
claude auth login --console # log in through Console billing
claude auth status # authorization status as JSON
claude auth logout # log out

claude setup-token

Issue a long-lived authorization token. [not on every plan] A subscription is required. The token is for places where you cannot log in interactively — a build server, a container, CI: you put it in an environment variable and claude -p works with no browser and no human.

You confirm the login in a browser, after which the token is printed to the terminal — and from there it goes into the build machine's environment.

Terminal window
claude setup-token # long-lived token for CI

claude agents

The management screen for background agents, and their launcher too. A background agent is a session that lives apart from your terminal: you hand it a task, close the window, and come back for the result. This screen shows what is running, what has finished and what has failed; all of it is available through separate subcommands (attach, logs, stop, rm) — the screen just collects them in one place.

You pick the session you want from the list, then choose what to do with it: open it in your terminal, look at its output, stop it, or delete it along with its working copy. Keep in mind that every background session burns your plan's limit like any other: five agents working at once eat through it five times faster.

Terminal window
claude agents # the background agents screen
# this is how the list looks in the documentation
Pinned
clawd walk cycle Drawing the walk-cycle sprite frames 3m
Ready for review
jump physics Opened PR with collision fix #2048 2h
Needs input
power-up design double jump or wall climb? 1m
Working
collision detection Adding swept-AABB checks to CollisionSystem 2m
playtest level 3 run 12 · all checkpoints cleared in 4m
Completed
title screen result: menu, options, and credits done 9m
sound effects result: 14 SFX exported to assets/audio 4h
6 more

claude attach <id>

Open a background session in this terminal. You get its whole conversation and carry on as if you had started it here. You need this when the agent has run into a question or gone off course and it is easier to steer it by hand from there. The id comes from claude agents or from the output at launch.

Terminal window
claude attach a1b2c3 # attach to a background session

claude logs <id>

Print a background session's latest output and exit. A quick way to see what the agent is up to without taking it over or getting in its way. Handy to call from a script when you need to wait for a result or just make sure work is happening.

Terminal window
claude logs a1b2c3 # a background session's latest output

claude stop <id>

Stop a background session; the conversation is kept. Alias: kill. This is not deletion: the session stops working and stops spending your limit, but its output and its working copy stay where they are and you can still look at them. If you want the session gone rather than stopped, that is claude rm.

Terminal window
claude stop a1b2c3 # stop it

claude respawn [id]

Restart a background session, or all of them, on the current version. The point is that agents already running keep spinning on the version they started with, and a Claude Code update does not reach them on its own. A single session is restarted by id, --all does the lot at once.

Terminal window
claude respawn --all # restart them all on the new version

claude rm <id>

Delete a background session and its working copy. Unlike stop, this is irreversible: the conversation goes, and so does the separate folder the agent worked in, along with everything you did not pull out of it into a branch. Clearing out finished sessions is worth doing — otherwise the list overgrows and the working copies take up space.

If the working copy still holds commits that exist nowhere else, the command refuses to touch it and tells you it left everything as it was.

Terminal window
claude rm a1b2c3 # delete the session and its working copy

claude daemon

The background service that holds all the background sessions. A subcommand few people know about, though it runs for everyone: it is the supervisor that starts background sessions and keeps them alive. You do not need it at all right up until an agent stops responding or the session list looks suspiciously empty — that is when you come here for its state and its log.

SubcommandWhat it does
statusService state: version, socket folder, number of worker processes
run [path]Start the service by hand
logsThe service log
stopStop it; --any — together with the sessions, --keep-workers — leaving the worker processes
uninstallRemove the service

The --json-path and --log-file flags change where the state file and the log live; by default that is ~/.claude/daemon.json and ~/.claude/daemon.log. In version 2.1.251 permanent installation of the service is disabled: it comes up on demand and shuts down when the last client disconnects.

A trap for scripts: claude --dangerously-skip-permissions daemon status works, but any other global flag before the word daemon will start an interactive session instead of the subcommand. Put the subcommand first.

Terminal window
claude daemon status # background service state
claude daemon stop --any --keep-workers # stop the service, keep the workers

claude mcp

Configuring MCP servers without starting a session. An MCP server is what the model reaches outside the project with: to an issue tracker, a database, the file system, an internal API. All of the same can be configured inside a session, but the shell is handier when servers are rolled out by a script or have to be set up identically on several machines.

SubcommandWhat it does
add <name> <command-or-url> [args...]Add a server.
add-json <name> <json>Add a server as a single line of JSON.
add-from-claude-desktopImport servers from Claude Desktop. macOS and WSL only.
list, get <name>The list and the details.
login <name>, logout <name>Authorize against a server, or clear its stored credentials.
remove <name>Remove a server.
reset-project-choicesReset the "approved or rejected" decisions on project servers.
serveRun Claude Code itself as an MCP server.

The most important flag here is --scope, and leaving it out explains a good half of the "why can only I see this server" and "why does everyone suddenly have it" questions. Values: local (the default), project — into .mcp.json, which gets committed, and user — into your user settings. It is available on add, add-json, add-from-claude-desktop and remove.

There are four transports, not three: stdio, http, sse and ws. Short forms: -t for --transport, -H for --header. For OAuth there is --client-id, --client-secret (it will prompt, or take it from an environment variable) and --callback-port; login additionally has --no-browser.

Unapproved servers from .mcp.json show up in the list as awaiting approval and do not connect. Adding one is confirmed with a line saying exactly where the entry went; list walks the servers before printing and checks whether they answer, and serve does not exit — the process stays up and talks over standard input and output.

Terminal window
claude mcp add fs npx -- -y @modelcontextprotocol/server-filesystem ~/work # into the local scope
claude mcp add --scope project github https://api.example.com/mcp -t http # into the project's .mcp.json
claude mcp add-json local-tools '{"command":"./tools","args":["--serve"]}' # the same thing from ready-made JSON
claude mcp list # what is connected and in what state
# captured on build 2.1.252
Checking MCP server health…
claude.ai Google Drive: https://drivemcp.googleapis.com/mcp/v1 - Connected
serena: C:/Users/user/.local/bin/uvx.exe --python 3.13 --from git+... - Connected
claude mcp serve # serve Claude Code itself as an MCP server

claude plugin

Plugins and marketplaces. Alias: plugins. A plugin is a bundle of skills, agents, commands, hooks and MCP servers, shipped and updated as one piece from a marketplace. This is where you install them, enable them, disable them and build your own. It works without starting a session, so rolling out an identical set across a whole team is easy to script.

SubcommandWhat it does
install <plugin>Install from a marketplace. Alias i.
uninstall <plugin>Remove it. Aliases remove, rm.
enable, disableTurn an installed one on or off.
listList what is installed. Alias ls.
details <name>An inventory of components and an estimate of how much context the plugin will eat.
update <plugin>Update it; takes effect after a restart.
marketplaceManaging marketplaces.
init <name>Create a plugin skeleton. Alias new.
validate <path>Check the manifest, plus the skills, agents and commands in the folder.
eval [target]Run the test cases against the plugin and show the scores.
tag [path]Create a release git tag, checking the manifest against the marketplace entry.
pruneRemove automatically installed dependencies that are no longer needed. Alias autoremove.

Almost every subcommand takes -s, --scope with the values user (the default), project and local, and update also takes managed. Beyond that: install has --config key=value (repeatable) and -y; uninstall has --keep-data, --prune, -y; disable has -a for all of them; list has --json and --available; prune has --dry-run and -y; validate has --strict, which turns warnings into errors; init has --description, --author, --author-email, -f and --with with a list of components: skills, agents, hooks, mcp, lsp, output-style, channel.

Worth knowing: validate works on an ordinary folder of skills and agents too, with no plugin involved.

A plain list prints the installed plugins with their version, scope and state — enabled or disabled; with --json the same thing arrives machine-readable, for a script to parse.

Terminal window
claude plugin install code-review@claude-plugins-official # install from a marketplace
claude plugin list --json # what is installed, machine-readable
# captured on build 2.1.252, without --json
Installed plugins:
frontend-design@claude-plugins-official
Version: unknown
Scope: project
Status: enabled
claude plugin details formatter # how much context it takes up
claude plugin init my-tools --with skills,hooks # a plugin skeleton
claude plugin validate ./my-tools --strict # check the manifest and the folder's contents

claude auto-mode

Configuring the auto-mode classifier. Auto mode decides what to run without asking and what to stop and ask you about; it decides that from a set of rules, and the rules come from three places — the built-in set, your settings, the project's settings. These subcommands show which of them are in force right now and where each came from, let you read a built-in rule in full, and let you ask the model to critique your own. It is worth coming here when auto mode asks too often or, the other way round, waves through what it should not.

SubcommandWhat it does
configWhat is in force and where from
defaultsThe built-in rules; with --label — the full text of one rule
critiqueThe model's critique of your rules
resetReset; --yes — without confirmation

defaults prints JSON: an object with the keys allow, soft_deny, hard_deny and environment, each holding an array of long text rules with names like "Security Discussion: …". The --label flag cuts one whole rule out of it.

Terminal window
claude auto-mode config # what is in force and where from
claude auto-mode defaults --label 'Git Destructive' # the full text of one rule
claude auto-mode critique # the model's critique of your rules
claude auto-mode reset --yes # reset without confirmation

claude project purge [path]

Delete all the state for a project: transcripts, tasks, file history, the configuration entry. The code itself is not touched — only what Claude Code has accumulated next to it. You need this when a project is finished, or when something has crept into the accumulated state that should not be there. Before running it for real it is worth looking at the list with --dry-run.

Terminal window
claude project purge ~/work/my-repo --dry-run # what would be deleted
# this is how it looks in the documentation
Purge plan for /home/user/work/my-repo:
dir: /home/user/.claude/projects/-home-user-work-my-repo
project transcripts (.jsonl) and memory/
config: projects["/home/user/work/my-repo"]
project entry in ~/.claude.json (trust, history, MCP servers)
filter: /home/user/.claude/history.jsonl
12 prompt(s) typed in this project
shell-snapshots/ are not project-scoped and will not be touched
backups/ may still contain this project entry in old .claude.json snapshots (/home/user/.claude/backups); at most 5 are kept and they rotate out automatically
Dry run: 3 item(s) would be deleted.

claude doctor

Diagnostics for the installation, with no session started and nothing modified. It runs a set of checks on how Claude Code is installed and what state its environment is in, and prints the result line by line. It fixes nothing on its own: this is a diagnosis, not a cure. It is the sensible place to start any "why doesn't it work" investigation, before changing settings at random.

Terminal window
claude doctor # diagnostics, nothing modified
# captured on build 2.1.252
Claude Code doctor
Running: native (2.1.252)
Commit: c0778c45886d
Platform: win32-x64
Path: C:\Users\user\.local\bin\claude.exe
Config install method: native
Search: OK (bundled)
Auto-updates: enabled
Auto-update channel: latest
Last update attempt: success 2.1.252 (2026-08-31)
Managed settings (remote): not fetched — requires an Enterprise or Team subscription
Remote Control
Control this session from claude.ai/code or the Claude mobile app
No installation issues found.
For a full setup checkup that can also fix issues, run /doctor in a Claude Code session.

claude import [source]

Bring configuration over from another coding agent, so you do not have to retype the rules, commands and settings you already assembled for a different tool. The source is given as an argument. --dry-run shows exactly what would come across without changing anything — start there if your current configuration already has something to lose.

Terminal window
claude import codex --dry-run # what would come across from another agent

claude install [version]

Install the native build: stable, latest or a specific version. Native means a standalone binary instead of an npm package, and it can update itself. The argument picks what gets installed: stable is the tested channel, latest is the newest, and an exact number pins the version hard — which is what build machines do, where behavior has to be the same today and in a month.

Terminal window
claude install stable # install the stable build

claude update

Check for updates and install them. Alias: upgrade. The native build updates itself anyway, so you call this by hand when you need the fresh version right now — for a capability from a specific release, say. Background sessions already running will not pick the update up: you restart them afterwards with claude respawn --all.

It starts with the current version and a check of the channel, and then comes either the install or a message that the download failed.

Terminal window
claude update # update
# the first lines of real output; in that run a download error came next
Current version: 2.1.241
Checking for updates to latest version...

claude ultrareview [target]

A cloud multi-agent review that prints its findings to the terminal. [costs extra] Pro and Max get three free runs — one-time, never replenished — and Team and Enterprise get none at all; after that the review is charged against credits, usually 5–25 dollars a run depending on the size of the changes, and with credits turned off the launch is simply blocked. [not on every plan] It needs a claude.ai account login: via Amazon Bedrock, Google Cloud Agent Platform and Microsoft Foundry, and in organizations with Zero Data Retention, the command is unavailable.

The analysis does not run on your machine: the changes go off to a cloud session where several agents work on them in parallel, and what comes back to the terminal is a finished list of findings. A run counts from the moment the cloud session started: a review stopped halfway still uses up a free run, while a paid one is charged only for the part that ran. Consent for the credit charge is asked once per conversation.

Terminal window
claude ultrareview # findings print straight to the terminal

claude gateway

Start the corporate authorization and telemetry gateway. Developers reach the API through it rather than directly: the credentials stay on the gateway, and the gateway also collects usage statistics — so keys do not spread across machines and you can see who spends how much. Its configuration comes from a separate file passed by a flag. A purely corporate thing; on your own you do not need it.

The command does not exit: it is a server, and it stays up until something stops it.

Terminal window
claude gateway --config gateway.yaml # the corporate gateway

claude remote-control

Hidden: hold remote control open as a server. Alias: rc. The machine stays reachable, and you can attach to its session from another device without going near the computer itself. The process does not exit on its own — it lives until you stop it, and --continue picks up the last control session instead of a new one. [not on every plan] It needs a claude.ai account login — remote control does not work with an API key.

Terminal window
claude remote-control --continue # return to the last control session

claude self-hosted-runner

Hidden: turn a machine or a container into a site where web, mobile and desktop sessions run. [not on every plan] This is a public beta for Team and Enterprise, off by default: the organization's owner has to allow self-hosted environments, the organization has to have web Claude Code enabled, and it does not work with Zero Data Retention. There is no separate charge for such a site — the hardware is yours, and sessions on it draw on the same organization limit as sessions on Anthropic's infrastructure.

It has a setup subcommand and an orchestrator of its own that brings up runners as the queue builds, plus around twenty flags: the API address, the environment secret file, the hooks folder, the health-check port, capacity, drain and shutdown timeouts, an idle runner's lifetime, a client label. All of it is described in a separate reference on self-hosted environments — contrary to the widespread belief that the subcommand is undocumented.

Terminal window
claude self-hosted-runner setup # prepare a machine as a site

Installing and updating

There are more ways than npm install, and it is worth knowing, because the native build updates itself and the npm package does not.

Terminal window
# macOS, Linux, WSL — the native installer
curl -fsSL https://claude.ai/install.sh | bash
curl -fsSL https://claude.ai/install.sh | bash -s stable # pin the channel
curl -fsSL https://claude.ai/install.sh | bash -s 2.1.236 # pin the version
# Windows
irm https://claude.ai/install.ps1 | iex # PowerShell
winget install Anthropic.ClaudeCode # or through a package manager
# macOS via Homebrew — two different packages
brew install --cask claude-code # stable, about a week behind
brew install --cask claude-code@latest # the fresh one
# npm — works, but needs Node 22+
npm install -g @anthropic-ai/claude-code

There are signed repositories for apt, dnf and apk as well. And claude install and claude update work once Claude Code is already installed.

Exit codes

A three-line section, but an important one for scripts.

CodeWhat it means
0Success
non-zeroThe run failed
143Interrupted by a termination signal
137The install was killed before it finished

A subtlety: a bad flag is reported on the error stream before the work starts, while a failure during the work — a missing login, for instance — is printed as the result on ordinary output. Which means the return code alone will not tell "it did not start" apart from "it started and could not finish".

A signal interrupt leaves the current turn unfinished and without a result, kills the process tree of any commands it launched, fires the session-end hooks — and when the session is resumed, that turn continues from where it stopped.

Launch flags

The [not in help] marker means the flag works, but claude --help in build 2.1.251 doesn't print it.

Sessions and resuming them

FlagWhat it does
-c, --continueResume the last conversation in the current folder. Skips background sessions.
-r, --resume [value]Resume by id, or open the interactive picker.
--fork-sessionOn resume, start a new id instead of reusing the old one.
--session-id <uuid>Set a specific session id.
-n, --name <name>Display name for the session.
--from-pr [value]Resume the session tied to a pull request.
--no-session-persistenceDon't save the session to disk. Only with non-interactive mode.
--teleport [session]Pull a web session into the terminal.
--cloud [description|id|url]Create a cloud session or attach to an existing one.
--remote[deprecated] The old name of --cloud. Still turns up in other people's scripts.
--environment <id>Create a cloud session on your own environment.
--ref <branch>[not in help] Which ref to bring the cloud environment up from. Works together with --environment.
--remote-control [name], --rcStart a session with remote control enabled.
--remote-control-session-name-prefix <prefix>Prefix for the auto-generated names of such sessions.
--bg, --backgroundRun in the background and hand control back; prints the id.
--exec <command>[not in help] Run a plain command as a background task instead of a session.
-w, --worktree [name]Create a fresh git worktree for the session.
--tmuxBring up a tmux session for the worktree.
--teammate-mode <mode>[not in help] How to show teammates: in-process, auto, tmux, iterm2.
Terminal window
claude -c # resume the last conversation
claude -r # pick from a list
claude -r 8f3c1d2e --fork-session # resume as a copy, original untouched
claude -n "payments refactor" # start with a name
claude --from-pr 1234 # session for a pull request
claude --bg "run the whole test suite" # in the background, returns an id
claude --bg --exec 'pytest -x' # a background task with no session at all
claude -w feature-x # its own worktree for the session
claude -w feature-x --tmux # the same, in tmux
claude --cloud "fix the flaky CI tests" # a cloud session
claude --environment ccpool_abc --ref main -p "run the smoke tests"

The --exec flag deserves its own line: it turns the CLI into a launcher for background tasks with no model involved at all. The command runs in a pseudo-terminal, you read its output through claude logs, and you stop it with claude stop. Handy when you want one uniform way to watch long-running processes.

Output and non-interactive mode

FlagWhat it does
-p, --printPrint the answer and exit. The folder-trust dialog is skipped.
--output-format <format>text by default, json or stream-json.
--input-format <format>text by default, or stream-json.
--json-schema <schema>Schema for validating a structured response.
--include-partial-messagesDeliver chunks of messages as they arrive.
--include-hook-eventsInclude hook lifecycle events in the stream.
--forward-subagent-textForward subagent text and thinking.
--replay-user-messagesEcho user messages back into the output.
--max-turns <n>[not in help] Cap on the number of tool-using turns. The main cost-control lever in CI.
--max-budget-usd <amount>Cap on what the API calls may spend.
--permission-prompt-tool <tool>[not in help] An MCP tool that answers permission requests in a human's place.
--ax-screen-readerFlat text, no frames and no animation.
--verboseOverride the matching setting from the file.
Terminal window
claude -p "list the public endpoints" --output-format json | jq -r '.result'
claude -p "build a report" --json-schema ./report.schema.json | jq '.structured_output'
claude -p "fix the linter" --max-turns 5 # turn cap
claude -p "check the style" --max-budget-usd 0.50 # spending cap
claude -p "..." --permission-prompt-tool mcp_auth_tool
cat diff.patch | claude -p "assess the risk of these changes"

Two flags here are the most useful ones and also the ones missing from the help. --max-turns limits how many turns may call tools; when the cap is hit the run ends with a matching marker in the result, and this is exactly what Anthropic officially recommends as the main cost-control lever in CI. --permission-prompt-tool names an MCP tool that will answer permission requests instead of a human — the only way to get approval logic into a non-interactive run.

What you need to know about non-interactive mode

Slash commands do work there. Your own skills and commands are pasted straight into the prompt text. The terminal-only built-ins like /login aren't available, but /model, /effort, /fast, /color and /rename take their value as an argument, and /mcp with no argument prints a text summary of the servers. You change a setting with /config key=value.

Terminal window
claude -p "/model sonnet /code-review low"
claude -p "/config thinking=false tell me what this module does"

The json format hands back noticeably more than the answer text. Here's a real response to a trivial request, captured from build 2.1.252 and trimmed — only repetitive counters were dropped:

{
"type": "result",
"subtype": "success",
"is_error": false,
"result": "ok",
"session_id": "8a792c19-cd74-4531-8311-f5cab07771d8",
"num_turns": 1,
"total_cost_usd": 0.351315,
"duration_ms": 4988,
"duration_api_ms": 2029,
"ttft_ms": 2271,
"stop_reason": "end_turn",
"terminal_reason": "completed",
"usage": {
"input_tokens": 2,
"output_tokens": 4,
"cache_creation_input_tokens": 34368,
"cache_read_input_tokens": 15050,
"service_tier": "standard"
},
"modelUsage": {
"claude-opus-5": {
"inputTokens": 2,
"outputTokens": 4,
"costUSD": 0.351315,
"contextWindow": 1000000,
"maxOutputTokens": 64000,
"provider": "firstParty"
}
},
"permission_denials": [],
"subagent_stats": { "spawned": 0, "completed": 0, "failed": 0 },
"fast_mode_state": "off",
"fast_mode_disabled_reason": "sdk_opt_in_required"
}

Three things here are worth a look. The answer text sits in result — that's what you normally call jq -r '.result' for. The cost in total_cost_usd is computed by the client, not the server, and broken down per model in modelUsage. And usage shows where the money actually went: in the example above, four tokens of answer came with thirty-four thousand tokens of cache writes — meaning you pay for context, not for the answer. With a validation schema, the structured response lands in a separate field alongside these same metadata.

You can save the session_id and continue the conversation later — and, since version 2.1.223, from a different folder.

Flag conflicts. -p together with --bg is an error. So is --cloud with a task description together with -p; but --cloud <id> together with -p will queue the message on that cloud session and exit.

Stream limits. Piped input is capped at ten megabytes: go over and you get a clear error and a non-zero exit code. If the input stream can't be read at all, you get a warning and the run continues with the prompt from the command line.

Background tasks die with the run. A command started in the background during claude -p is torn down about five seconds after the result is printed. Background subagents and workflows are the exception — they get waited on, but never longer than ten minutes of uninterrupted idleness.

--bare is the recommended mode for scripts, and in the future it will become the default behavior for -p. The difference matters: without it, a non-interactive run executes the hooks from the project's .claude/settings.json and connects the servers from its .mcp.json even in a folder you never trusted, without asking a single question.

Model, effort, permission mode

FlagWhat it does
--model <model>An alias (fable, opus, sonnet, haiku) or the full name.
--fallback-model <model,...>Fallback when the main model is overloaded. Only with -p.
--effort <level>low, medium, high, xhigh, max, and per the docs ultracode as well.
--advisor <model>[not in help] Turn the advisor on and pick its model.
--agent <agent>The agent for the session; overrides the setting.
--agents <json>Declare your own agents right on the command line. Validated at startup.
--permission-mode <mode>default (also known as manual), acceptEdits, plan, auto, dontAsk, bypassPermissions.
--dangerously-skip-permissionsBypass the permission checks.
--allow-dangerously-skip-permissionsMake the bypass an available option without turning it on.
--restrictedRestricted mode.
--safe-modeTurn off every customization.
--bareMinimal mode for scripts.
Terminal window
claude --model haiku -p "list the changed files"
claude --effort xhigh # a session that reasons deeply
claude --effort ultracode # straight into workflow orchestration
claude --advisor opus # bring in the advisor
claude --permission-mode plan # start in planning mode
claude --permission-mode acceptEdits # accept edits automatically
claude --safe-mode # no hooks, skills, plugins or MCP
claude --bare -p "..." # minimal mode for a script

Three warnings. --dangerously-skip-permissions doesn't work as an administrator: on Linux and macOS a run as root or through sudo is rejected, because root plus no questions asked means access to everything on the machine. Inside a recognized sandbox the check is lifted. An organization can forbid the mode entirely with the disableBypassPermissionsMode key.

The docs and the binary disagree in two places. For --permission-mode the docs list both default and manual as its alias, while the binary's help lists only manual. For --effort the docs know about ultracode, the help doesn't. In both cases the wider variant works.

--safe-mode and --bare are different things. The first turns off all customization for diagnostics. The second is a minimal execution mode for scripts, where authorization also goes strictly by key. For debugging "something broke after my settings" you want the first one.

Tools, folders, MCP

FlagWhat it does
--tools <tools...>The set of built-in tools: an empty string turns them all off, default turns them all on, or list the names.
--allowedTools, --allowed-toolsAllow tools by list. Both spellings work.
--disallowedTools, --disallowed-toolsDeny tools by list.
--add-dir <folders...>Extra working folders.
--mcp-config <configs...>Load MCP servers from files or from JSON strings.
--strict-mcp-configUse only the servers from this flag.
--plugin-dir <path>Load a plugin from a folder or an archive, for this session only.
--plugin-url <url>The same, but the archive comes from a link.
--channels <servers...>[not in help] Which MCP servers to listen to for external events.
--dangerously-load-development-channels[not in help] Allow channels outside the approved list.
--disable-slash-commandsTurn off all skills.
--chrome, --no-chromeTurn the Chrome integration on or off.
--ideConnect to the IDE automatically when exactly one fits.

Both tool lists accept names separated by commas as well as by spaces. With -p, the servers from --mcp-config are awaited before the first turn, but no longer than the startup timeout; a malformed entry is skipped and the run carries on and finishes normally — which means what you check in CI is not the exit code but the list of server errors in the first event of the stream.

Settings, prompt, odds and ends

FlagWhat it does
--settings <file-or-json>Extra settings: a path to a file or a JSON string.
--setting-sources <sources>Which settings layers to load: user, project, local.
--system-prompt <prompt>Replace the system prompt entirely.
--system-prompt-file <path>[not in help] The same, but from a file.
--append-system-prompt <prompt>Append to the system prompt.
--append-system-prompt-file <path>[not in help] The same, but from a file.
--append-subagent-system-prompt <text>[not in help] Append to every subagent's system prompt.
--exclude-dynamic-system-prompt-sectionsMove the machine-dependent chunks into the first user message — the cache is reused better.
--autocompact <auto|tokens>Auto-compaction threshold.
--betas <betas...>Beta headers on the requests.
--init[not in help] Run the init hooks before the session. Only with -p.
--init-only[not in help] Run the startup hooks and exit without starting a conversation.
--maintenance[not in help] Run the maintenance hooks. Only with -p.
--file <id:path ...>Download file resources at startup.
--prompt-suggestions [on]Suggestions for the next prompt.
--briefEnable the tool the agent uses to talk to the user.
-d, --debug [filter]Debug mode with a category filter.
--debug-file <path>Write the debug log to a file.
-v, --versionVersion.
-h, --helpHelp.
Terminal window
claude --settings '{"disableAllHooks": true}' -p "..." # a run without the repo's hooks
claude --setting-sources user -p "..." # ignore the project settings
claude --append-system-prompt-file ./team-rules.md
claude --append-subagent-system-prompt "always give file paths"
claude --init-only # warm up the container and exit
claude -d "api,hooks" # debug by category
claude -d "!1p,!file" --debug-file ./claude.log # everything except these categories

--init-only is worth calling out separately: it's the natural way to warm up a container or a working folder in CI — the install and session-start hooks run, and then the process exits without starting a conversation.

And one divergence worth remembering if you write scripts from the docs: -v in build 2.1.251 is --version, even though the docs claim it's the short form of --verbose. Check it on your own version before you rely on it.

What no documentation covers at all

A caveat for the future: since none of this is in the documentation, nobody ever promised to keep it. Building automation on top of it is a risk you take knowingly.

Some fifteen commands for artifacts. Out of this group the official reference has only /artifacts, /design, /design-login and /design-sync. Everything else — /prototype, /doc, /plan-artifact, /artifact-pr-review, /artifact-dashboard, /artifact-report, /artifact-data-table, /artifact-explainer, /artifact-components, /artifact-design, /artifact-diagramming, /artifact-capabilities — isn't mentioned anywhere. Same goes for /whiteboard, /whiteboard-mp and /workshop.

Seven subcommands of /design. Officially it's a single command that takes a description of the design. In the binary it understands sync, login, consent, revoke, import, export and status.

Diagnostics for your own spending. /skill-doctor, which shows unused skills, and /explain-usage, which explains where the money went in plain language, are both undocumented. So is /plugin-types, which generates types for the connected MCP tools.

Five more everyday commands. /brief — short-answer mode. /daemon — managing background services. /cloud-plugins — plugins in cloud sessions. /session (alias /remote) — the address of a remote session and a QR code for it; the reference has /remote-control and /teleport, but not this line. And /install, which installs the native build straight from the session.

Built-in skills everybody uses. /commit, /pr, /update-config, /claude-code-docs, /claude-in-chrome are described neither in the command reference nor in the section on built-in skills. The one indirect mention in the changelog is a bug fix for the agent calling a commit skill that didn't exist.

Commands turned off in this build. /version, /update, /loops, /wellbeing with all its aliases, and /pause-memory are registered but don't work. Not one of them appears in the changelog, neither as removed nor as added: /version, /wellbeing and /pause-memory never show up there once in the whole history, and the mentions of /update are bug fixes from back when it still worked.

Commands that appear depending on state. /limit-reset, /low-priority, /pro-trial-expired, /design-consent, /design-revoke, and /setup-cowork, which belongs to Cowork mode. The documentation admits to exactly one hidden command — dumping memory — and separately mentions that the provider configuration shows up along with an environment variable. About these six, nothing.

Internal entry points and model-only skills. __remote-workflow and workflow-launch-exec, through which the server hands a ready-made workflow to a session. And three skills the agent pulls in on its own that you can't type yourself: keybindings-help, memory-types, cowork-plugin. The mechanism — the user-invocable: false field — is documented; the skills themselves aren't.

How /code-review works inside. The documentation describes the levels qualitatively. How many independent search angles there are, how many candidates per angle, what the cap on findings is at each level, and the fact that on Opus 5 the medium and high levels currently collapse into a single pass — none of that is anywhere. Nor are the three argument-parsing rules that make ultra work only as the first word.

The /sandbox exclude "pattern" form. The official line about this command is one sentence: toggle sandbox mode. Nothing about taking individual commands out of the isolation, and nothing about the subcommand that finishes the install on Windows.

The /name alias of /rename. The reference's line about the command itself is unusually detailed — name sanitization and a length limit — but the alias isn't in it.

The --file flag. Downloading file resources at startup is missing from the list of flags.

Eight settings keys. Not a single line about them in the documentation, in the changelog, or in the published schema: doneMeansMerged — "done means merged"; breakReminder and quietHours — break reminders and quiet hours (a search turns up an article about the consumer Claude app, but that's a different thing and has no settings keys); precomputeCompactionEnabled; daemonColdStart; defaultView; autoUploadSessions; showMessageTimestamps. Plus xaaIdp together with the variable that turns it on, syncClaudeAiPlugins — even though its sibling syncClaudeAiSkills is documented — and proxyAuthHelper.

Keys that exist only in the published schema. sandbox.enabledPlatforms, skippedMarketplaces and skippedPlugins — zero mentions in the documentation and the changelog; the schema remains their only public trace.

Eight environment variables. The official page lists three hundred and forty-nine of them, and these aren't among them: CLAUDE_CODE_GOAL_CHECKIN_MINUTES, CLAUDE_CODE_WORKFLOW_PREFIX_STAGGER_MS, CLAUDE_CODE_DISABLE_AGENT_VIEW, CLAUDE_CODE_DISABLE_WORKFLOWS, CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING, CLAUDE_CODE_DISABLE_CLAUDE_MDS, CLAUDE_CODE_SHELL together with CLAUDE_CODE_SHELL_PREFIX, and USE_BUILTIN_RIPGREP. Some of them have documented neighbours under different names and with slightly different meaning — for turning thinking off, say, or for switching the file search — but those aren't the same thing.

The claude plugin eval subcommand. Running check cases against a plugin: the plugin reference lists ten subcommands, and this one isn't among them.

And the absence of what doesn't exist. There is no /init-verifiers command, /alias isn't a slash command, and there's no .claudeignore file at all. The documentation is naturally silent about things that don't exist — and there's no article about them on the internet either.

The number itself deserves a separate word. The official reference has a hundred and eleven lines, and it says honestly that not every command is available to everyone. How many are registered in total isn't published; in build 2.1.251 it comes to around a hundred and fifty, skills included. Community cheat sheets claim either two hundred and seventy-two (counting the command-line flags along the way) or about seventy — and neither figure rests on anything.

Where to start if you're seeing all this for the first time

There are a lot of tables here, and the first instinct is to close the page. So here's a short practical minimum: what's worth setting up on day one, and what you come back to as the need arises.

Right away, in the user file. Tool permissions: without them you'll be asked about every build and every git status, and within an hour you'll be hitting "allow" without reading — which is exactly the habit that later gets something deleted. The status line: spending and context fill that are permanently in view change your behavior more than any good intentions do. And a bigger cleanupPeriodDays, if you ever plan on digging up an old conversation or rolling back to a checkpoint.

In the project, committed to the repository. Permissions for the commands of this particular project, hooks that hold the invariants, and a .mcp.json with the servers the whole team needs.

For later. The sandbox, self-hosted environments, enterprise keys. They solve problems you most likely don't have yet; and the section on the sandbox is worth reading on exactly the day you first launch an agent that skips confirmations.

A file that's a fine place to start:

~/.claude/settings.json
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"cleanupPeriodDays": 365,
"fileCheckpointingEnabled": true,
"permissions": {
"allow": [
"Bash(git status)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Bash(npm run build)",
"Bash(npm test:*)"
],
"ask": ["Bash(git push:*)"],
"deny": ["Read(./.env)", "Read(./.secrets/**)"]
},
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.sh"
}
}

Five permissions already means noticeably fewer questions. One deny on the file with the secrets — because deny beats allow, and it's the cheapest way to make sure the contents of .env never ride into the context. Checkpointing is turned on explicitly: without it /rewind won't bring back a single file, and you usually learn that at the worst possible moment.

Sources

Everything this article stands on, with links. The Claude Code docs live at code.claude.com/docs; the old docs.claude.com addresses redirect there, so a year-old bookmark no longer lands where you expect.

What it covers in this articleDocumentation page
Slash commands: the list, the arguments, the version gatescommands
Keyboard shortcuts and input behaviourinteractive-mode
Code review: levels, flags, targetcode-review
Cloud review: diff limits and priceultrareview
Permission rules: syntax, path anchors, protected pathspermissions
Permission modes, dontAsk includedpermission-modes
Settings: where they live and what overrides whatsettings
Every settings key, one by onesettings-reference
Managed settings and policy sourcesmanaged-settings
Environment variables — all 349 of themenv-vars
Telemetry, metrics and eventsmonitoring-usage
Hooks: events, exit codes, matchershooks
Terminal subcommands and launch flagscli-reference
Non-interactive mode and output formatsheadless
MCP: transports, scopes, timeoutsmcp
Skills and the SKILL.md formatskills
Subagents and their frontmattersub-agents
Plugins, the manifest and marketplacesplugins-reference
Project memory and CLAUDE.mdmemory
The sandbox: files, network, secretssandboxing
Checkpoints and /rewindcheckpointing
Plan limits, credits, costcosts
Fast mode and what pays for itfast-mode
Models, aliases and the credit-billed variantsmodel-config
The advisoradvisor
Scheduled routinesroutines
Auto mode and its rulesauto-mode-config
The background agent viewagent-view
The status linestatusline
Self-hosted environments for cloud sessionsself-hosted-environments-reference
Review in GitHub Actionsgithub-actions
Error and warning textserrors
What fills up the context windowcontext-window

Two sources are not documentation, and without them half of this article would not exist. The changelog in the anthropics/claude-code repository is the only place that records what was removed or renamed in which version; the product no longer has a release-notes page of its own. The settings schema knows keys the docs never mention — though it also lags behind the product: it still carries a key that was removed in 2.1.234.

Verbatim command output was hunted through the entire docs corpus as a single file — easier than walking a hundred and ninety pages one at a time.

And the third source is the installed program itself. The lists of commands, settings keys and flags were taken from it rather than from the docs: it holds more of them, and in places the two disagree. Everything that could be checked by running it was checked by running it.