MCP elicitation UI
UI for MCP server-initiated user input requests mid-tool-execution. Form mode (schema-driven) for inline fields; URL mode for external credentials. Completes MCP client capability surface alongside tool-invocation (#100), permission-prompt (#101), server-state (#104), and sampling-approval (#103).
Spec — MCP elicitation UI
MCP normative source: https://modelcontextprotocol.io/specification/draft/client/elicitation.
Princípios
- *wo modes*— form (inline JSON schema fields) vs URL (external page for sensitive creds).
- *erver cancellable*— server may cancel; client respects + cleanup.
- *imeout default*— 5min; configurable per-elicitation.
- *o tenant leak*— input values scoped per workspace.
R1 — Form mode
Server sends elicitation request with JSON Schema:
{
"type": "elicitation/request",
"id": "e_123",
"schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "Your city"},
"temperature_unit": {"type": "string", "enum": ["C", "F"]}
},
"required": ["city"]
},
"title": "Weather lookup needs your input",
"description": "..."
}Client renders inline dialog with form fields:
| JSON Schema type | Field |
|---|---|
string |
text input (or textarea if format: textarea) |
number / integer |
spinner / number input |
boolean |
switch |
enum |
segmented control or dropdown |
array of string |
tag input |
object |
nested fieldset |
Required fields: asterisk; client-side validation before submit.
R2 — URL mode
Server requests external URL elicitation (credentials, OAuth, payment):
{
"type": "elicitation/request",
"id": "e_124",
"mode": "url",
"url": "https://server.example/elicit/abc",
"title": "Sign in to GitHub"
}Client opens external browser (desktop) / in-app WebView (mobile) OR delegates to koder_web_kit browse component for Web Surfaces.
Polling: client polls server elicitation/status/<id> until completion or timeout.
R3 — Actions
Form mode:
- *ccept* validate + submit values.
- *eject* emit
elicitation/rejectwith optional reason. - *ancel* emit
elicitation/cancel; close dialog.
URL mode:
- *ancel* same as form cancel; abort browser session.
R4 — Timeout
Default 5min. Server may set custom timeout. Visual countdown last 30s. On timeout: emit elicitation/timeout to server; close dialog.
R5 — Multi-tenant
Input values scoped per (koder_user_id, workspace_id, conversation_id, elicitation_id). Cross-tenant lookup 404.
R6 — Surface bindings
| Surface | API |
|---|---|
| Flutter | KoderMCPElicitationDialog({required schema, onAccept, onReject}) em koder_kit/lib/src/ai/mcp_elicitation.dart |
| Web | <koder-mcp-elicitation> |
| Compose/SwiftUI | futuro |
| CLI / TUI | Plain prompts inline; URL mode opens system browser |
R7 — Acessibilidade
- Dialog:
role="dialog" aria-modal="true". - Form fields: standard
<label for="...">+aria-required+aria-invalidon error. - Focus trap; ESC cancela; Tab cycle.
- URL mode: announce "Opening external page" to screen reader.
R8 — i18n
| Key | en-US | pt-BR |
|---|---|---|
mcp.elicitation.action.accept |
"Submit" | "Enviar" |
mcp.elicitation.action.reject |
"Reject" | "Recusar" |
mcp.elicitation.action.cancel |
"Cancel" | "Cancelar" |
mcp.elicitation.timeout_warning |
"Closing in {seconds}s" | "Fechando em {seconds}s" |
mcp.elicitation.url_mode.opening |
"Opening external page" | "Abrindo página externa" |
mcp.elicitation.field_required |
"Required" | "Obrigatório" |
T-suite
- *1*Form mount: schema with 2 fields → both fields rendered.
- *2*Validation: missing required → submit disabled; aria-invalid set.
- *3*Accept: valid form →
elicitation/acceptsent with values. - *4*Reject: button →
elicitation/rejectsent. - *5*Cancel: ESC →
elicitation/cancel. - *6*URL mode: opens browser; polls status; updates on complete.
- *7*Timeout: advance clock 5min →
elicitation/timeoutsent; dialog closes. - *8*Server cancel: server emits cancel → client closes; no submit.
- *9*Multi-tenant: workspace switch → previous elicitation dialog dismissed.
Cross-link
- Companion:
mcp-tool-invocation.kmd,mcp-permission-prompt.kmd,mcp-sampling-approval.kmd - Backend:
services/ai/mcp/ - Refs: https://modelcontextprotocol.io/specification/draft/client/elicitation, GitHub blog elicitation