CertSafari
    CCAR-P · Lessons

    Domain 5 · Lesson 28/38

    Human Approval Checkpoints for Claude Agent Tool Calls

    Apply human-in-the-loop validation strategies

    7 min read
    2.8% of exam
    3 sources
    Published 27 Sep 2026
    Docs as of 26 Sep 2026

    What you will be able to do

    • Decide which agent actions need a human checkpoint and explain why irreversible actions come first
    • Wire a canUseTool approval callback in the Claude Agent SDK and read the tool name and input it receives
    • Choose among the reviewer responses (approve, approve with changes, approve and remember, reject, suggest an alternative, redirect)
    • Route Claude's clarifying questions to a human through AskUserQuestion

    Key concept

    Human approval checkpoint — A point where the agent's proposed action stops and waits for a person to allow it, change it or refuse it before it runs. In the Agent SDK this is the canUseTool callback, and it runs only for calls that no earlier rule or mode has already settled.

    1.Where a human checkpoint earns its cost

    Human-in-the-loop validation means an agent stops before certain actions and waits for a person to approve, change or refuse them. The first design question is where to put those stops. Anthropic's guidance for agents that act on the web answers it directly: put them in front of irreversible actions. Its examples are submitting forms, making purchases, sending messages and modifying data. It also describes this checkpoint as the most effective mitigation against prompt injection, whatever the classifiers catch. A classifier can miss an injected instruction. A person who sees the concrete action before it runs gets a final chance to notice that it is not what they asked for.

    The same guidance adds two companions to the checkpoint. The first is to scope the agent's permissions, because a tool the agent does not have needs no approval and cannot be abused. The second is to log every action the agent takes, so reviewers can audit afterwards what they did not see live. Use all three together: a human gate on high-stakes actions, a narrow toolset, and a complete action log.

    In the Claude Agent SDK the checkpoint has a fixed place in how each tool call is resolved. The SDK checks hooks first, then deny rules, then ask rules, then the permission mode, then allow rules. Only a call that none of those settles reaches the approval callback. So human review is the last step in the chain, and everything before it decides how many calls a person actually sees.

    Sources12

    2.The canUseTool approval callback

    You pass a function as canUseTool (TypeScript) or can_use_tool (Python). It fires in two situations. The first is when Claude wants a tool that no permission rule or mode auto-approves. The second is when Claude calls the AskUserQuestion tool to ask something. The callback gets enough information to show a reviewer exactly what is about to happen:

    Arguments the approval callback receives
    ArgumentWhat the reviewer learns from it
    toolNameWhich tool Claude wants, for example Bash, Write or Edit
    inputThe parameters Claude is passing, which differ per tool (Bash: command, description, timeout; Write: file_path, content)
    options (TS) / context (Python)Optional suggestions (proposed PermissionUpdate entries to avoid re-prompting) and a cancellation signal

    The smallest useful callback asks the person and turns the answer into one of two results: allow with the input to run, or deny with a message.

    A minimal approval gate: ask the user, then allow or denytypescript
    canUseTool: async (toolName, input) => {
      console.log(`Claude wants to use ${toolName}`);
      const approved = await askUser("Allow this action?");
    
      if (approved) {
        return { behavior: "allow", updatedInput: input };
      }
      return { behavior: "deny", message: "User declined" };
    };

    For a Bash call, the documented example shows the reviewer the command and its description before asking. A prompt that shows only the tool name gives the reviewer nothing to judge.

    A fintech company's Claude-powered agent can initiate wire transfers through a custom MCP tool. Even though the operations team has configured allowedTools to auto-approve most read and reporting tools, they want every wire-transfer tool call to require a human's explicit approval no matter what permission mode the session is later switched to, including bypassPermissions. Which approach best satisfies this requirement?

    Sources3

    3.More than yes or no: shaping the reviewer's answer

    Allow and deny are the only two return types, but they cover six reviewer decisions. Allowing with a modified updatedInput lets a person fix a call instead of rejecting it. Denying with a descriptive message tells Claude why it was refused and what to try next.

    Reviewer decisions and how each maps onto the callback
    DecisionWhat happens
    ApproveThe tool executes as Claude requested
    Approve with changesThe input is modified before execution, for example to sanitize paths or add constraints
    Approve and rememberA suggested permission rule is echoed back so matching calls skip the prompt next time
    RejectThe tool is blocked and Claude is told why
    Suggest alternativeThe tool is blocked, and the message steers Claude toward what the user wants instead
    Redirect entirelyStreaming input sends Claude a completely new instruction
    The Python branch: allow with the (possibly modified) input, or deny with a message Claude readspython
        # Get user approval
        response = input("Allow this action? (y/n): ")
    
        # Return allow or deny based on user's response
        if response.lower() == "y":
            # Allow: tool executes with the original (or modified) input
            return PermissionResultAllow(updated_input=input_data)
        else:
            # Deny: tool doesn't execute, Claude sees the message
            return PermissionResultDeny(message="User denied this action")

    Sources3

    4.Humans answering, not only approving

    A human in the loop can also supply information. When Claude is unsure what the user wants, it can call AskUserQuestion. That call goes to the same callback, so your handler should check whether tool_name equals AskUserQuestion and show a question instead of an approval prompt. This matters if you restrict the agent's tools: when you pass an explicit tools array, AskUserQuestion has to be in it or Claude cannot ask.

    The Python SDK has one extra requirement. Its documented example streams the prompt and registers a no-op PreToolUse hook, labelled a required workaround, because that hook keeps the stream open so can_use_tool can run.

    Sources3

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.Denying a tool call just stops it, and Claude gets no feedback about why.Why is that wrong?

      A deny result carries a message that Claude reads. Rejecting a call and suggesting an alternative both work through that message.

      Covered in More than yes or no: shaping the reviewer's answer

    2. 2.Clarifying questions always reach the callback, even when you pass a restricted tools array.Why is that wrong?

      With an explicit tools array, AskUserQuestion must be listed, or Claude cannot ask the user anything through the callback.

      Covered in Humans answering, not only approving

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “Have the agent pause and request user confirmation before performing irreversible actions such as submitting forms, making purchases, sending messages, or modifying data.”
      ↩︎ Where a human checkpoint earns its cost
      “This is the single most effective mitigation against prompt injection regardless of classifier performance.”
      ↩︎ Where a human checkpoint earns its cost
      “Classifiers are one layer of defense, not a complete solution.”
      ↩︎ Where a human checkpoint earns its cost
    2. 2.
      “canUseTool callback: prompt users for approval at runtime, when no earlier step resolves the call.”
      ↩︎ Where a human checkpoint earns its cost
      “canUseTool callback: prompt users for approval at runtime, when no earlier step resolves the call.”
      ↩︎ Key concept
    3. 3.
      “The parameters Claude is passing to the tool. Contents vary by tool.”
      ↩︎ The canUseTool approval callback
      “Additional context including optional suggestions (proposed PermissionUpdate entries to avoid re-prompting) and a cancellation signal.”
      ↩︎ The canUseTool approval callback
      “Approve with changes: modify the input before execution (for example, sanitize paths, add constraints)”
      ↩︎ More than yes or no: shaping the reviewer's answer
      “Approve and remember: echo a suggested permission rule back so matching calls skip the prompt next time”
      ↩︎ More than yes or no: shaping the reviewer's answer
      “If you specify a tools array, include AskUserQuestion for this to work.”
      ↩︎ Humans answering, not only approving
      “# Required workaround: dummy hook keeps the stream open for can_use_tool”
      ↩︎ Humans answering, not only approving
      “Reject: block the tool and tell Claude why”
      ↩︎ Exam trap 1
      “If you specify a tools array, include AskUserQuestion for this to work.”
      ↩︎ Exam trap 2

    Continue to page 2 of 2

    Calibrating Human Review: Permission Modes and Managed Agent Policies