Model Context Protocol server for MySQL databases including AWS RDS
mcp-mysql presents a functional MySQL client with 8 well-named tools following verb_noun conventions (mysql_connect, mysql_query, mysql_list_databases, etc.). All tools have descriptions and input schemas are present and properly structured with JSON Schema. However, there are significant gaps in definition quality: output schemas are NOT documented anywhere, error handling lacks recovery guidance, parameter descriptions are minimal in some cases, and there is no distinction between idempotent read operations and irreversible write operations beyond basic tagging. The server lacks production-grade polish despite having the basic scaffolding. Baseline expectations for a database tool: full schema documentation for both inputs AND outputs, explicit parameter constraints (enums, min/max), clear guidance on when each tool should be used, and actionable error messages with recovery hints.
Connect to a MySQL database with provided connection parameters
Get the structure/schema of a specific table
Disconnect from the MySQL database
Get statistics about a table (row count, size, etc.)
List all databases on the MySQL server
List all tables in the current or specified database
Execute a SQL query on the connected MySQL database
Output schemas are completely undocumented. LLMs cannot predict the structure of results returned by mysql_query, mysql_list_tables, mysql_describe_table, etc. This forces agents to reason blindly about result shapes and downstream field availability, increasing hallucination and wasted round-trips.
mysql_query description is dangerously vague (60 chars: 'Execute a SQL query on the connected MySQL database'). It does not indicate: (a) whether this tool can modify data or only read, (b) what the agent should pass in 'parameters', (c) what structure the result will have, (d) maximum result size. An LLM cannot distinguish between SELECT and DELETE without explicit guidance.
No error handling guidance. The code has try-catch blocks but error messages returned to LLMs are likely raw exception text (see src/index.ts line ~error handling). LLMs receive stack traces or database errors like 'Access denied for user' with no hint about recovery steps, alternatives, or classification (retryable vs fatal vs user-fixable).
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 58 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 45 | - | v1 |
Show indexes for a specific table
mysql_query parameters array (type: string items) lacks explanation. What format are parameters in? Positional (?) or named (:param)? This forces LLMs to guess at parameter binding semantics.
No result size limits documented. mysql_list_tables and mysql_query could return enormous result sets with no pagination or capping. Baseline expectation: tools returning lists must accept limit/offset and state max results in description.
mysql_connect password parameter is exposed as a plain string input. While this is a connection tool, best practice is to accept connection URI strings or environment variable references, not raw passwords in tool calls. Credentials in parameters risk logging and trace leakage.
Risk labels (READ_ONLY, WRITE, IRREVERSIBLE) are metadata annotations, not part of the tool schema visible to LLMs. LLMs do not read these tags, they infer destructiveness from descriptions. mysql_query marked IRREVERSIBLE but description does not warn it can DELETE/DROP. mysql_disconnect marked WRITE but it is idempotent.
No tool annotations in the input schema (readOnlyHint, destructiveHint, idempotentHint). These allow clients to apply UI hints and safety guards. All read tools should be marked readOnlyHint: true, and mysql_disconnect should be marked idempotentHint: true.
Composition gap: mysql_connect and mysql_disconnect manage global state (this.pool). LLMs cannot know if they need to disconnect before connecting to a different database, or if disconnecting will affect other concurrent operations. Stateless tool design is preferred.