MCP server for MySQL database interaction and business intelligence
This MySQL MCP server has significant definition quality gaps. While tool names follow verb-noun convention and input schemas are present, descriptions are minimal and lack the context needed for LLM selection. Parameter descriptions are trivial or absent. Output schemas are not documented. The server stores business insights in memory without persistence, mixing database operations with application state. No error recovery guidance. Tool definitions are visible in src/index.ts but descriptions lack depth and parameter documentation is sparse.
Add a business insight or analysis note to the server
Get detailed information about a specific table structure
List all stored business insights
List all tables in the connected database
Execute a SELECT query and retrieve results
Execute a write operation (INSERT, UPDATE, DELETE) on the database
Descriptions are minimal (under 50 chars for most tools). 'List all tables in the connected database' and 'Execute a SELECT query and retrieve results' lack context about when to use each tool, what data is returned, or prerequisites. LLMs cannot reliably select between tools or understand limitations.
Parameter descriptions are trivial or missing entirely. 'query' parameter in read_query and write_query lacks format guidance (e.g., 'SELECT queries only', 'must be valid SQL', 'no DDL'). 'table_name' in describe_table lacks examples or disambiguation (is it case-sensitive? does it support schema.table notation?). LLMs cannot infer valid inputs.
Output schemas are not documented anywhere in the code. Callers cannot know what fields list_tables returns, what structure describe_table produces, or what read_query result format is. LLMs must guess at response structure.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 45 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 0 | - | v1 |
No input validation or error recovery guidance. If an LLM passes a malformed SQL query, there is no actionable error message (e.g., 'Syntax error in query near line X. Did you mean...?'). A raw MySQL error or code is useless for agent self-correction.
add_insight and list_insights mix application state with database tools. Insights are stored in-memory in the MySQLServer class (private insights: Insight[] = []), not in the database. This breaks persistence across restarts and violates the single-responsibility principle. If insights should exist, they belong in a dedicated table with full ACID guarantees.
No pagination support. list_tables and list_insights will return unbounded results. If a database has hundreds of tables or insights, the LLM context window is exhausted. No mention of limits, total counts, or cursor-based pagination.
SQL injection risk. write_query and read_query accept raw SQL strings with no parameterization guidance. The descriptions do not mention using prepared statements. An LLM could be tricked into passing 'DROP TABLE users; --' as a query.
No distinction between read and write safety. write_query lacks a dry-run or confirmation mechanism. An LLM could accidentally issue 'DELETE FROM users;' without any safety check or recovery path.
describe_table does not document what columns are returned (name, type, nullable, default, key, extra?). LLMs cannot plan subsequent write_query calls without knowing the schema structure.
Tool names do not disambiguate between database operations. 'write_query' covers INSERT, UPDATE, and DELETE, semantically very different operations. Splitting into create_record, update_record, delete_record would clarify intent and allow per-operation error handling.