Claude Code asks before every edit and every command. For the first ten minutes that feels right. After that you approve on reflex, and approving without reading is not reviewing: you keep the friction and lose the control.
The usual way out is the other extreme. An alias with --dangerously-skip-permissions, running on your main machine. It works until the day it doesn't.
Between those two extremes there are five levers to stop Claude Code asking for permission. They stack rather than compete, and the order matters: first the ones that remove prompts without removing any protection, last the ones that remove protections. This guide puts them in that order and sends you to the tip that covers each one in depth. I write it from daily use: I spend many hours a day in Claude Code, and I switched from YOLO mode to auto mode the day it shipped.
Why it keeps asking
Every tool call goes through the permission layer before it runs. Your rules are checked in a fixed order, deny, then ask, then allow, and the first match wins. The Tool(specifier) syntax takes wildcards and gitignore patterns, so one rule like Bash(npm run *) covers a whole family of commands. The three concepts are in Claude Code permissions: deny rules, modes and wildcards.
Whatever no rule covers, the mode decides. In default, Claude reads freely and asks before every edit and every command. acceptEdits approves edits and basic filesystem commands, but npm test, git push and curl still ask, and that misunderstanding accounts for much of the fatigue. What each of the six modes approves is in the 6 permission modes.
The rule also has to live in the right file. A "don't push" written in CLAUDE.md is a suggestion; the same rule under permissions.deny in settings.json is enforced by the engine, whatever Claude decides. Team rules are committed in .claude/settings.json, yours go in settings.local.json, which Claude Code keeps out of git when it creates it: CLAUDE.md, settings.json, or .mcp.json.
With that in place, the order.
1. Turn what repeats into rules
Most of your prompts are the same ten read-only commands. Before you touch the mode, turn them into allow rules. The risk is close to zero: you only pre-approve what you were already approving by hand.
You don't have to write them yourself. /fewer-permission-prompts reads your last 50 sessions, keeps the read-only commands you approved at least three times, and proposes up to 20 rules for the project's .claude/settings.json. It leaves out risky wildcards like Bash(python3:*) and anything that writes. Automatic allowlist in Claude Code.
If the prompt always comes from inside the same skill, the allowed-tools field in its frontmatter pre-approves only the tools you list while the skill is active; everything else still asks. Run the skill two or three times, note what you approve, and write it there. allowed-tools for your skills.
In claude -p nobody is there to press a key, so the rule is declared at launch: --allowedTools "Read" "Bash(curl *)" states exactly what the agent may do, and a read-only audit needs nothing more than "Read" "Glob" "Grep". Claude Code can work while you sleep.
2. Match the mode to the task
The mode isn't a one-time decision. It's a dial you turn with Shift+Tab depending on the work in front of you.
For a task you don't understand yet, use plan mode: Claude explores and proposes without touching a file, and when you approve you choose whether it continues in auto mode or with you approving each edit. Ctrl+G opens the plan in your editor before you approve it. Plan mode doesn't make Claude smarter, it forces you to think.
If you start a plan and walk away, "proceed with the plan?" sits there waiting. A PermissionRequest hook with "matcher": "ExitPlanMode" answers that one question; Bash, edits and MCP keep asking as before. Stop approving every plan in Claude Code.
The same Tool(pattern) syntax filters hooks too: the if field stops a hook from spawning when the call doesn't match. It's a performance tool, not a security one. An allow or deny that must hold belongs in permission rules, not in a hook. Conditional hooks, and the rest of the events in the practical hooks guide.
3. Let a classifier approve: auto mode
This is the big step. Auto mode puts a classifier between Claude and your machine: safe actions run without a prompt, risky ones (curl | bash, production deploys, force push) get blocked. Most of YOLO's flow, with a net under it. Escape Claude Code's permission fatigue without going YOLO.
Two configuration details before you rely on it. Since v2.1.228, new sessions on Pro, Max and Team start in auto, but if you want to pin it, "defaultMode": "auto" has to go in ~/.claude/settings.json: in the project's .claude/settings.json it is silently ignored. And if that project file still says "defaultMode": "bypassPermissions", the session starts in Manual even when your user settings say auto: Claude Code bypass permissions: project settings no longer turn it on. Broad allow rules such as Bash(*) are also switched off while auto is on; the narrow ones from step 1 stay.
The classifier reads prose, not patterns, so you can give it rules of your own as plain sentences under autoMode.soft_deny in ~/.claude/settings.json. Put "$defaults" first: without it, your sentence replaces every built-in rule. Check the result with claude auto-mode config. Write your own auto mode rules.
The built-in rules keep growing too. Auto mode now stops destructive local git (git reset --hard, git clean -fd), an rm -rf on a variable it can't resolve, and writes to the session transcript, and lets them through once your intent is explicit. When something gets blocked, the reason is in the "Recently denied" tab of /permissions. Auto mode now protects you from yourself.
One cost to keep in mind: entering or leaving auto mode breaks the prompt cache, so pick it at the start of the session instead of toggling back and forth: prompt caching in Claude Code.
4. Put up a wall: /sandbox
Auto mode decides with a model. /sandbox decides nothing: with the auto-allow option, commands run without a prompt, but the operating system stops them from writing outside the project or reaching domains you never approved. Watch the reads: by default it can still reach ~/.ssh and ~/.aws/credentials until you block them with sandbox.filesystem.denyRead. It runs on macOS, Linux and WSL2, and it complements auto mode: the classifier decides what Claude tries, the wall limits how far it gets. /sandbox in Claude Code.
5. Bypass, only inside a container
--dangerously-skip-permissions (the bypassPermissions mode) removes the classifier and almost every guardrail (deny rules still block). It has its place: throwaway containers, VMs, isolated CI. On your main machine, no.
In CI it has a trap of its own. In claude -p, a denied permission doesn't fail the run: you get exit 0, "subtype": "success" and "is_error": false even when Claude never touched a file, and the only trace is the permission_denials array. That's why so many people end up pasting the flag into the pipeline, when the right order is --allowedTools, then --permission-mode dontAsk, then auto, and bypass last. Why your script exits green without doing anything.
If you run several sessions, bypass has one more effect: a session in bypassPermissions holds messages from a session that does prompt until you approve them by hand. And a message from another session never counts as your consent. Message another Claude Code session.
Permissions reach beyond the terminal
The mode you pick also governs the browser. With /chrome, Claude works in your Chrome with your signed-in sessions: in Auto the classifier approves routine actions, and in Don't Ask anything that would need approval is skipped without telling you, so the task carries on without that click. /chrome in Claude Code.
And when you step away from the desk, a single prompt stalls the whole task. Push when actions required pings your phone when Claude is waiting on you. If it pings too often, the notification isn't the problem, your permissions are: go back to steps 1 and 3. Claude Code notifications on your phone.
What to do today
- Run
/fewer-permission-promptsand review the rules it proposes before you accept them. - Pin
"defaultMode": "auto"in~/.claude/settings.json, remove anybypassPermissionsfrom the project's.claude/settings.json, and add a rule of your own underautoMode.soft_deny, with"$defaults"first. - Turn on
/sandboxwith auto-allow and block reads of~/.sshand~/.aws. - Keep
--dangerously-skip-permissionsfor containers, and inclaude -preadpermission_denials.
After that, the prompts you still get are few, and they are worth reading. That's the control you were after.
If you're new to Claude Code, the context for all of this is in Claude Code first steps, which covers permissions alongside sessions, context, quota and models.