How It Works
- Tool invocation: The agent decides to call a tool that requires approval
- Execution pauses: The run transitions to an
await_approvalstate - User reviews: The pending tool call is presented to the user for review
- User responds: The user approves or rejects the tool call
- Execution resumes: The agent continues with the approved tools or handles rejections
Configuring Approval for Custom Tools
To require approval for a custom function tool, embedagents.BaseTool and set RequiresApproval: true:
Configuring Approval for MCP Tools
For MCP tools, use themcpclient.WithApprovalRequiredTools option when creating the client:
Handling Approval in Your Application
When a tool requires approval, the agent execution pauses and returns with apaused status. The pending tool calls are available in the run state.
Agent Output
Execute() (via the handle’s Result()/Wait()) returns an *agents.AgentOutput. When approval is needed, its Status is RunStatusPaused and the paused run exposes one Interrupt per pending tool call in Interrupts:
Interrupt carries the intercepted call and the kind of gate:
Mode discriminates the kind of pause, so one shape covers approval gates and MCP elicitations alike:
See MCP Tools → Elicitation for the form and URL flows.
Approval-required tools inside sub-agents (see Agent as a tool) bubble up to the parent’sInterruptswithIsNested: true, so the parent run pauses and surfaces them just like its own tools.
Resuming Execution
To resume execution after user review, send aFunctionCallInterruptResolutionMessage on the same thread, resolving each call by ID with InterruptActionApprove or InterruptActionReject. Execute() returns an *AgentHandle; the simplest way to wait for the resumed run is handle.Result():
Handling Rejections
To reject a call, resolve it withInterruptActionReject. You can approve some calls and reject others in the same Resolutions slice:
"Request to call this tool has been declined" and can adjust its response accordingly.
The resolution shape
Content is for interrupts that ask for data rather than a verdict — a submitted MCP form elicitation. Plain approvals leave it empty, and it is dropped on a rejection.
Pausing from a hook
A hook can pause a run too, by returning aToolCallResponse carrying Interrupts. That is how an unauthenticated caller is sent to a login URL from one place rather than from inside every tool.