MySQL MCP Server

Connects an MCP client to a MySQL database to browse schemas, sample tables and run SQL

By Dana K. Williams (individual) Python Local · stdio Databases

74 popularity score ★ 1.4k ↓ 30k/mo

Connect your client

Local (PyPI)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

It needs MYSQL_USER, MYSQL_PASSWORD. Replace each <NAME> with your value.

Claude CodeTerminal
claude mcp add mysql -e MYSQL_USER=<MYSQL_USER> -e MYSQL_PASSWORD=<MYSQL_PASSWORD> -- uvx --from mysql-mcp-server mysql_mcp_server
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "mysql": {
      "command": "uvx",
      "args": [
        "--from",
        "mysql-mcp-server",
        "mysql_mcp_server"
      ],
      "env": {
        "MYSQL_USER": "<MYSQL_USER>",
        "MYSQL_PASSWORD": "<MYSQL_PASSWORD>"
      }
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "mysql": {
      "command": "uvx",
      "args": [
        "--from",
        "mysql-mcp-server",
        "mysql_mcp_server"
      ],
      "env": {
        "MYSQL_USER": "<MYSQL_USER>",
        "MYSQL_PASSWORD": "<MYSQL_PASSWORD>"
      }
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "mysql": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "--from",
        "mysql-mcp-server",
        "mysql_mcp_server"
      ],
      "env": {
        "MYSQL_USER": "<MYSQL_USER>",
        "MYSQL_PASSWORD": "<MYSQL_PASSWORD>"
      }
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.mysql]
command = "uvx"
args = ["--from", "mysql-mcp-server", "mysql_mcp_server"]

[mcp_servers.mysql.env]
MYSQL_USER = "<MYSQL_USER>"
MYSQL_PASSWORD = "<MYSQL_PASSWORD>"
Gemini CLITerminal
gemini mcp add --scope user -e MYSQL_USER=<MYSQL_USER> -e MYSQL_PASSWORD=<MYSQL_PASSWORD> mysql uvx -- --from mysql-mcp-server mysql_mcp_server

Settings 12

MYSQL_USER Required: MySQL user name; the server refuses to connect without it.
MYSQL_PASSWORD secret Required: Password for that user; must be set, may be an empty string.
MYSQL_HOST Optional: Database host. Default localhost.
MYSQL_PORT Optional: Database port. Default 3306.
MYSQL_DATABASE Optional: Database to work in; leave unset for multi-database mode.
MYSQL_CONNECT_TIMEOUT Optional: Connection timeout in seconds. Default 10.
MCP_TRANSPORT Optional: stdio, or sse for an HTTP server. Default stdio.
MYSQL_SQL_MODE Optional: SQL mode for the connection. Default TRADITIONAL.
Set together: ssl
MYSQL_SSL_MODE Optional: DISABLED, REQUIRED, VERIFY_CA or VERIFY_IDENTITY.
MYSQL_SSL_CA Optional: CA certificate path used with VERIFY_CA or VERIFY_IDENTITY.
Set together: sse
MCP_SSE_HOST Optional: Address the SSE server listens on. Default 0.0.0.0. For SSE mode.
Set together: ssh
MYSQL_SSH_ENABLE Optional: Set to true to connect through an SSH tunnel set up with MYSQL_SSH_HOST, MYSQL_SSH_USER and MYSQL_SSH_KEY_PATH. Default false.

What it does

MySQL MCP Server is a Python server that sits between an MCP client and a MySQL database you point it at with environment variables. It has three tools. One runs a single SQL statement and hands back the rows as comma-separated text, one describes the columns of a table or of the whole configured database, and one pulls a few sample rows. Tables are also served as MCP resources, and two prompts, explore_database and analyze_table, walk the client through a survey of the schema or of one table.

With MYSQL_DATABASE set it works inside that database. Leave it out and it lists every non-system database instead, and you write database.table names. It can reach a remote server through an SSH tunnel (the MYSQL_SSH_* settings) and supports SSL modes from DISABLED to VERIFY_IDENTITY. It speaks stdio by default, and MCP_TRANSPORT=sse starts an HTTP server.

The code of version 0.4.5 (server.py) is looser than the README suggests. execute_sql has no statement filter: the README names SELECT, SHOW, DESCRIBE and INSERT/UPDATE/DELETE, but DROP, ALTER or GRANT go through just the same, on a connection with autocommit on. What it can change depends only on the grants of the MySQL user you give it. The single-statement rule is a plain check for a semicolon anywhere but the end of the query, so a semicolon inside a string literal gets the query refused too. The code also reads MYSQL_SSL_CA for the VERIFY_CA and VERIFY_IDENTITY modes, a setting the README never lists.

What it needs

RuntimePython
Runs onmacOS, Windows, Linux
MySQLYour own instanceA reachable MySQL server and a MySQL user for the server to sign in as
Also
  • uv, for the uvx launch command

Install uv for the uvx command, or use pip install mysql-mcp-server. MYSQL_USER and MYSQL_PASSWORD go in the client's env block (the password may be an empty string). SSE mode needs the extra packages from pip install mysql-mcp-server[sse]. SSH tunnelling needs a jump host and a private key file.

Limits

  • Not covered One statement per call: a semicolon anywhere but the end is refused, even inside a quoted string, so USE db; SELECT ... fails
  • Size cap get_table_sample returns 5 rows by default and at most 20; reading a table resource returns its first 100 rows
  • Size cap execute_sql has no row cap and fetches the whole result set
  • Not covered Table names for the schema and sample tools may hold only letters, digits, the _ and $ signs, and one dot
  • Not covered get_schema_info without a table name covers only the database in MYSQL_DATABASE, so it returns nothing in multi-database mode
  • Limit A .env file is found only when the server starts in the project folder. Claude Desktop and Claude Code start it elsewhere, so put settings in the client config
  • Limit SSE mode has no authentication of its own and listens on 0.0.0.0 unless MCP_SSE_HOST is set

Single statements only: multi-statement input such as USE db; SELECT ... is not supported. get_table_sample returns 5 rows by default and at most 20; reading a table resource returns its first 100 rows; execute_sql has no row cap and fetches the whole result. Table names passed to the schema and sample tools may contain only letters, digits, underscores, $ and one dot. A .env file is only found when the server runs from the project folder: Claude Desktop and Claude Code start it elsewhere, so settings must go in the client config. SSE mode has no authentication of its own and listens on 0.0.0.0 by default.

Who it suits

Suits developers who want an assistant to explore and query a MySQL database they control, locally or over SSH, and who can create a dedicated MySQL user with only the privileges they want it to have. Since execute_sql passes any statement through, anyone who wants the server itself to refuse writes should look at read-only-local-mysql-mcp-server, which we also list: it accepts only SELECT, WITH, SHOW, DESCRIBE and EXPLAIN and runs them in a read-only transaction. With this one, read-only access has to come from the MySQL user's grants.

Tools 3

2 only read, 1 can delete or overwrite. A ? marks an optional parameter.

execute_sql deletes
Runs one SQL statement of any kind and returns rows as CSV-style text or the affected row countquery: string
get_schema_info
Lists column names, types, nullability, defaults and comments for one table, or columns of every table in the configured databasetable_name?: string
get_table_sample
Returns sample rows from a tabletable_name: stringlimit?: integer

Resources 2

mysql://{table}/data
First 100 rows of a table, served when MYSQL_DATABASE is set
mysql://database/{database}
Tables in a database, served in multi-database mode

Prompts 2

explore_database
Guides the client through listing tables, reading their schemas, sampling a few and summarising them
analyze_table
Guides the client through one table's schema and sample rows and asks for example queries; takes table_name

Similar servers