What it takes off you is the guesswork before the query: read the columns, look at a handful of real rows, then write SQL that matches what is actually stored rather than what the table name suggests. The same connection reaches every database on the server as long as you qualify the name.
Three calls over a MySQL connection: one runs a statement, two describe what is there. Naming a database is optional — leave MYSQL_DATABASE unset and every user database on the server is in reach through database.table notation.
- A SQL statement executed against the server — SELECT, INSERT, UPDATE, DELETE, SHOW, DESCRIBE — one statement per call, with the writing ones marked destructive
- Column metadata for one table or every table: names, types, nullability, defaults and comments
- A sample of rows from a table, up to twenty, so the shape of the data is visible before the query is written
- Cross-database access from the same connection, by naming database.table on any of the three calls
- Two guided prompts your client can launch: explore_database walks the whole database, analyze_table digs into one and suggests queries
- An SSH tunnel to a database that is not directly reachable, set up by the server itself through the MYSQL_SSH_ variables
- TLS on the connection through MYSQL_SSL_MODE — REQUIRED, VERIFY_CA or VERIFY_IDENTITY
- Stdio by default, or MCP_TRANSPORT=sse for a remote or containerised deployment
Uv, and MYSQL_HOST, MYSQL_USER and MYSQL_PASSWORD at minimum; MYSQL_PORT defaults to 3306 and MYSQL_DATABASE is optional. Put those values in the env block of your MCP client's config rather than a .env file — the client launches the server from its own working directory, so a project .env is not found and startup fails on missing configuration. Statements run one at a time, so a fully qualified name takes the place of a USE statement.
One command plus a key — pip install mysql-mcp-server, then supply credentials
