Skip to content

elicit_confirm

Ask the user an OK/Cancel confirmation — modeled on JavaScript’s confirm(), as a convenience wrapper over elicit_form.

One question, binary answer, decided by the person at the host right now. For multiple typed fields use elicit_form; for a decision that must survive the session or reach another reviewer, use the Pro approval tools — see Choosing a tool.

Parameter Type Required Description
message string yes The question shown to the user.
labels object no { ok?, cancel? }, each 1–40 characters. Defaults "OK" / "Cancel". Relabel or localize (e.g. Aceptar/Cancelar) — labels only rename the choices; their order and meaning stay fixed.
timeoutSeconds number no Default 300, clamped 603600 — how long to wait for the answer. The default 5 minutes gives a human time to notice and respond; raise it for a question you expect to sit unanswered for a while.
{ "message": "Ship it?", "labels": { "ok": "OK", "cancel": "Cancel" }, "timeoutSeconds": 300 }
{ "confirmed": true }

confirmed is the whole story, and it is three-state:

  • true — the user chose “OK”: proceed.
  • false — a human explicitly said no, whether they chose “Cancel” or declined the dialog itself.
  • null — no answer was obtained; reason says why: "dismissed" (the dialog was closed unanswered) or "error" (timeout, or the host failed to render it). Ask again later.

Unlike JavaScript’s confirm(), an explicit “Cancel” choice (confirmed: false) is distinguished from an unanswered dialog (confirmed: null). The MCP-level elicitation action is deliberately not echoed — how the “no” arrived (the Cancel option inside the form vs. the host’s own decline control) has no caller value. Use elicit_form if you need the raw {action, content}.

Defaults are all most confirmations need:

{ "message": "Ship v2.1.0 to production?" }

The user sees an OK/Cancel dialog; on OK:

{ "confirmed": true }

For consequential actions, relabel the options so the button says what it does — and note the three-state subtlety in the result:

{
"message": "Permanently delete 42 archived reports?",
"labels": { "ok": "Delete permanently", "cancel": "Keep them" }
}

If the user picks “Keep them” and submits, that is an answered question, not a dismissal:

{ "confirmed": false }

— whereas closing the dialog without answering yields { "confirmed": null, "reason": "dismissed" }. A skill deleting data should proceed only on "confirmed": true, treat false as a clear “no”, and treat null as “ask again later”.