Configure human-in-the-loop approval for tool calls, MCP invocations, and sub-agent delegation
Before registry tools, MCP tools, or sub-agent delegation execute, the SDK can pause and wait for human approval. One agent-level policy governs all three paths.
Every tool call, MCP call, and sub-agent delegation requires approval
AutoToolApprovalPolicy()
Nothing requires approval — use only when you fully trust the agent
AllowlistToolApprovalPolicy(config)
Listed tools/skills/sub-agents skip approval; everything else still requires it
When you omit WithToolApprovalPolicy, the default is require-all. If your agent has tools registered, every run will pause for approval unless you set a policy. For automated or trusted agents, use AutoToolApprovalPolicy().
Approval and delegation requests arrive as AgentEventTypeCustom events on the stream — not via WithApprovalHandler. Parse and respond with OnApproval:
for ev := range eventCh { if ev == nil || ev.Type() != agent.AgentEventTypeCustom { continue } ce, ok := ev.(*agent.AgentCustomEvent) if !ok { continue } if v, err := agent.ParseCustomEventApproval(ce); err == nil { _ = a.OnApproval(ctx, v.ApprovalToken, agent.ApprovalStatusApproved) } else if d, err := agent.ParseCustomEventDelegation(ce); err == nil { _ = a.OnApproval(ctx, d.ApprovalToken, agent.ApprovalStatusApproved) }}
For Run and RunAsync, use req.Respond() inside WithApprovalHandler. For Stream, use OnApproval with ApprovalToken from the parsed event — these are two separate paths and cannot be mixed.
Parent and specialist agents have independent policies:
Main agent: RequireAll → delegate to MathSpecialist → user approval on main streamMath agent: Auto → calculator inside specialist → no approvalMath agent: RequireAll → calculator inside specialist → approval (fan-in on main stream)
The main agent’s policy governs whether delegation itself requires approval. The specialist’s policy governs tool calls inside the specialist. Set each independently.