A provably read-only SQL guard for AI agents - checks what a statement calls, not just its shape. Postgres, MySQL, SQL Server, SQLite.
Two tools with clear, domain-specific names (assert_read_only, is_read_only) and good descriptions (60-80 chars each). Input schemas present with typed parameters and descriptions. However, output schemas are not documented in the visible code, only exception types are mentioned. Error handling via ReadOnlyViolation exception is present but lacks recovery guidance. No tool annotations (readOnlyHint, destructiveHint). The tools are narrow and focused (single responsibility), but descriptions could be more explicit about when to use each variant and what the return value structure is.
Raise ReadOnlyViolation unless sql is a single, side-effect-free read.
Boolean convenience wrapper around assert_read_only.
Output schema not documented. Code shows exception-based error handling but no explicit return type or success response structure documented for LLMs.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Both tools are read-only and idempotent, these should be declared for agent planning.
Error messages lack recovery guidance. ReadOnlyViolation is raised but LLMs are not told what to do next (e.g., 'This SQL contains a write operation. Try a SELECT-only query.').
Descriptions do not explain when to use assert_read_only vs is_read_only. LLMs cannot distinguish between the two without explicit guidance.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 56 | 2026-07-28+ | v2 |
Parameter 'dialect' description lists aliases ('tsql (or mssql/sqlserver)') but does not clarify that None means dialect-agnostic parsing. LLMs may not understand the default behavior.