MCP server for YugabyteDB/PostgreSQL — read and write tools, optional OAuth
YugabyteDB MCP server demonstrates solid foundational quality with three well-named, action-oriented tools (summarize_database, run_read_only_query, run_write_query). All tools have clear descriptions (100-200 chars range, within baseline 194 char average) and properly typed input schemas with parameter descriptions. However, there are significant gaps in output schema documentation, error handling guidance, and parameter constraint enforcement that prevent this from reaching 70+. The server lacks documented output schemas (HARD requirement per pattern:tool), and error responses are not shown to include recovery guidance. Parameter descriptions exist but lack explicit format constraints, ranges, and enum values that would enable robust LLM reasoning. The write tool notably lacks a dry-run/confirmation pattern despite operating on destructive operations. Security controls (OIDC auth, guardrails, role-based execution) are well-designed but not reflected in tool annotations or error responses.
Execute a read-only SQL query against the database. The query runs in a READ ONLY transaction and cannot modify data.
Execute a write SQL query (INSERT, UPDATE, DELETE) against the database. Subject to guardrails: blocklists on dangerous keywords/functions, optional WHERE enforcement.
Get a summary of all tables and their schemas in the connected database.
Output schemas not documented. No visible description of what summarize_database, run_read_only_query, or run_write_query return. LLMs cannot plan downstream actions without knowing response structure (e.g., does summarize_database return {tables: [...]} or {schema: {tables: [...]}}?). Per pattern:tool and mxe:response-field-naming, every tool must document its output schema.
Error handling does not include recovery guidance. Source code shows validation and guardrails (QueryBlockedError, IdentityError), but no evidence that error responses tell LLMs what to do next (pattern:recovery-guide). E.g., if a query is blocked, does the error message suggest using a safer query or calling summarize_database first?
run_write_query lacks dry-run or confirmation pattern. Destructive operations (INSERT, UPDATE, DELETE) should support confirmation before execution per pattern:confirmation-request, but no evidence of this in tool definition. Agents can make mistakes, a confirm_before_execute step prevents catastrophic errors.
Inferred effective spec: 2026-07-28+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 69 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 43 | - | v1 |
Parameter descriptions lack explicit format constraints and enum values. 'query' parameters say 'SQL SELECT query' or 'SQL write query' but do not specify: forbidden keywords (from guardrails.QueryBlockedError), format constraints, or how to reference tables/columns. LLMs cannot validate against implicit guardrails, constraints must be explicit in descriptions.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). run_read_only_query and run_write_query have obvious security/destructiveness implications, but no tool annotations in the visible schema to signal this to clients. Per current spec alignment (2026-07-28), tool annotations should be present.
requested_role parameter lacks validation and error handling. Description says 'requires OIDC auth' but does not specify: what happens if role is not found, what roles are available, or how to discover valid roles. Per mxe:natural-identifiers, tool should enrich errors with available alternatives (e.g., 'Role not found. Available roles: admin, readonly, analyst').
No pagination or result limits documented. summarize_database may return all tables and schemas without documented limits. Per pattern:paginated-result and mxe:enforce-result-limits, large result sets should be capped and paginated to avoid context window exhaustion. Is there a limit? How does an agent fetch partial results?