Follow Discord
Sweep 23 Oct 2026 · 21:48Z Build v2.1.310 529 read Stable v2.1.308 Latest v2.1.310 Next v2.1.310 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · claude-code

Handle approvals and user input changedagent-sdk/user-input

Nearest release: v2.1.295, published 9 hours before upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Upstream edited this page at 9 Oct 2026 03:28 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 23 Oct 2026 19:07 UTC.

Upstream edited
Recorded here
Lines+20added
Lines−20removed
From line 8 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits14to this page, all time

The whole hunk

from line 8, old and new numbered
/
lines
from line 8
88 
99For clarifying questions, Claude generates the questions and options. Your role is to present them to users and return their selections. You can't add your own questions to this flow; if you need to ask users something yourself, do that separately in your application logic.
1010 
11The callback can stay pending indefinitely. Execution remains paused until your callback returns. If a user might take longer to respond than your process can reasonably stay running, register a [`PreToolUse` hook](/docs/en/agent-sdk/hooks) that returns the [`defer` decision](/docs/en/hooks#defer-a-tool-call-for-later) instead of waiting in the callback, so the process can exit and resume later from the persisted session.
11The callback can stay pending indefinitely. Execution remains paused until your callback returns. If a user might take longer to respond than your process can reasonably stay running, register a [`PreToolUse` hook](https://code.claude.com/docs/en/agent-sdk/hooks) that returns the [`defer` decision](https://code.claude.com/docs/en/hooks#defer-a-tool-call-for-later) instead of waiting in the callback, so the process can exit and resume later from the persisted session.
1212 
1313This guide shows you how to detect each type of request and respond appropriately.
1414 
from line 42
4242 
4343The callback fires in two cases:
4444 
451. **Tool needs approval**: Claude wants to use a tool that isn't auto-approved by a [permission rule](/docs/en/agent-sdk/permissions.md) or permission mode. Check `tool_name` for the tool (e.g., `"Bash"`, `"Write"`).
451. **Tool needs approval**: Claude wants to use a tool that isn't auto-approved by a [permission rule](https://code.claude.com/docs/en/agent-sdk/permissions.md) or permission mode. Check `tool_name` for the tool (e.g., `"Bash"`, `"Write"`).
46462. **Claude asks a question**: Claude calls the `AskUserQuestion` tool. Check if `tool_name == "AskUserQuestion"` to handle it differently. If you specify a `tools` array, include `AskUserQuestion` for this to work. See [Handle clarifying questions](#handle-clarifying-questions) for details.
4747 
4848> [!WARNING]
4949>
50> **The callback never fires for auto-approved tools.** Any approval earlier in the [permission evaluation flow](/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated), an allow rule or a mode like `acceptEdits` or `bypassPermissions`, resolves the call before `canUseTool` is consulted. If you list a tool bare in `allowed_tools`, a `canUseTool` check for that tool runs only when the [evaluation flow](/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) routes the call back to a prompt, such as an ask rule or `plan` mode. For logic that must apply to every tool call, use a [`PreToolUse` hook](/docs/en/agent-sdk/hooks), which executes before the rest of the flow and can allow, deny, or modify requests.
50> **The callback never fires for auto-approved tools.** Any approval earlier in the [permission evaluation flow](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated), an allow rule or a mode like `acceptEdits` or `bypassPermissions`, resolves the call before `canUseTool` is consulted. If you list a tool bare in `allowed_tools`, a `canUseTool` check for that tool runs only when the [evaluation flow](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) routes the call back to a prompt, such as an ask rule or `plan` mode. For logic that must apply to every tool call, use a [`PreToolUse` hook](https://code.claude.com/docs/en/agent-sdk/hooks), which executes before the rest of the flow and can allow, deny, or modify requests.
5151>
52> An allow rule doesn't pre-approve the [actions no mode auto-approves](/docs/en/permission-modes.md#actions-no-mode-auto-approves); see [How permissions are evaluated](/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) for which of them reach the callback and what happens in `dontAsk` and `auto` mode.
52> An allow rule doesn't pre-approve the [actions no mode auto-approves](https://code.claude.com/docs/en/permission-modes.md#actions-no-mode-auto-approves); see [How permissions are evaluated](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) for which of them reach the callback and what happens in `dontAsk` and `auto` mode.
5353 
54You can also use the [`PermissionRequest` hook](/docs/en/agent-sdk/hooks#available-hooks) to send external notifications (Slack, email, push) when Claude is waiting for approval.
54You can also use the [`PermissionRequest` hook](https://code.claude.com/docs/en/agent-sdk/hooks#available-hooks) to send external notifications (Slack, email, push) when Claude is waiting for approval.
5555 
5656## Handle tool approval requests
5757 
58Once you've passed a `canUseTool` callback in your query options, it fires when Claude wants to use a tool that nothing earlier in the permission flow has approved. In some configurations, such as `dontAsk` mode, Claude Code doesn't call it; the last step of [How permissions are evaluated](/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) lists them and says what happens to the call instead.
58Once you've passed a `canUseTool` callback in your query options, it fires when Claude wants to use a tool that nothing earlier in the permission flow has approved. In some configurations, such as `dontAsk` mode, Claude Code doesn't call it; the last step of [How permissions are evaluated](https://code.claude.com/docs/en/agent-sdk/permissions.md#how-permissions-are-evaluated) lists them and says what happens to the call instead.
5959 
6060Your callback receives three arguments:
6161 
from line 63
6363| - | - |
6464| `toolName` | The name of the tool Claude wants to use (for example, `"Bash"`, `"Write"`, `"Edit"`) |
6565| `input` | The parameters Claude is passing to the tool. Contents vary by tool. |
66| `options` (TS) / `context` (Python) | Additional context including optional `suggestions` (proposed `PermissionUpdate` entries to avoid re-prompting) and a cancellation signal. In TypeScript, `signal` is an `AbortSignal`; in Python, the signal field is reserved for future use. See [`ToolPermissionContext`](/docs/en/agent-sdk/python#toolpermissioncontext) for Python. |
66| `options` (TS) / `context` (Python) | Additional context including optional `suggestions` (proposed `PermissionUpdate` entries to avoid re-prompting) and a cancellation signal. In TypeScript, `signal` is an `AbortSignal`; in Python, the signal field is reserved for future use. See [`ToolPermissionContext`](https://code.claude.com/docs/en/agent-sdk/python#toolpermissioncontext) for Python. |
6767 
6868The `input` object contains tool-specific parameters. Common examples:
6969 
from line 74
7474| `Edit` | `file_path`, `old_string`, `new_string` |
7575| `Read` | `file_path`, `offset`, `limit` |
7676 
77See the SDK reference for complete input schemas: [Python](/docs/en/agent-sdk/python.md#tool-input%2Foutput-types) | [TypeScript](/docs/en/agent-sdk/typescript.md#tool-input-types).
77See the SDK reference for complete input schemas: [Python](https://code.claude.com/docs/en/agent-sdk/python.md#tool-input%2Foutput-types) | [TypeScript](https://code.claude.com/docs/en/agent-sdk/typescript.md#tool-input-types).
7878 
7979You can display this information to the user so they can decide whether to allow or reject the action, then return the appropriate response.
8080 
from line 217
217217* **Approve and remember**: echo a suggested permission rule back so matching calls skip the prompt next time
218218* **Reject**: block the tool and tell Claude why
219219* **Suggest alternative**: block but guide Claude toward what the user wants instead
220* **Redirect entirely**: use [streaming input](/docs/en/agent-sdk/streaming-vs-single-mode.md) to send Claude a completely new instruction
220* **Redirect entirely**: use [streaming input](https://code.claude.com/docs/en/agent-sdk/streaming-vs-single-mode.md) to send Claude a completely new instruction
221221 
222222The `ask_user` and `askUser` helpers in the following snippets stand in for your application's own prompt UI.
223223 
from line 279
279279 
280280**Approve and remember**
281281 
282The user approves and doesn't want to be asked again for this kind of call. The third callback argument carries `suggestions`, an array of ready-made [`PermissionUpdate`](/docs/en/agent-sdk/typescript#permissionupdate) entries. Echo one back in `updatedPermissions` to apply it. A suggestion with the `localSettings` destination writes the rule to `.claude/settings.local.json` so future sessions skip the prompt for matching calls.
282The user approves and doesn't want to be asked again for this kind of call. The third callback argument carries `suggestions`, an array of ready-made [`PermissionUpdate`](https://code.claude.com/docs/en/agent-sdk/typescript#permissionupdate) entries. Echo one back in `updatedPermissions` to apply it. A suggestion with the `localSettings` destination writes the rule to `.claude/settings.local.json` so future sessions skip the prompt for matching calls.
283283 
284In TypeScript, skip the always-allow choice for a request whose options carry [`suppressAlwaysAllowRule: true`](/docs/en/agent-sdk/typescript#canusetool). The hint requires Agent SDK v0.3.268 or later, and the Python `context` doesn't carry it.
284In TypeScript, skip the always-allow choice for a request whose options carry [`suppressAlwaysAllowRule: true`](https://code.claude.com/docs/en/agent-sdk/typescript#canusetool). The hint requires Agent SDK v0.3.268 or later, and the Python `context` doesn't carry it.
285285 
286286The Python example requires `claude-agent-sdk` 0.1.80 or later.
287287 
from line 379
379379 
380380**Redirect entirely**
381381 
382For a complete change of direction (not just a nudge), use [streaming input](/docs/en/agent-sdk/streaming-vs-single-mode.md) to send Claude a new instruction directly. This bypasses the current tool request and gives Claude entirely new instructions to follow.
382For a complete change of direction (not just a nudge), use [streaming input](https://code.claude.com/docs/en/agent-sdk/streaming-vs-single-mode.md) to send Claude a new instruction directly. This bypasses the current tool request and gives Claude entirely new instructions to follow.
383383 
384384## Handle clarifying questions
385385 
from line 387
387387 
388388> [!TIP]
389389>
390> Clarifying questions are especially common in [`plan` mode](/docs/en/agent-sdk/permissions#plan-mode-plan), where Claude explores the codebase and asks questions before proposing a plan. This makes plan mode ideal for interactive workflows where you want Claude to gather requirements before making changes.
390> Clarifying questions are especially common in [`plan` mode](https://code.claude.com/docs/en/agent-sdk/permissions#plan-mode-plan), where Claude explores the codebase and asks questions before proposing a plan. This makes plan mode ideal for interactive workflows where you want Claude to gather requirements before making changes.
391391 
392392The following steps show how to handle clarifying questions:
393393 
from line 800
800800 
801801### Streaming input
802802 
803Use [streaming input](/docs/en/agent-sdk/streaming-vs-single-mode.md) when you need to:
803Use [streaming input](https://code.claude.com/docs/en/agent-sdk/streaming-vs-single-mode.md) when you need to:
804804 
805805* **Interrupt the agent mid-task**: send a cancel signal or change direction while Claude is working
806806* **Provide additional context**: add information Claude needs without waiting for it to ask
from line 810
810810 
811811### Custom tools
812812 
813Use [custom tools](/docs/en/agent-sdk/custom-tools.md) when you need to:
813Use [custom tools](https://code.claude.com/docs/en/agent-sdk/custom-tools.md) when you need to:
814814 
815815* **Collect structured input**: build forms, wizards, or multi-step workflows that go beyond `AskUserQuestion`'s multiple-choice format
816816* **Integrate external approval systems**: connect to existing ticketing, workflow, or approval platforms
from line 820
820820 
821821## Related resources
822822 
823* [Configure permissions](/docs/en/agent-sdk/permissions.md): set up permission modes and rules
824* [Control execution with hooks](/docs/en/agent-sdk/hooks.md): run custom code at key points in the agent lifecycle
825* [TypeScript SDK reference](/docs/en/agent-sdk/typescript.md#canusetool): full canUseTool API documentation
823* [Configure permissions](https://code.claude.com/docs/en/agent-sdk/permissions.md): set up permission modes and rules
824* [Control execution with hooks](https://code.claude.com/docs/en/agent-sdk/hooks.md): run custom code at key points in the agent lifecycle
825* [TypeScript SDK reference](https://code.claude.com/docs/en/agent-sdk/typescript.md#canusetool): full canUseTool API documentation
826826 
Feedback