Operators who ship production-capable database MCP servers keep rediscovering the same shape. They add a confirmation step for mutating SQL. It works in their CLI or GUI. Then they notice the hard limit: other clients do not inherit that prompt. Tool annotations help discovery, and they can be ignored. Spec elicitation is the cleaner portable UX — and in mid-2026 it is still unevenly adopted.
Three layers people already build
- Hard mode / role — the connection cannot write at all.
- Local consent — this client asked the human, then set
user_consent=trueor answered elicitation. - Portable receipt — a short-lived, single-use credential bound to the exact SQL (and usually the target), checked before execute by any host.
Layers 1 and 2 belong inside the write tool. Layer 3 is what travels when the client changes, when CI re-runs the statement, or when a later retry tries to swap SQL after the human said yes.
Batch writes make the gap louder
Multi-statement migrations amplify the UX problem: one prompt per statement is noisy; one batch approval without a bound receipt is loose. The useful compromise is one human approval moment, then a receipt whose hash covers the normalized batch you will actually run. Change the batch, mint again.
What we sell into that gap
SQLGuard issues the statement-bound Authorization Receipt and verifies it at the write
boundary (POST /v1/gate is free and portable). MCP elicitation or a local
[y/N] can still collect the human yes — that yes becomes an input to the receipt,
not a substitute for it.
Drop-in sketch for servers that already have mode → consent gates:
examples/db-conn-mcp-receipt-hook
(default-off). Cursor bundle:
plugins/sqlguard-authorize.
If this is your write path
Run the Pilot Challenge ($100 Exact unlock) against one production-shaped statement, or review Gateway ($299/mo) for a standing control. Compare notes in Discord.