MCP database errors need a side-channel contract
Your row-level policy works. The forbidden row never appears. Then the database returns “duplicate key,” “foreign key violation,” or a schema-qualified column name—and the AI learns something it was never allowed to read.
An MCP database server needs an error side-channel contract, not only a result policy.
Errors are outputs
Database errors can reveal whether an identifier exists, which tenant owns a value, table and column names, constraint structure, query text, driver versions, replica state, or timing differences. Treat every error as data crossing the same trust boundary as a successful result.
Separate internal evidence from client messages
Keep the original SQLSTATE, constraint, trace, source, and retry evidence in a restricted audit path. Return a stable client-facing class such as invalid input, conflict, not permitted, temporarily unavailable, or query exceeded policy. Never copy raw driver text into model context by default.
This complements result redaction for AI database agents: successful rows and failed operations both require minimization.
Authorize before distinguishing outcomes
If a caller cannot read a record, do not let create, update, or reference checks confirm it exists. For tenant-local identifiers, prefer tenant-scoped uniqueness such as UNIQUE (tenant_id, slug). Use composite tenant-aware foreign keys where the domain allows it.
Where global uniqueness is necessary, normalize the external response so “owned elsewhere” cannot be enumerated. Add rate limits and anomaly detection for repeated conflicts.
Make retries policy-aware
Transient failures may be retried; authorization, validation, and policy failures should not. Bind retry classification to SQLSTATE plus operation policy, cap attempts, add jitter, and preserve one logical operation identity. A model should not convert a refusal into repeated probes by rephrasing the request.
Return a safe error receipt
Include operation ID, public error class, retryable flag, policy version, normalized scope, completion state, and trace ID. Keep sensitive database diagnostics in restricted logs. The public receipt should prove what happened without becoming a schema-discovery endpoint.
Negative tests
- Probe globally unique values owned by another tenant.
- Reference invisible parent rows.
- Trigger malformed SQL, timeouts, cancellation, and replica failure.
- Compare response body, status, timing, and retry behavior.
- Plant secrets in constraint names and driver messages.
- Verify logs preserve evidence without exposing raw values broadly.
Where Conexor fits
Conexor provides MCP infrastructure for governed database and API tools. Teams can keep identity, scope, query limits, result handling, and error evidence explicit instead of handing raw database exceptions to an AI client.