import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import type { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { type RiskLevel, type AutoApproveRisk } from "../registry/types.js"; export interface ElicitationResult { /** Whether the operation should proceed. */ proceed: boolean; /** Why the operation was stopped, if applicable. */ reason?: "declined" | "cancelled"; /** How the confirmation was resolved — maps directly to ConfirmationMethod for audit. */ method: "elicited" | "caller_confirmed" | "auto_approved" | "not_required" | "blocked"; } /** * Build a tool-handler-friendly error string for a non-proceeding * `ElicitationResult`. Branches on `method` so the recovery hint matches * what actually happened: * * - `elicited` → the client completed the handshake and the user explicitly * declined or cancelled. Authoritative; `confirm: true` does NOT bypass. * - `blocked` → the client did not surface a usable prompt (no elicitation * capability, `elicitInput` failed, or accept arrived without * `confirm=true`). Caller can retry with `confirm: true` to opt in for * non-interactive automation. */ export declare function describeElicitationFailure(result: ElicitationResult): string; /** * Build the audit-row error string for a non-proceeding * `ElicitationResult`. Mirrors `describeElicitationFailure` in attributing * the block correctly: the `blocked` method is a CLIENT-side failure to * surface a prompt, not a human decline, and the audit row must say so. * * For the `blocked` branch we deliberately do NOT echo the internal * `reason` token. confirmViaElicitation always sets `reason: "cancelled"` * on blocked results today, but the function is defensive against any * residual `reason: "declined"` shape — either token would falsely imply * a human action when surfaced on a client-capability failure. The fact * that the operation never reached dispatch is captured by * `outcome: "blocked"` on the audit row instead. */ export declare function describeBlockedAudit(result: ElicitationResult): string; /** * Configure the elicitation module. Call once at startup. */ export declare function configureElicitation(opts: { autoApproveRisk?: AutoApproveRisk; }): void; /** * Check whether the connected client advertises form elicitation support. */ export declare function clientSupportsElicitation(server: Server): boolean; /** * Prompt the user to confirm a write operation via MCP form elicitation. * * Decision flow: * 1. If the operation risk is at or below `HARNESS_AUTO_APPROVE_RISK`, proceed * immediately (autonomous mode for CI/CD agents). * 2. If the operation risk is `read` or `low_write`, proceed silently — these * do not require user confirmation regardless of client capability. * `requiresConfirmation(risk)` is the single threshold that decides * whether a prompt is surfaced; it kicks in at `medium_write`. * 3. If the client supports elicitation, prompt the user. The prompt * contains a `confirm` checkbox (default `true`): * - `accept` + `confirm === true` → proceed * - `accept` + `confirm === false` (user unchecked the box) → BLOCK * (authoritative; not bypassable by callerConfirmed) * - `accept` missing the `confirm` field → degenerate non-interactive * response (handled under callerConfirmed below) * - `decline` / `cancel` → BLOCK (authoritative; not bypassable) * 4. If the client lacks elicitation: * - `medium_write` / `high_write` / `destructive` → BLOCK. * 5. `callerConfirmed` (caller passed `confirm: true`) overrides: * - the lacking-elicitation block (managed MCP, Cursor, etc.), * - an `elicitInput` failure (transport or unsupported method), * - an `accept` action missing `confirm=true` (degenerate response from * a non-interactive client that advertises elicitation but does not * actually surface a prompt). * It does NOT override an explicit `decline` or `cancel` from a client * that completed the elicitation handshake — a human (or trusted client) * saying "no" to a write is authoritative, even if the model also passed * `confirm: true` on the call. */ export declare function confirmViaElicitation({ server, toolName, message, risk, autoApproveRisk, callerConfirmed, }: { server: McpServer; toolName: string; message: string; /** The risk level of the operation (from operationPolicy). */ risk: RiskLevel; /** Optional per-session threshold. Falls back to the process default. */ autoApproveRisk?: AutoApproveRisk; /** When true, the caller explicitly passed confirm=true — acts as confirmation * on clients that lack elicitation support (managed MCP, Cursor, etc.) and * on clients that fail to surface a usable prompt. Override paths emit * `method: "caller_confirmed"` (distinct from `elicited`) so audit sinks * can tell automation overrides apart from genuine human consents. */ callerConfirmed?: boolean; }): Promise; //# sourceMappingURL=elicitation.d.ts.map