MCP Server for MySQL

Run SQL against a MySQL database from an AI client, read-only unless writes are switched on

By Ben Borla (individual) TypeScript Local · stdio Databases

84 popularity score ★ 2.2k ↓ 22k/wk

Connect your client

Local (npm)

Add in one click

Opens the app, which asks before it adds the server.

Or add it by command or config

Claude CodeTerminal
claude mcp add for-mysql -- npx -y @benborla29/mcp-server-mysql
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "for-mysql": {
      "command": "npx",
      "args": [
        "-y",
        "@benborla29/mcp-server-mysql"
      ]
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "for-mysql": {
      "command": "npx",
      "args": [
        "-y",
        "@benborla29/mcp-server-mysql"
      ]
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "for-mysql": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@benborla29/mcp-server-mysql"
      ]
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.for-mysql]
command = "npx"
args = ["-y", "@benborla29/mcp-server-mysql"]
Gemini CLITerminal
gemini mcp add --scope user for-mysql npx -- -y @benborla29/mcp-server-mysql
Local (from source)

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

FirstTerminal
git clone https://github.com/benborla/mcp-server-mysql.git
cd mcp-server-mysql
pnpm install
pnpm run build
Claude CodeTerminal
claude mcp add for-mysql -- node '<PATH_TO_REPO>/dist/index.js'
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "for-mysql": {
      "command": "node",
      "args": [
        "<PATH_TO_REPO>/dist/index.js"
      ]
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "for-mysql": {
      "command": "node",
      "args": [
        "<PATH_TO_REPO>/dist/index.js"
      ]
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "for-mysql": {
      "type": "stdio",
      "command": "node",
      "args": [
        "<PATH_TO_REPO>/dist/index.js"
      ]
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.for-mysql]
command = "node"
args = ["<PATH_TO_REPO>/dist/index.js"]
Gemini CLITerminal
gemini mcp add --scope user for-mysql node -- '<PATH_TO_REPO>/dist/index.js'

Settings 12

MYSQL_HOST Optional: MySQL host, default 127.0.0.1.
MYSQL_PORT Optional: MySQL port, default 3306.
MYSQL_USER Optional: MySQL user name, default root.
MYSQL_PASS Optional: Password for the MySQL user.
MYSQL_DB Optional: Database to use; leave empty to work across all databases.
MYSQL_SOCKET_PATH Optional: Unix socket to connect through instead of host and port.
MYSQL_CONNECTION_STRING Optional: MySQL CLI-style connection string that overrides the separate settings.
ALLOW_INSERT_OPERATION Optional: Set true to allow INSERT statements.
ALLOW_UPDATE_OPERATION Optional: Set true to allow UPDATE statements.
ALLOW_DELETE_OPERATION Optional: Set true to allow DELETE statements.
ALLOW_DDL_OPERATION Optional: Set true to allow CREATE, ALTER and DROP.
ENABLE_PII_REDACTION Optional: Set true to mask likely personal data in read results.

What it does

This Node.js server connects an MCP client to a MySQL database. It offers one tool, mysql_query, which takes a SQL statement and returns the result. It also offers a resource that lists the tables and their columns, so the assistant can see the schema before it writes a query.

By default it only reads: queries run in read-only transactions. INSERT, UPDATE, DELETE and DDL (CREATE, ALTER, DROP) each have their own switch, and the schema permission settings can allow writes on one database while blocking them on another. If MYSQL_DB is left empty, the server works across every database the MySQL user can see, and writes stay off unless they are enabled for each schema.

It can connect over TCP, a Unix socket, a MySQL CLI-style connection string, or SSL/TLS with optional client certificates. The docs also describe reaching a remote database through an SSH tunnel. Other settings cover a connection pool, query timeouts, a result cache, a per-minute query rate limit and a cap on query complexity. An optional PII mode masks values that look like personal data (emails, phone numbers, card numbers) in read results. It runs over stdio by default, and it can also run as an HTTP server that checks a bearer token.

What it needs

RuntimeNode.js 20+

Node.js 20 or newer and a MySQL server, version 5.7 or newer (8.0 is recommended), that the machine running the server can reach. You also need a MySQL user with the privileges you want the assistant to have. Remote HTTP mode needs a secret of your choosing for the bearer token.

Limits

There is only one tool, a raw SQL runner: no separate tools for listing, describing or migrating. Writes are off by default and need a separate switch for each kind of statement. In multi-database mode you have to qualify table names or switch databases with USE. The docs list gaps in PII masking: numbers stored in numeric columns, non-US phone and ID formats, IBANs, nested JSON fields, binary data, column aliases and write summaries are not masked. When masking is on, SHOW CREATE TABLE and information_schema queries are refused. Queries are rate-limited (100 per minute by default) and time out after 30 seconds by default.

Who it suits

It suits developers who want an assistant to look at a MySQL schema and query it on their own machine, with writes kept off or allowed only for some schemas, for example on a development database but not production. Because it passes any SQL to the database, the MySQL user's grants are the real limit, so give it a narrow user. It is a community project, not one from Oracle. Teams that want structured tools rather than free-form SQL, or that need hosted access without running Node, should look at other database servers.

Tools 1

mysql_query
Runs one SQL statement on the connected MySQL server and returns the rows; writes only when enabled

Similar servers