6 6
7> Control how your agent uses tools with permission modes, hooks, and declarative allow/deny rules.7> Control how your agent uses tools with permission modes, hooks, and declarative allow/deny rules.
8 8
9The Claude Agent SDK provides permission controls to manage how Claude uses tools. Use permission modes and rules to define what's allowed automatically, and the [`canUseTool` callback](/docs/en/agent-sdk/user-input) to handle everything else at runtime.9The Claude Agent SDK provides permission controls to manage how Claude uses tools. Use permission modes and rules to define what's allowed automatically, and the [`canUseTool` callback](https://code.claude.com/docs/en/agent-sdk/user-input) to handle everything else at runtime.
10 10
11## How permissions are evaluated11## How permissions are evaluated
12 12
14 14
15**1. Hooks**15**1. Hooks**
16 16
17Run [hooks](/docs/en/agent-sdk/hooks.md) first. A hook can deny the call outright or pass it on. A hook that returns `allow` doesn't skip the deny and ask rules below, which are evaluated regardless of the hook result.17Run [hooks](https://code.claude.com/docs/en/agent-sdk/hooks.md) first. A hook can deny the call outright or pass it on. A hook that returns `allow` doesn't skip the deny and ask rules below, which are evaluated regardless of the hook result.
18 18
19A `PreToolUse` hook that returns `allow` also can't approve an `rm` or `rmdir` command whose target Claude Code recognizes as a [critical path](/docs/en/permission-modes.md#critical-paths), such as `rm -rf ~`. For what that `allow` does in plan mode, see [Hook approvals in plan mode](/docs/en/permissions.md#hook-approvals-in-plan-mode).19A `PreToolUse` hook that returns `allow` also can't approve an `rm` or `rmdir` command whose target Claude Code recognizes as a [critical path](https://code.claude.com/docs/en/permission-modes.md#critical-paths), such as `rm -rf ~`. For what that `allow` does in plan mode, see [Hook approvals in plan mode](https://code.claude.com/docs/en/permissions.md#hook-approvals-in-plan-mode).
20 20
21**2. Deny rules**21**2. Deny rules**
22 22
23Check `deny` rules (from `disallowed_tools` and [settings.json](/docs/en/settings-reference.md#permission-settings)). If a deny rule matches, the tool is blocked, even in `bypassPermissions` mode. Bare-name deny rules like `Bash` remove the tool from Claude's context before this evaluation begins, so only scoped rules like `Bash(rm *)` are checked at this step.23Check `deny` rules (from `disallowed_tools` and [settings.json](https://code.claude.com/docs/en/settings-reference.md#permission-settings)). If a deny rule matches, the tool is blocked, even in `bypassPermissions` mode. Bare-name deny rules like `Bash` remove the tool from Claude's context before this evaluation begins, so only scoped rules like `Bash(rm *)` are checked at this step.
24 24
25**3. Ask rules**25**3. Ask rules**
26 26
27Check `ask` rules from [settings.json](/docs/en/settings-reference.md#permission-settings). If an ask rule matches, the call falls through to your [`canUseTool` callback](/docs/en/agent-sdk/user-input) for confirmation, even in `bypassPermissions` mode.27Check `ask` rules from [settings.json](https://code.claude.com/docs/en/settings-reference.md#permission-settings). If an ask rule matches, the call falls through to your [`canUseTool` callback](https://code.claude.com/docs/en/agent-sdk/user-input) for confirmation, even in `bypassPermissions` mode.
28 28
29Tools that require user interaction behave the same way: `AskUserQuestion` and MCP tools whose server sets [`_meta["anthropic/requiresUserInteraction"]`](/docs/en/mcp#require-approval-for-a-specific-tool) always fall through to the callback, even when an allow rule matches. In `dontAsk` mode both cases are denied instead, because that mode never prompts. The MCP annotation requires Claude Code v2.1.199 or later.29Tools that require user interaction behave the same way: `AskUserQuestion` and MCP tools whose server sets [`_meta["anthropic/requiresUserInteraction"]`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool) always fall through to the callback, even when an allow rule matches. In `dontAsk` mode both cases are denied instead, because that mode never prompts. The MCP annotation requires Claude Code v2.1.199 or later.
30 30
31[claude.ai connector](/docs/en/mcp.md#organization-controls-on-connector-tools) tools your organization has set to `ask` also leave the flow at this step. Every call falls through to the callback, even in `bypassPermissions` mode and even when an allow rule matches. The callback receives the reason `Your organization requires approval for this tool`. In `dontAsk` mode the call is denied instead, because that mode never prompts.31[claude.ai connector](https://code.claude.com/docs/en/mcp.md#organization-controls-on-connector-tools) tools your organization has set to `ask` also leave the flow at this step. Every call falls through to the callback, even in `bypassPermissions` mode and even when an allow rule matches. The callback receives the reason `Your organization requires approval for this tool`. In `dontAsk` mode the call is denied instead, because that mode never prompts.
32 32
33**4. Permission mode**33**4. Permission mode**
34 34
35Apply the active [permission mode](#permission-modes):35Apply the active [permission mode](#permission-modes):
36 36
37* In `bypassPermissions` mode, Claude Code approves everything that reaches this step except recognized [critical-path removals](/docs/en/permission-modes.md#critical-paths), which fall through instead.37* In `bypassPermissions` mode, Claude Code approves everything that reaches this step except recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths), which fall through instead.
38* In `acceptEdits` mode, Claude Code approves the file operations listed under [Accept edits mode](#accept-edits-mode-acceptedits).38* In `acceptEdits` mode, Claude Code approves the file operations listed under [Accept edits mode](#accept-edits-mode-acceptedits).
39* In `plan` mode, Claude Code sends file-edit and shell-write tools to your `canUseTool` callback regardless of allow rules, so write operations can't be auto-approved while planning.39* In `plan` mode, Claude Code sends file-edit and shell-write tools to your `canUseTool` callback regardless of allow rules, so write operations can't be auto-approved while planning.
40* In other modes, the request falls through.40* In other modes, the request falls through.
41 41
42**5. Allow rules**42**5. Allow rules**
43 43
44Check `allow` rules (from `allowed_tools` and settings.json). If a rule matches, the tool is approved. A call the tool approves on its own is resolved at this step too, with no rule needed: for example a file read inside your working directories or a [read-only Bash command](/docs/en/permissions.md#read-only-commands).44Check `allow` rules (from `allowed_tools` and settings.json). If a rule matches, the tool is approved. A call the tool approves on its own is resolved at this step too, with no rule needed: for example a file read inside your working directories or a [read-only Bash command](https://code.claude.com/docs/en/permissions.md#read-only-commands).
45 45
46Recognized [critical-path removals](/docs/en/permission-modes.md#critical-paths) aren't approved by an allow rule. Whether they then reach your callback depends on the permission mode: in an Agent SDK session in `auto` mode, for example, Claude Code denies them by default without calling it. The [Critical paths mode table](/docs/en/permission-modes.md#critical-path-removals-in-each-permission-mode) lists what each mode does with them.46Recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) aren't approved by an allow rule. Whether they then reach your callback depends on the permission mode: in an Agent SDK session in `auto` mode, for example, Claude Code denies them by default without calling it. The [Critical paths mode table](https://code.claude.com/docs/en/permission-modes.md#critical-path-removals-in-each-permission-mode) lists what each mode does with them.
47 47
48An allow rule doesn't approve a read from a [network path](/docs/en/permissions.md#network-paths).48An allow rule doesn't approve a read from a [network path](https://code.claude.com/docs/en/permissions.md#network-paths).
49 49
50**6. canUseTool callback**50**6. canUseTool callback**
51 51
52If not resolved by any of the above, call your [`canUseTool` callback](/docs/en/agent-sdk/user-input) for a decision. In `dontAsk` mode, this step is skipped and the tool is denied, though a [mod](/docs/en/plugins/mods/overview.md) you installed can still approve [some such calls](/docs/en/permissions.md#precedence-among-rules-hooks-and-mods).52If not resolved by any of the above, call your [`canUseTool` callback](https://code.claude.com/docs/en/agent-sdk/user-input) for a decision. In `dontAsk` mode, this step is skipped and the tool is denied, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve [some such calls](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods).
53 53
54In the TypeScript SDK, if you set [`permissionPrompts: 'none'`](/docs/en/agent-sdk/typescript#options), your callback isn't called at this step. A [`PermissionRequest` hook](/docs/en/hooks#permissionrequest) still gets a chance to decide, and if it doesn't, Claude Code denies the call. The option requires Claude Code v2.1.259 or later.54In the TypeScript SDK, if you set [`permissionPrompts: 'none'`](https://code.claude.com/docs/en/agent-sdk/typescript#options), your callback isn't called at this step. A [`PermissionRequest` hook](https://code.claude.com/docs/en/hooks#permissionrequest) still gets a chance to decide, and if it doesn't, Claude Code denies the call. The option requires Claude Code v2.1.259 or later.
55 55
5656
57 57
58If you pass a `canUseTool` callback in a configuration where the TypeScript SDK expects the evaluation order to auto-approve calls before the callback is consulted, the SDK emits a Node.js process warning once when the query is constructed. The warning's code is `CLAUDE_SDK_CAN_USE_TOOL_SHADOWED`. Two configurations trigger it:58If you pass a `canUseTool` callback in a configuration where the TypeScript SDK expects the evaluation order to auto-approve calls before the callback is consulted, the SDK emits a Node.js process warning once when the query is constructed. The warning's code is `CLAUDE_SDK_CAN_USE_TOOL_SHADOWED`. Two configurations trigger it:
59 59
60* `permissionMode: 'bypassPermissions'`, which auto-approves every call that reaches the permission mode step apart from the [actions no mode auto-approves](/docs/en/permission-modes.md#actions-no-mode-auto-approves)60* `permissionMode: 'bypassPermissions'`, which auto-approves every call that reaches the permission mode step apart from the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves)
61* Each bare `allowedTools` entry such as `"Read"`, which auto-approves that whole tool before the callback is consulted, apart from the [actions no mode auto-approves](/docs/en/permission-modes.md#actions-no-mode-auto-approves) and [reads from network paths](/docs/en/permissions.md#network-paths)61* Each bare `allowedTools` entry such as `"Read"`, which auto-approves that whole tool before the callback is consulted, apart from the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves) and [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths)
62 62
63Entries with a specifier such as `Bash(ls *)` and the `acceptEdits` mode don't trigger it, and allow rules coming from settings files aren't visible to the check.63Entries with a specifier such as `Bash(ls *)` and the `acceptEdits` mode don't trigger it, and allow rules coming from settings files aren't visible to the check.
64 64
65Listen with `process.on('warning', ...)` and match the code to log or suppress it. To gate every tool call regardless of mode and rules, use a [`PreToolUse` hook](/docs/en/agent-sdk/hooks) instead.65Listen with `process.on('warning', ...)` and match the code to log or suppress it. To gate every tool call regardless of mode and rules, use a [`PreToolUse` hook](https://code.claude.com/docs/en/agent-sdk/hooks) instead.
66 66
67This page focuses on **allow and deny rules** and **permission modes**. For the other steps:67This page focuses on **allow and deny rules** and **permission modes**. For the other steps:
68 68
69* **Hooks:** run custom code to allow, deny, or modify tool requests. See [Control execution with hooks](/docs/en/agent-sdk/hooks.md).69* **Hooks:** run custom code to allow, deny, or modify tool requests. See [Control execution with hooks](https://code.claude.com/docs/en/agent-sdk/hooks.md).
70* **canUseTool callback:** prompt users for approval at runtime, when no earlier step resolves the call. See [Handle approvals and user input](/docs/en/agent-sdk/user-input.md).70* **canUseTool callback:** prompt users for approval at runtime, when no earlier step resolves the call. See [Handle approvals and user input](https://code.claude.com/docs/en/agent-sdk/user-input.md).
71 71
72## Allow and deny rules72## Allow and deny rules
73 73
74`allowed_tools` and `disallowed_tools` (TypeScript: `allowedTools` / `disallowedTools`) add entries to the allow and deny rule lists in the evaluation flow above. If you name one of the [task-tracking tools](/docs/en/agent-sdk/todo-tracking.md#model-availability) in `allowed_tools`, Claude Code also opts the session in. Any other tool not listed in `allowed_tools` is still available to Claude, and a call to it that needs approval falls through to the permission mode. Deny rules behave differently depending on whether they name a tool or scope a pattern within one.74`allowed_tools` and `disallowed_tools` (TypeScript: `allowedTools` / `disallowedTools`) add entries to the allow and deny rule lists in the evaluation flow above. If you name one of the [task-tracking tools](https://code.claude.com/docs/en/agent-sdk/todo-tracking.md#model-availability) in `allowed_tools`, Claude Code also opts the session in. Any other tool not listed in `allowed_tools` is still available to Claude, and a call to it that needs approval falls through to the permission mode. Deny rules behave differently depending on whether they name a tool or scope a pattern within one.
75 75
76| Option | Effect |76| Option | Effect |
77| :- | :- |77| :- | :- |
78| `allowed_tools=["Read", "Grep"]` | `Read` and `Grep` are auto-approved, apart from [reads from network paths](/docs/en/permissions.md#network-paths). Other tools not listed here still exist, and calls to them that need approval fall through to the permission mode and `canUseTool`. |78| `allowed_tools=["Read", "Grep"]` | `Read` and `Grep` are auto-approved, apart from [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths). Other tools not listed here still exist, and calls to them that need approval fall through to the permission mode and `canUseTool`. |
79| `disallowed_tools=["Bash"]` | The `Bash` tool definition is removed from the request. Claude does not see the tool and cannot attempt it. |79| `disallowed_tools=["Bash"]` | The `Bash` tool definition is removed from the request. Claude does not see the tool and cannot attempt it. |
80| `disallowed_tools=["Bash(rm *)"]` | `Bash` stays available. Calls matching `rm *` [as written](/docs/en/permissions.md#bash-rule-limits) are denied in every permission mode, including `bypassPermissions`. Other `Bash` calls, including `/bin/rm`, fall through to the permission mode. |80| `disallowed_tools=["Bash(rm *)"]` | `Bash` stays available. Calls matching `rm *` [as written](https://code.claude.com/docs/en/permissions.md#bash-rule-limits) are denied in every permission mode, including `bypassPermissions`. Other `Bash` calls, including `/bin/rm`, fall through to the permission mode. |
81| `disallowed_tools=["*"]` | Every tool definition is removed from the request. Tool-name globs are supported in deny rules: `"*"` matches every tool and `"mcp__*"` matches every MCP tool across all servers. |81| `disallowed_tools=["*"]` | Every tool definition is removed from the request. Tool-name globs are supported in deny rules: `"*"` matches every tool and `"mcp__*"` matches every MCP tool across all servers. |
82 82
83Allow rules accept tool-name globs only after a literal `mcp__<server>__` prefix. The server segment must be glob-free so the rule names a specific server you configured: `mcp__puppeteer__*` matches every tool from the `puppeteer` server, and `mcp__github__get_*` matches its `get_` tools. An unanchored entry like `allowed_tools=["*"]` or `allowed_tools=["mcp__*"]` is ignored and doesn't auto-approve anything.83Allow rules accept tool-name globs only after a literal `mcp__<server>__` prefix. The server segment must be glob-free so the rule names a specific server you configured: `mcp__puppeteer__*` matches every tool from the `puppeteer` server, and `mcp__github__get_*` matches its `get_` tools. An unanchored entry like `allowed_tools=["*"]` or `allowed_tools=["mcp__*"]` is ignored and doesn't auto-approve anything.
84 84
85Scoped rules for `Read` and `Edit` take a path pattern. `Edit(path)` rules govern all built-in tools that write files, including `Write` and `NotebookEdit`; a `Write(path)` rule is never matched by the file permission checks.85Scoped rules for `Read` and `Edit` take a path pattern. `Edit(path)` rules govern all built-in tools that write files, including `Write` and `NotebookEdit`; a `Write(path)` rule is never matched by the file permission checks.
86 86
87Use `//path` for an absolute filesystem path: a deny rule of `Edit(//secrets/**)` blocks writes anywhere under `/secrets` on disk. With a single leading slash, `Edit(/secrets/**)` anchors at the rule's source instead. For rules passed through `allowed_tools` or `disallowed_tools`, that means the session's working directory, so the rule doesn't block `/secrets` on disk. See [Read and Edit rules](/docs/en/permissions.md#read-and-edit) for the four anchor forms and how rules from settings files resolve.87Use `//path` for an absolute filesystem path: a deny rule of `Edit(//secrets/**)` blocks writes anywhere under `/secrets` on disk. With a single leading slash, `Edit(/secrets/**)` anchors at the rule's source instead. For rules passed through `allowed_tools` or `disallowed_tools`, that means the session's working directory, so the rule doesn't block `/secrets` on disk. See [Read and Edit rules](https://code.claude.com/docs/en/permissions.md#read-and-edit) for the four anchor forms and how rules from settings files resolve.
88 88
89> [!WARNING]89> [!WARNING]
90>90>
91> **Auto-approved tools never reach `canUseTool`.** A tool call approved at any earlier step, by `acceptEdits` or `bypassPermissions`, or by an allow rule, skips your `canUseTool` callback, so permission checks you put there are silently bypassed for that tool.91> **Auto-approved tools never reach `canUseTool`.** A tool call approved at any earlier step, by `acceptEdits` or `bypassPermissions`, or by an allow rule, skips your `canUseTool` callback, so permission checks you put there are silently bypassed for that tool.
92>92>
93> No allow rule auto-approves `AskUserQuestion`, MCP tools marked [`_meta["anthropic/requiresUserInteraction"]`](/docs/en/mcp#require-approval-for-a-specific-tool), connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools), or recognized `rm` and `rmdir` [critical-path removals](/docs/en/permission-modes.md#critical-paths). In `dontAsk` mode Claude Code denies these calls without invoking the callback. In other modes the first three reach the callback. The [Critical paths mode table](/docs/en/permission-modes.md#critical-path-removals-in-each-permission-mode) lists what each mode does with a critical-path removal. The check that recognizes these removals [can miss some commands](/docs/en/permission-modes.md#critical-paths).93> No allow rule auto-approves `AskUserQuestion`, MCP tools marked [`_meta["anthropic/requiresUserInteraction"]`](https://code.claude.com/docs/en/mcp#require-approval-for-a-specific-tool), connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), or recognized `rm` and `rmdir` [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths). In `dontAsk` mode Claude Code denies these calls without invoking the callback. In other modes the first three reach the callback. The [Critical paths mode table](https://code.claude.com/docs/en/permission-modes.md#critical-path-removals-in-each-permission-mode) lists what each mode does with a critical-path removal. The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths).
94>94>
95> Coverage depends on the entry's form: a bare name like `Read` or `mcp__github__get_issue` auto-approves every call to that tool apart from those exceptions and [reads from network paths](/docs/en/permissions.md#network-paths), while a scoped rule like `Bash(npm test *)` auto-approves only matching calls, and other `Bash` calls that need approval still fall through to the callback. For checks that must run on every tool call, use a [`PreToolUse` hook](/docs/en/agent-sdk/hooks): hooks run before every other step, and a hook deny applies even in `bypassPermissions` mode.95> Coverage depends on the entry's form: a bare name like `Read` or `mcp__github__get_issue` auto-approves every call to that tool apart from those exceptions and [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths), while a scoped rule like `Bash(npm test *)` auto-approves only matching calls, and other `Bash` calls that need approval still fall through to the callback. For checks that must run on every tool call, use a [`PreToolUse` hook](https://code.claude.com/docs/en/agent-sdk/hooks): hooks run before every other step, and a hook deny applies even in `bypassPermissions` mode.
96 96
97For a locked-down agent, pair `allowedTools` with `permissionMode: "dontAsk"`:97For a locked-down agent, pair `allowedTools` with `permissionMode: "dontAsk"`:
98 98
103};103};
104```104```
105 105
106Listed tools are approved, apart from the [actions no mode auto-approves](/docs/en/permission-modes.md#actions-no-mode-auto-approves) and [reads from network paths](/docs/en/permissions.md#network-paths). Every other call that would prompt is denied instead, though a [mod](/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](/docs/en/permissions.md#precedence-among-rules-hooks-and-mods).106Listed tools are approved, apart from the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves) and [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths). Every other call that would prompt is denied instead, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods).
107 107
108Calls that need no approval in `default` mode run whether or not you list them. They include [read-only Bash commands](/docs/en/permissions.md#read-only-commands), tools like `Agent` that don't ask before running, and file reads inside your working directories. To remove a tool from the request entirely, add its bare name to `disallowedTools`.108Calls that need no approval in `default` mode run whether or not you list them. They include [read-only Bash commands](https://code.claude.com/docs/en/permissions.md#read-only-commands), tools like `Agent` that don't ask before running, and file reads inside your working directories. To remove a tool from the request entirely, add its bare name to `disallowedTools`.
109 109
110> [!WARNING]110> [!WARNING]
111>111>
112> **`allowed_tools` does not constrain `bypassPermissions`.** `allowed_tools` pre-approves the tools you list. Other unlisted tools are not matched by any allow rule and fall through to the permission mode, where `bypassPermissions` approves them. Setting `allowed_tools=["Read"]` alongside `permission_mode="bypassPermissions"` still approves every tool, including `Bash`, `Write`, and `Edit`. If you need `bypassPermissions` but want specific tools blocked, use `disallowed_tools`.112> **`allowed_tools` does not constrain `bypassPermissions`.** `allowed_tools` pre-approves the tools you list. Other unlisted tools are not matched by any allow rule and fall through to the permission mode, where `bypassPermissions` approves them. Setting `allowed_tools=["Read"]` alongside `permission_mode="bypassPermissions"` still approves every tool, including `Bash`, `Write`, and `Edit`. If you need `bypassPermissions` but want specific tools blocked, use `disallowed_tools`.
113 113
114You can also configure allow, deny, and ask rules declaratively in `.claude/settings.json`. These rules are read when the `project` setting source is enabled, which it is for default `query()` options. If you set `setting_sources` (TypeScript: `settingSources`) explicitly, include `"project"` for them to apply. See [Permission settings](/docs/en/settings-reference.md#permission-settings) for the rule syntax.114You can also configure allow, deny, and ask rules declaratively in `.claude/settings.json`. These rules are read when the `project` setting source is enabled, which it is for default `query()` options. If you set `setting_sources` (TypeScript: `settingSources`) explicitly, include `"project"` for them to apply. See [Permission settings](https://code.claude.com/docs/en/settings-reference.md#permission-settings) for the rule syntax.
115 115
116## Permission modes116## Permission modes
117 117
118Permission modes provide global control over how Claude uses tools. You can set the permission mode when calling `query()` or change it dynamically during streaming sessions.118Permission modes provide global control over how Claude uses tools. You can set the permission mode when calling `query()` or change it dynamically during streaming sessions.
119 119
120With Claude Code v2.1.302 or later, your app starts in `default` mode unless you set a permission mode or it gets one from [`permissions.defaultMode`](/docs/en/settings-reference#permissions-defaultmode) in its settings files. In `default` mode, Claude Code denies any tool call needing approval unless you approve it through an allow rule, hook, `canUseTool` callback, or permission prompt tool. If tool calls are denied, see [Tool calls denied in `claude -p` and Agent SDK runs](/docs/en/permission-modes#which-mode-a-non-interactive-run-starts-in).120With Claude Code v2.1.302 or later, your app starts in `default` mode unless you set a permission mode or it gets one from [`permissions.defaultMode`](https://code.claude.com/docs/en/settings-reference#permissions-defaultmode) in its settings files. In `default` mode, Claude Code denies any tool call needing approval unless you approve it through an allow rule, hook, `canUseTool` callback, or permission prompt tool. If tool calls are denied, see [Tool calls denied in `claude -p` and Agent SDK runs](https://code.claude.com/docs/en/permission-modes#which-mode-a-non-interactive-run-starts-in).
121 121
122### Available modes122### Available modes
123 123
126| Mode | Description | Tool behavior |126| Mode | Description | Tool behavior |
127| :- | :- | :- |127| :- | :- | :- |
128| `default` | Standard permission behavior | No mode-based auto-approvals; calls that need approval and match no allow rule trigger your `canUseTool` callback |128| `default` | Standard permission behavior | No mode-based auto-approvals; calls that need approval and match no allow rule trigger your `canUseTool` callback |
129| `dontAsk` | Deny instead of prompting | Any call that would otherwise prompt is denied without calling `canUseTool`, though a [mod](/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](/docs/en/permissions.md#precedence-among-rules-hooks-and-mods). Calls approved by `allowed_tools` or `settings.json` allow rules run, and so do calls that need no approval in `default` mode. Some calls, such as [reads from network paths](/docs/en/permissions.md#network-paths), are denied even when `allowed_tools` or an allow rule matches them. For the list, see [Don't ask mode](#don’t-ask-mode-dontask) |129| `dontAsk` | Deny instead of prompting | Any call that would otherwise prompt is denied without calling `canUseTool`, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods). Calls approved by `allowed_tools` or `settings.json` allow rules run, and so do calls that need no approval in `default` mode. Some calls, such as [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths), are denied even when `allowed_tools` or an allow rule matches them. For the list, see [Don't ask mode](#don’t-ask-mode-dontask) |
130| `acceptEdits` | Auto-accept file edits | File edits and [filesystem operations](#accept-edits-mode-acceptedits) (`mkdir`, `rm`, `mv`, etc.) are automatically approved |130| `acceptEdits` | Auto-accept file edits | File edits and [filesystem operations](#accept-edits-mode-acceptedits) (`mkdir`, `rm`, `mv`, etc.) are automatically approved |
131| `bypassPermissions` | Bypass permission checks | Tools run without permission prompts, except for the [actions no mode auto-approves](/docs/en/permission-modes.md#actions-no-mode-auto-approves). Use with caution |131| `bypassPermissions` | Bypass permission checks | Tools run without permission prompts, except for the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves). Use with caution |
132| `plan` | Planning mode | Claude explores and plans without editing your source files; file edits are never auto-approved and prompt through your `canUseTool` callback |132| `plan` | Planning mode | Claude explores and plans without editing your source files; file edits are never auto-approved and prompt through your `canUseTool` callback |
133| `auto` | Model-classified approvals | A model classifier reviews actions such as shell commands and network requests, allowing or blocking each one it reviews. See [Auto mode](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) for availability and the decision order |133| `auto` | Model-classified approvals | A model classifier reviews actions such as shell commands and network requests, allowing or blocking each one it reviews. See [Auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) for availability and the decision order |
134 134
135> [!WARNING]135> [!WARNING]
136>136>
137> **Subagent inheritance:** A subagent runs in the parent session's permission mode unless you set `permissionMode` on its [`AgentDefinition`](/docs/en/agent-sdk/typescript#agentdefinition) and the parent session is in `default`, `dontAsk`, or `plan` mode. Even then, Claude Code never applies a `"bypassPermissions"` value, and applies an `"auto"` value only when [auto mode is available](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) to that subagent. A subagent runs in `bypassPermissions` mode only when the parent session itself does. The `bypassPermissions` exception requires Claude Code v2.1.267 or later.137> **Subagent inheritance:** If your main session is in [plan mode](https://code.claude.com/docs/en/permission-modes.md#analyze-before-you-edit-with-plan-mode), a subagent whose [`AgentDefinition`](https://code.claude.com/docs/en/agent-sdk/typescript#agentdefinition) sets `permissionMode: "acceptEdits"` still runs in plan mode. That subagent's `Edit` and `Write` calls on your source files still go to your `canUseTool` callback. Plan mode holds for the subagents you define too, so that handing work to one doesn't get around reviewing the plan first.
138>138>
139> Subagents may have different system prompts and less constrained behavior than your main agent, so inheriting `bypassPermissions` grants them full, autonomous system access. The [actions no mode auto-approves](/docs/en/permission-modes.md#actions-no-mode-auto-approves) still apply.139> The subagent inherits `plan`, `acceptEdits`, `auto`, or `bypassPermissions` from the main session, and under a `default`- or `dontAsk`-mode main session it runs in the mode you set. Even then, Claude Code never applies a `"bypassPermissions"` value, and applies an `"auto"` value only when [auto mode is available](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode) to that subagent. The `bypassPermissions` exception requires Claude Code v2.1.267 or later.
140>
141> Subagents may have different system prompts and less constrained behavior than your main agent, so inheriting `bypassPermissions` grants them full, autonomous system access. The [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves) still apply.
140 142
141### Set permission mode143### Set permission mode
142 144
253 255
254* Works on a path outside that scope256* Works on a path outside that scope
255* Writes to a protected path257* Writes to a protected path
256* Removes a path that Claude Code recognizes as a [critical path](/docs/en/permission-modes.md#critical-paths) with `rm` or `rmdir`258* Removes a path that Claude Code recognizes as a [critical path](https://code.claude.com/docs/en/permission-modes.md#critical-paths) with `rm` or `rmdir`
257 259
258**Use when:** you trust Claude's edits and want faster iteration, such as during prototyping or when working in an isolated directory.260**Use when:** you trust Claude's edits and want faster iteration, such as during prototyping or when working in an isolated directory.
259 261
260#### Don't ask mode (`dontAsk`)262#### Don't ask mode (`dontAsk`)
261 263
262Converts any permission prompt into a denial, without calling `canUseTool`, though a [mod](/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](/docs/en/permissions.md#precedence-among-rules-hooks-and-mods). Tools pre-approved by `allowed_tools`, `settings.json` allow rules, or a hook run as normal. Calls that need no approval in `default` mode also run, such as file reads inside your working directories and calls to `Agent`.264Converts any permission prompt into a denial, without calling `canUseTool`, though a [mod](https://code.claude.com/docs/en/plugins/mods/overview.md) you installed can still approve [some of those calls](https://code.claude.com/docs/en/permissions.md#precedence-among-rules-hooks-and-mods). Tools pre-approved by `allowed_tools`, `settings.json` allow rules, or a hook run as normal. Calls that need no approval in `default` mode also run, such as file reads inside your working directories and calls to `Agent`.
263 265
264Connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools), tools that require user interaction, [reads from network paths](/docs/en/permissions.md#network-paths), and recognized [critical-path removals](/docs/en/permission-modes.md#critical-paths) are denied even when an allow rule matches. A `PreToolUse` hook allow doesn't clear a recognized critical-path removal or a read from a network path either. The check that recognizes these removals [can miss some commands](/docs/en/permission-modes.md#critical-paths).266Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), tools that require user interaction, [reads from network paths](https://code.claude.com/docs/en/permissions.md#network-paths), and recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) are denied even when an allow rule matches. A `PreToolUse` hook allow doesn't clear a recognized critical-path removal or a read from a network path either. The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths).
265 267
266**Use when:** you want a fixed, explicit tool surface for a headless agent and prefer a hard deny over silent reliance on `canUseTool` being absent.268**Use when:** you want a fixed, explicit tool surface for a headless agent and prefer a hard deny over silent reliance on `canUseTool` being absent.
267 269
268#### Bypass permissions mode (`bypassPermissions`)270#### Bypass permissions mode (`bypassPermissions`)
269 271
270Auto-approves tool uses without prompting, except the cases listed in the warning below. Hooks still execute and can block operations if needed. On Linux and macOS, Claude Code refuses to start in this mode as root or under `sudo` outside a [recognized sandbox](/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode), and the query fails before the first turn.272Auto-approves tool uses without prompting, except the cases listed in the warning below. Hooks still execute and can block operations if needed. On Linux and macOS, Claude Code refuses to start in this mode as root or under `sudo` outside a [recognized sandbox](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode), and the query fails before the first turn.
271 273
272> [!WARNING]274> [!WARNING]
273>275>
276> `allowed_tools` does not constrain this mode. Every tool is approved, not just the ones you listed. These controls still apply:278> `allowed_tools` does not constrain this mode. Every tool is approved, not just the ones you listed. These controls still apply:
277>279>
278> * Deny rules, explicit `ask` rules, and hooks are evaluated before the mode check and can still block a tool.280> * Deny rules, explicit `ask` rules, and hooks are evaluated before the mode check and can still block a tool.
279> * Connector tools [your organization set to `ask`](/docs/en/mcp#organization-controls-on-connector-tools), tools that require user interaction, and recognized [critical-path removals](/docs/en/permission-modes.md#critical-paths) still fall through to your `canUseTool` callback. The check that recognizes these removals [can miss some commands](/docs/en/permission-modes.md#critical-paths).281> * Connector tools [your organization set to `ask`](https://code.claude.com/docs/en/mcp#organization-controls-on-connector-tools), tools that require user interaction, and recognized [critical-path removals](https://code.claude.com/docs/en/permission-modes.md#critical-paths) still fall through to your `canUseTool` callback. The check that recognizes these removals [can miss some commands](https://code.claude.com/docs/en/permission-modes.md#critical-paths).
280> * The [cross-session messaging safeguards](/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) still apply.282> * The [cross-session messaging safeguards](https://code.claude.com/docs/en/permission-modes.md#skip-all-checks-with-bypasspermissions-mode) still apply.
281 283
282#### Plan mode (`plan`)284#### Plan mode (`plan`)
283 285
287 289
288In the TypeScript SDK, if you set `allowDangerouslySkipPermissions: true` alongside `permissionMode: 'plan'`, file edits and shell commands that modify files still reach your `canUseTool` callback. The option lets you switch to `bypassPermissions` later with `setPermissionMode()`.290In the TypeScript SDK, if you set `allowDangerouslySkipPermissions: true` alongside `permissionMode: 'plan'`, file edits and shell commands that modify files still reach your `canUseTool` callback. The option lets you switch to `bypassPermissions` later with `setPermissionMode()`.
289 291
290Claude may use `AskUserQuestion` to clarify requirements before finalizing the plan. See [Handle approvals and user input](/docs/en/agent-sdk/user-input.md#handle-clarifying-questions) for handling these prompts.292Claude may use `AskUserQuestion` to clarify requirements before finalizing the plan. See [Handle approvals and user input](https://code.claude.com/docs/en/agent-sdk/user-input.md#handle-clarifying-questions) for handling these prompts.
291 293
292**Use when:** you want Claude to propose changes without executing them, such as during code review or when you need to approve changes before they're made.294**Use when:** you want Claude to propose changes without executing them, such as during code review or when you need to approve changes before they're made.
293 295
294#### Auto mode (`auto`)296#### Auto mode (`auto`)
295 297
296A classifier model reviews actions such as shell commands and network requests before they run, and allows or blocks each one it reviews. For the models and providers auto mode requires and the order it evaluates actions in, see [Eliminate permission prompts with auto mode](/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode).298A classifier model reviews actions such as shell commands and network requests before they run, and allows or blocks each one it reviews. For the models and providers auto mode requires and the order it evaluates actions in, see [Eliminate permission prompts with auto mode](https://code.claude.com/docs/en/permission-modes.md#eliminate-prompts-with-auto-mode).
297 299
298If you switch a session that's in auto mode to a model that auto mode doesn't support, using [`set_model()`](/docs/en/agent-sdk/python#claudesdkclient), [`setModel()`](/docs/en/agent-sdk/typescript#query-object), or [`applyFlagSettings()`](/docs/en/agent-sdk/typescript#applyflagsettings), the session changes to `default` mode:300If you switch a session that's in auto mode to a model that auto mode doesn't support, using [`set_model()`](https://code.claude.com/docs/en/agent-sdk/python#claudesdkclient), [`setModel()`](https://code.claude.com/docs/en/agent-sdk/typescript#query-object), or [`applyFlagSettings()`](https://code.claude.com/docs/en/agent-sdk/typescript#applyflagsettings), the session changes to `default` mode:
299 301
300* **What you see**: a `system` message with subtype `status` and `permissionMode` set to `"default"`, which the TypeScript SDK types as [`SDKStatusMessage`](/docs/en/agent-sdk/typescript#sdkstatusmessage). From then on, calls that need approval and match no allow rule reach your `canUseTool` callback.302* **What you see**: a `system` message with subtype `status` and `permissionMode` set to `"default"`, which the TypeScript SDK types as [`SDKStatusMessage`](https://code.claude.com/docs/en/agent-sdk/typescript#sdkstatusmessage). From then on, calls that need approval and match no allow rule reach your `canUseTool` callback.
301* **To return to auto mode**: switch to a supported model, then call `set_permission_mode("auto")` or `setPermissionMode("auto")`. If you switch the model back without making that call, the session stays in `default` mode. While the unsupported model is active, the call fails with `Cannot set permission mode to auto: auto mode unavailable for this model`.303* **To return to auto mode**: switch to a supported model, then call `set_permission_mode("auto")` or `setPermissionMode("auto")`. If you switch the model back without making that call, the session stays in `default` mode. While the unsupported model is active, the call fails with `Cannot set permission mode to auto: auto mode unavailable for this model`.
302 304
303The change to `default` mode after a `set_model()`, `setModel()`, or `applyFlagSettings()` call requires Claude Code v2.1.299 or later.305The change to `default` mode after a `set_model()`, `setModel()`, or `applyFlagSettings()` call requires Claude Code v2.1.299 or later.
306 308
307For the other steps in the permission evaluation flow:309For the other steps in the permission evaluation flow:
308 310
309* [Handle approvals and user input](/docs/en/agent-sdk/user-input.md): interactive approval prompts and clarifying questions311* [Handle approvals and user input](https://code.claude.com/docs/en/agent-sdk/user-input.md): interactive approval prompts and clarifying questions
310* [Hooks guide](/docs/en/agent-sdk/hooks.md): run custom code at key points in the agent lifecycle312* [Hooks guide](https://code.claude.com/docs/en/agent-sdk/hooks.md): run custom code at key points in the agent lifecycle
311* [Permission rules](/docs/en/settings-reference.md#permission-settings): declarative allow/deny rules in `settings.json`313* [Permission rules](https://code.claude.com/docs/en/settings-reference.md#permission-settings): declarative allow/deny rules in `settings.json`