feat(mcp): elicitation for confirmations and interactive flows #6

Closed
opened 2026-07-11 21:09:03 +00:00 by hexajon · 3 comments
hexajon commented 2026-07-11 21:09:03 +00:00 (Migrated from codeberg.org)

Part of #10.

Claude Code fully supports MCP elicitation: "When a server needs information it can't get on its own, Claude Code displays an interactive dialog and passes your response back to the server. No configuration is required" (docs, verified 2026-07-06). madtea never uses it — today the server can only error out and hope the agent re-calls correctly.

Prime use cases, in value order:

  1. Bare-close reason — with close_requires_reason=require, instead of hard-refusing, elicit the reason from the human and proceed.
  2. Destructive-op confirmationmadt_issues action=delete, gated admin-domain destructive ops: elicit an explicit confirm instead of trusting the agent's judgment.
  3. madtea setup over MCP — the CLI setup flow uses survey prompts; an MCP-side setup could elicit URL/token interactively instead of being CLI-only.

Acceptance criteria

  • Capability-gated: elicitation only attempted when the client declares the elicitation capability; current behavior (error with guidance) is the fallback — no regression on non-supporting clients
  • At least the bare-close-reason and one destructive-confirm flow use elicitation end-to-end
  • Tests cover both the elicit path (mock client with capability) and the fallback path
  • Live check in Claude Code: dialog appears, response reaches the server, operation completes
  • Steering/help text updated where the error-path wording changes
Part of #10. Claude Code fully supports MCP elicitation: "When a server needs information it can't get on its own, Claude Code displays an interactive dialog and passes your response back to the server. No configuration is required" (docs, verified 2026-07-06). madtea never uses it — today the server can only error out and hope the agent re-calls correctly. Prime use cases, in value order: 1. **Bare-close reason** — with `close_requires_reason=require`, instead of hard-refusing, elicit the reason from the human and proceed. 2. **Destructive-op confirmation** — `madt_issues action=delete`, gated admin-domain destructive ops: elicit an explicit confirm instead of trusting the agent's judgment. 3. **`madtea setup` over MCP** — the CLI setup flow uses survey prompts; an MCP-side setup could elicit URL/token interactively instead of being CLI-only. ## Acceptance criteria - [ ] Capability-gated: elicitation only attempted when the client declares the `elicitation` capability; current behavior (error with guidance) is the fallback — no regression on non-supporting clients - [ ] At least the bare-close-reason and one destructive-confirm flow use elicitation end-to-end - [ ] Tests cover both the elicit path (mock client with capability) and the fallback path - [ ] Live check in Claude Code: dialog appears, response reaches the server, operation completes - [ ] Steering/help text updated where the error-path wording changes
hexajon commented 2026-07-11 22:08:47 +00:00 (Migrated from codeberg.org)

Landed in a later PR (2026-07-09): capability-gated elicitation for the two pinned flows — bare-close reason (single + batch, elicited reason feeds the same path as reason=; decline/empty/error → the byte-identical refusal) and issue-delete confirmation (decline/error → fail-safe abort). Non-elicitation clients unchanged on every path. Notable: review caught a would-be production bug headless — Claude Code's bundled schema rejects form elicitation without requestedSchema.properties, so the delete-confirm now sends a minimal empty-properties schema (which Claude Code renders as exactly the message-only accept/decline dialog we want), with a wire-shape regression test.

What keeps this open — two things:

  1. Live check (the usual headless-unverifiable criterion): in an interactive Claude Code session on a post-release binary, (a) set close_requires_reason=require, bare-close an issue and confirm the reason dialog appears and the typed reason lands in the closing comment; (b) madt_issues action=delete on a scratch issue and confirm the confirm dialog appears, decline aborts, accept deletes.
  2. The issue's third use case — madtea setup over MCP (elicit URL/token interactively) — was deliberately left out of this slice; it's a bigger surface (credential flow over elicitation needs its own security look, ADR 0013). Say the word and it gets its own ladder, or close this issue after the live check and file it separately.
Landed in a later PR (2026-07-09): capability-gated elicitation for the two pinned flows — bare-close reason (single + batch, elicited reason feeds the same path as `reason=`; decline/empty/error → the byte-identical refusal) and issue-delete confirmation (decline/error → fail-safe abort). Non-elicitation clients unchanged on every path. Notable: review caught a would-be production bug headless — Claude Code's bundled schema rejects form elicitation without `requestedSchema.properties`, so the delete-confirm now sends a minimal empty-properties schema (which Claude Code renders as exactly the message-only accept/decline dialog we want), with a wire-shape regression test. **What keeps this open — two things:** 1. **Live check (the usual headless-unverifiable criterion):** in an interactive Claude Code session on a post-release binary, (a) set `close_requires_reason=require`, bare-close an issue and confirm the reason dialog appears and the typed reason lands in the closing comment; (b) `madt_issues action=delete` on a scratch issue and confirm the confirm dialog appears, decline aborts, accept deletes. 2. **The issue's third use case — `madtea setup` over MCP (elicit URL/token interactively)** — was deliberately left out of this slice; it's a bigger surface (credential flow over elicitation needs its own security look, ADR 0013). Say the word and it gets its own ladder, or close this issue after the live check and file it separately.
hexajon commented 2026-07-11 22:08:48 +00:00 (Migrated from codeberg.org)

madtea setup or mcp tooling for same should be its own issue

madtea setup or mcp tooling for same should be its own issue
hexajon commented 2026-07-17 19:26:53 +00:00 (Migrated from codeberg.org)

Labelled status/needs-decision after today's strict-omission convergence changed this issue's ground. Where each original ask stands:

  • Bare-close reason elicitation: superseded by #167 - under close_requires_reason=require a bare close is refused on every client, elicitation-capable or not (consent-vs-substance line; refusal parity across clients).
  • Delete-confirm elicitation: shipped via the earlier destructive-delete work, then REMOVED by ADR 0029 / the #209 convergence - irreversible deletes are now omitted from every surface, not dialog-gated, and with zero remaining consumers the elicitation seam itself was removed from internal/mcp.
  • Remaining "interactive flows": no current consumer exists. ADR 0029 records elicitation as the sanctioned mechanism for FUTURE reversible-but-notable consent features; the go-sdk provides Elicit natively, so a future feature re-adds the thin helper with its first use case.

Decision needed: close this as superseded by ADR 0029 (the pattern this issue proposed for destruction is deliberately retired, and nothing reversible currently wants a dialog), or reshape it into a placeholder for the first reversible-consent use case. CLOSING.

Labelled status/needs-decision after today's strict-omission convergence changed this issue's ground. Where each original ask stands: - Bare-close reason elicitation: superseded by #167 - under close_requires_reason=require a bare close is refused on every client, elicitation-capable or not (consent-vs-substance line; refusal parity across clients). - Delete-confirm elicitation: shipped via the earlier destructive-delete work, then REMOVED by ADR 0029 / the #209 convergence - irreversible deletes are now omitted from every surface, not dialog-gated, and with zero remaining consumers the elicitation seam itself was removed from internal/mcp. - Remaining "interactive flows": no current consumer exists. ADR 0029 records elicitation as the sanctioned mechanism for FUTURE reversible-but-notable consent features; the go-sdk provides Elicit natively, so a future feature re-adds the thin helper with its first use case. Decision needed: close this as superseded by ADR 0029 (the pattern this issue proposed for destruction is deliberately retired, and nothing reversible currently wants a dialog), or reshape it into a placeholder for the first reversible-consent use case. CLOSING.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sixfold-space/madtea#6
No description provided.