Skip to main content

Elicitation & HITL — Advanced Features

← Back to Dashboard
1. Sampling & Roots2. Async Tasks (2025)3. Elicitation & HITL4. Structured Content & Tool Annotations5. Completions & Metadata

Elicitation & HITL

📚 Advanced Features⏱ 9 min⭐ 100 XP⌨ Hands-on lab

Interactive Elicitation & Human-in-the-Loop (HITL)

In autonomous agent workflows, tools frequently encounter situations where information is ambiguous, credentials require out-of-band authorization, or actions carry destructive enterprise impact (e.g., dropping a production database partition or force-pushing a shared branch).

Elicitation (elicitation/create) allows an MCP server to request structured input or confirmation directly from the human user. MCP supports two distinct elicitation modes:

  • Form Mode (introduced in 2025-06-18): The server supplies a flat requestedSchema (strings, numbers, booleans, enums), and the Host UI renders a native form returning action: "accept" | "decline" | "cancel" plus typed content.
  • URL Mode (introduced in 2025-11-25): The server returns mode: "url" with a target url and elicitationId, directing the user to a secure browser page for sensitive secrets, API keys, or third-party OAuth flows that must never pass through the LLM client.
Stateless Multi Round-Trip Requests (Spec 2026-07-28)
  • Form / URL Request: Over stdio or stateful streams, server.server.elicitInput() prompts the client directly; over stateless 2026-07-28 HTTP, the server returns an InputRequiredResult (MRTR) containing an opaque requestState.
  • Client Presentation & Retry: The host displays the approval dialog or opens the URL, then re-invokes the request with inputResponses—preserving state without sticky HTTP sessions.
server.registerTool(
  "deploy_production_release",
  {
    description: "Deploy a service version to production with HITL approval",
    inputSchema: z.object({ service: z.string(), version: z.string() })
  },
  async ({ service, version }) => {
    // Human-in-the-loop confirmation gate via official MCP Elicitation API
    const result = await server.server.elicitInput({
      message: "Deploying " + service + " to PRODUCTION (" + version + "). Confirm release?",
      requestedSchema: {
        type: "object",
        properties: { confirm: { type: "boolean", title: "Confirm Production Release" } },
        required: ["confirm"]
      }
    });

    if (result.action !== "accept" || !result.content?.confirm) {
      return { content: [{ type: "text", text: "Deployment aborted by user." }] };
    }

    await triggerProdRelease(service, version);
    return { content: [{ type: "text", text: "Successfully released " + service + " v" + version + " to prod." }] };
  }
);
⌨ HANDS-ON LABSimulate Human-in-the-Loop Confirmation
⭐ +150 XP

Trigger a sensitive tool requiring explicit user approval before execution.

1Call a sensitive tool with confirm flag.
lab-sandbox — simulated environment
INFINITY LAB SANDBOX v2.6 — simulated shell
Type the command for the current objective. Helpers: "hint", "solution", "clear".
$
OBJECTIVE 1 / 1 — type "hint" if stuck
🧪 Knowledge Check
Press 1-4 to select1 of 3
What occurs during Elicitation?
The server crashes to reboot.
The server pauses execution, requesting the UI to ask the human a clarifying question.
The LLM forgets the context window.
The transport layer switches to UDP.