spring-ai-playground

description: Human-in-the-Loop approval in Spring AI Playground - require explicit approval before a tool runs, set it per tool, and approve or decline calls inside Agentic Chat.

Human-in-the-Loop Approval

Where: set it per tool in Tool Studio → Sandbox & Capabilities → Human-in-the-loop, or per re-exposed tool in the Composed Tools drawer’s HITL column. It then takes effect in Agentic Chat and for any external MCP client.

Human-in-the-loop (HITL) pauses a tool call and waits for you to approve or decline before the tool runs. The risk level warns you how dangerous a tool is; the sandbox limits what it can touch; HITL is the gate that asks “run this exact call?” at the moment it would fire.

It is the final safety layer, on top of the tool sandbox and the MCP risk model. The design and internals are on the Human-in-the-Loop Approval architecture page; this page is the how-to.

flowchart LR
    CALL["Agent decides<br/>to call a tool"]
    GATE{"Tool requires<br/>approval?"}
    ASK["Ask the human<br/>Approve / Decline"]
    RUN["Run the tool"]
    SKIP["Tell the model<br/>it was declined"]
    CALL --> GATE
    GATE -- "no" --> RUN
    GATE -- "yes" --> ASK
    ASK -- "Approve" --> RUN
    ASK -- "Decline / timeout" --> SKIP

The two modes { #modes }

Every tool has an approval mode:

Mode What it does
Required - ask every run The call is gated every time, for both Agentic Chat and external MCP clients.
Disabled - no prompt The tool runs without asking.

The mode defaults to Required above L0 and to Disabled at L0 - the more capable a tool, the more it asks out of the box.

Set approval on a tool you author { #author }

  1. Open Tool Studio and select or create a tool.
  2. Expand Sandbox & Capabilities.
  3. Under Human-in-the-loop, pick Required or Disabled.
  4. (Optional) In Approval prompt (optional), write the question shown at approval time. {toolName} and {args} are substituted at call time - e.g. Run tool '{toolName}' with arguments {args}?
  5. Test & Publish (or Test & Update).

!!! warning “Reducing oversight asks for confirmation” Moving a tool from Required to Disabled opens a Reduce human oversight? confirmation, so you never lower the gate by accident. Disabled lets any client run the tool immediately, with no approval step beyond the sandbox.

Require approval on a re-exposed external tool { #expose }

When you proxy an external tool through the built-in server, each row in the Composed Tools drawer has a HITL toggle:

You can toggle approval per tool, or for all selected tools at once. The same setting is available in YAML via the hitl: true key on a composed tool - see the Configuration reference.

Approve a call in Agentic Chat { #chat }

When the agent calls a gated tool, a dialog appears titled Tool approval required with the rendered prompt and two buttons:

If you don’t answer within two minutes, or close the dialog, the call is declined automatically - approval fails safe. If the agent requested several tools at once, each gated one is confirmed on its own; ungated calls run without interruption.

Walk through it end to end in Tutorial 11 - Approve a Tool in Chat.

What an external client sees { #external }

For an external MCP client (e.g. Claude Desktop) calling a Required tool on the built-in /mcp server, the built-in server issues an MCP elicitation request - a confirmation card the client renders before the call proceeds. If the client does not support elicitation, the call is denied (it cannot be approved). The playground’s own MCP Inspector → Elicitation shows elicitation requests the playground receives while acting as an MCP client; external clients render the built-in server’s approval prompt in their own UI.

Good defaults { #defaults }