MCP server providing database schema exploration and SQL query execution tools with LLM integration for no-code database interactions
The server exposes 3 database tools via FastMCP with basic descriptions and input schemas. However, there are significant gaps in LLM-ready quality: parameter descriptions are minimal and generic, output schemas are undocumented, error handling is primitive (raw exceptions converted to strings), and critical security concerns exist around SQL injection and permission validation. The tool naming is appropriate (verb_noun pattern: list_, get_, execute_) but descriptions lack the depth needed to guide LLM selection and usage. No tool annotations (readOnlyHint/destructiveHint/idempotentHint) despite execute_query being destructive. Output documentation is absent, LLMs must infer structure from tool names alone.
Execute a raw SQL query against the database.
Get the full schema (tables and columns) for the specified database.
List all tables in the specified database.
execute_query lacks destructiveHint annotation and safety guidance. Description does not warn that raw SQL can modify/delete data, nor does it explain when to use this vs safer discovery tools (list_tables, get_schema). LLMs may invoke destructive queries without understanding consequences.
No SQL injection defense visible in tool definition or DbManager integration (DbManager.execute_query implementation not provided). Parameter 'query' accepts raw user SQL with no sanitization hint or warning. Against pattern:tool-gateway.
Output schemas are completely undocumented. list_tables returns List[str] (table names only), get_schema returns List[Dict[str, Any]] (structure unknown to LLM), execute_query returns str (could be JSON, CSV, error message, ambiguous). LLMs cannot plan downstream tool calls or extract structure reliably.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 63 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 42 | - | v1 |
Parameter descriptions are trivial (e.g., 'The ID of the database to query' for db_id in all 3 tools). No guidance on valid db_id values, format, enumeration, or discovery method. LLMs have no way to know what strings to pass, forces trial-and-error or extra discovery calls.
Error handling returns raw exception strings (e.g., 'Error: {str(e)}', 'Error executing query: {str(e)}'). No recovery guidance, no error classification (retryable vs user-fixable vs fatal), no invalid-value context. LLMs cannot self-correct or know what action to take next.
execute_query accepts a free-form SQL string with no format validation, length limits, or query-type constraints in the schema. LLMs could pass malformed SQL, extremely long queries, or ddl/admin commands. No documented timeout or result-size cap.
No permission or scope declaration visible in tool definitions. No documentation of what database permissions or user roles are required to call these tools. Against pattern:scope-declaration for least-privilege agent config.
get_schema returns full table structure including all columns for all tables, with no pagination or result-size limit. For large schemas, response could exhaust context window. Against pattern:paginated-result.
db_id parameter is opaque (e.g., 'postgres', 'mysql'). No enum, no way for LLM to discover valid database IDs, and no natural-language alternative (e.g., 'database_name'). LLM must guess or call a discovery tool first.