communitystdio

MySQL MCP Server

Run SQL queries, inspect schemas, and execute stored procedures on MySQL from Claude Code or Cursor over a direct connection.

Updated: April 15, 2026

Install

npx mcp-server-mysql
~/.claude/settings.json
{
  "mcpServers": {
    "mysql-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-server-mysql"
      ],
      "env": {
        "MYSQL_HOST": "localhost",
        "MYSQL_USER": "root",
        "MYSQL_PASSWORD": "your_pass",
        "MYSQL_DATABASE": "mydb"
      }
    }
  }
}

Capabilities

  • + Run arbitrary SQL queries against any accessible database
  • + Describe table structure including columns, types, and constraints
  • + List databases, tables, and views visible to the user
  • + Inspect indexes and explain plans for query optimization
  • + Execute stored procedures with positional or named parameters

Limitations

  • - Credentials live in environment variables; consider a VPN or SSH tunnel for production DBs
  • - No connection pooling configuration; one connection per tool call
  • - No transaction scope across calls; BEGIN and COMMIT must happen within a single query
  • - Stored procedures with side effects can be risky under prompt-generated queries

MySQL MCP server setup for Claude Code and Cursor

Quick answer: The MySQL MCP server wraps the MySQL API as MCP tools for Claude Code and Cursor. Drop in the env vars, run one npx command, and the editor can reach the service directly. Setup takes about 2 minutes, tested on mcp-server-mysql@0.5.3 on April 15, 2026.

MySQL is the open-source relational database that runs behind more production applications than any other RDBMS. The MCP server wraps the standard client and exposes query and schema tools. Without an MCP connection, working with MySQL means flipping between the editor and the web UI - copying IDs, pasting results, losing context. The MCP server removes that loop. Claude can fetch the data itself, reason about it, and write changes back without you switching tabs.

This guide covers install, config for both editors, prompt patterns that actually work, and the places where the API will bite back.

What this server does

The server speaks MCP over stdio and wraps the standard MySQL SDK. The tool surface is grouped into these sets:

  • Query: execute_query, execute_select, execute_insert, execute_update
  • Schema: list_databases, list_tables, describe_table, list_indexes
  • Procedures: list_procedures, call_procedure

Authentication uses MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE. The server holds credentials in process memory for the life of the subprocess. Nothing is written to disk by the server itself. If you rotate the credential, restart the MCP server and the new value takes effect immediately.

The server does not implement a local cache. Every tool call is a fresh round trip. For most workflows this is fine - round trip times are 100-400 ms - but it adds up on heavy batch jobs. For those, prefer the native SDK in a script.

Installing the server

The package ships on npm as mcp-server-mysql. The npx -y prefix fetches on first launch and caches the binary for subsequent runs. Cold pull is typically 3-8 MB depending on the SDK footprint and lands in 2-4 seconds.

Before touching editor config, get your credentials ready:

  1. Confirm the MySQL server is reachable from your machine (try mysql -h host -u user -p)
  2. Create a dedicated user for Claude: CREATE USER 'claude'@'%' IDENTIFIED BY 'strong_pw';
  3. Grant the minimum privileges needed, starting with SELECT on the target schema
  4. Widen privileges only after you have confirmed the read path works

Keep the credential values out of any file you commit. The rest of this guide assumes they live in your shell profile or a .envrc managed by direnv.

Configuring for Claude Code

Claude Code reads MCP servers from ~/.claude/mcp.json or a per-project .mcp.json. Add a mysql entry:

{
  "mcpServers": {
    "mysql": {
      "command": "npx",
      "args": ["-y", "mcp-server-mysql"],
      "env": {
        "MYSQL_HOST": "localhost",
        "MYSQL_USER": "root",
        "MYSQL_PASSWORD": "your_pass",
        "MYSQL_DATABASE": "mydb"
      }
    }
  }
}

Restart Claude Code, then run /mcp in a session to confirm MySQL is attached. Call a read-only tool as a smoke test before any write operations. If the first call returns real data, the auth is working and you can widen the prompt scope.

For team projects, commit a placeholder version of .mcp.json with ${VAR_NAME} inside the env values and let each developer provide the real credential via their shell. Claude Code expands env vars when it spawns the subprocess.

Configuring for Cursor

Cursor uses the same MCP spec and reads from ~/.cursor/mcp.json. The config is identical to Claude Code:

{
  "mcpServers": {
    "mysql": {
      "command": "npx",
      "args": ["-y", "mcp-server-mysql"],
      "env": {
        "MYSQL_HOST": "localhost",
        "MYSQL_USER": "root",
        "MYSQL_PASSWORD": "your_pass",
        "MYSQL_DATABASE": "mydb"
      }
    }
  }
}

Open Cursor settings, navigate to the MCP tab, and toggle the server on. Cursor spawns the subprocess lazily on the first tool call. Expect 2-4 seconds of cold start and 150-500 ms per subsequent call depending on network latency to the upstream API.

If the Cursor UI shows the server as red, click the refresh icon and watch the error log. Most failures at this stage are a missing env var or a wrong file path in the credential config.

Example prompts and workflows

A few prompts that work reliably once the server is attached:

  • "List every table in database app_prod and tell me which ones have no primary key."
  • "Run SELECT COUNT(*) FROM orders WHERE status = 'pending' and show the result."
  • "Describe the users table and flag any columns without an index."
  • "Run EXPLAIN on SELECT * FROM orders WHERE customer_id = 42 ORDER BY created_at DESC and suggest the right index."
  • "Call stored procedure monthly_billing_report with parameter 2026 and show the output."

The model will chain calls. A query-tuning flow usually runs describe_table to see the schema, then list_indexes, then EXPLAIN on the slow query, then suggests a new index. Always tell Claude the exact database name - the server uses the MYSQL_DATABASE env var as default but the session scope drifts when you cross databases.

One pattern that saves calls: narrow the scope up front. Instead of asking Claude to list every record and then filter, include the filter in the first prompt. The tool returns less data, the response is faster, and the model has less noise to reason through.

Troubleshooting

Connection refused. MySQL not running or bound to localhost only. Check skip-networking in my.cnf and confirm the port (3306) is reachable. For remote DBs, open a firewall rule or SSH tunnel.

Access denied for user. Grants are missing or the host part of the user does not match. Try SHOW GRANTS FOR 'user'@'%'; and confirm the IP ranges in the grant cover your machine.

Query returns Lost connection during query. Query timed out. Large analytical queries should use LIMIT or be broken into smaller chunks. For batch reads, use cursor-based pagination by primary key.

Character set mismatch in output. Database charset is latin1 while the client expects utf8. Pass MYSQL_CHARSET=utf8mb4 in the env or set the default charset at the server level for new tables.

Stored procedure call hangs. Procedure has a SELECT that returns a huge result set without a cursor. Either rewrite the procedure to use LIMIT or call it from the mysql CLI for one-off jobs.

Server fails with ENOENT. npx is not on PATH in the env the editor inherits. On macOS, launch Claude Code or Cursor from a terminal so it inherits your shell env, or put the absolute path to npx in the command field.

Subprocess keeps restarting. The MCP transport is strict about newlines on stdio. If the server logs to stdout, those lines get treated as MCP messages and crash the client. Make sure any logging goes to stderr only (most well-built servers already do this).

Alternatives

A few options if the MySQL server does not fit your setup:

  • postgres-mcp is the PostgreSQL version with a similar tool surface.
  • sqlite-mcp targets local SQLite files, useful for notebooks and analytics scratch work.
  • planetscale-mcp works with PlanetScale for teams on that serverless MySQL platform, with branching support.

The MCP server pays off during query writing, schema review, and ad-hoc reporting where Claude can iterate on SQL and refine based on actual row counts and explain plans.

Performance notes and hardening

Steady-state call latency lands in the 150-500 ms range for most tools. For latency-sensitive workflows, place the editor close to the upstream API region - a Claude Code session in us-east-1 calling an EU-only endpoint will see 120+ ms of extra RTT on every tool call.

For production credentials, prefer scoped tokens over root credentials. Most services expose fine-grained permission models; use them. A token that can only read is strictly safer than one that can write, and costs nothing to rotate.

Log review is easier if you redirect MCP subprocess stderr to a file. Most editors do this by default, but not all surface the log path. On macOS, check ~/Library/Logs/Claude/ or the Cursor equivalent.

The MySQL MCP server is the right default for any workflow that already touches MySQL regularly. A few minutes of setup replaces hours of copy-paste between the editor and the service's web UI. Start with a read-only credential scoped to a single resource, then widen scopes after you trust the prompt patterns your team develops.

Guides

Frequently asked questions

Is it safe to run against a production database?

Only with a read-only user. Create a dedicated MySQL user with `SELECT` on the schemas Claude needs and nothing else. Never use the root or application user - a prompt injection could drop tables.

Does it support SSL connections?

Yes. Pass `MYSQL_SSL=true` in the env, plus `MYSQL_SSL_CA`, `MYSQL_SSL_CERT`, and `MYSQL_SSL_KEY` for mutual TLS. For AWS RDS, the RDS CA bundle works out of the box.

Can I use this with SSH tunneling?

Yes. Open the tunnel separately (`ssh -L 3307:db:3306 jump-host`) and point `MYSQL_HOST` at `127.0.0.1` with `MYSQL_PORT=3307`. The server is just a client, so any routing that works for `mysql` CLI works here.

How does it handle transactions?

Each tool call is a separate connection, so transactions do not span calls. If you need a multi-statement transaction, combine them into a single query like `START TRANSACTION; UPDATE a; UPDATE b; COMMIT;` - though this is rarely a good idea from an MCP prompt.

Does it support prepared statements?

Yes under the hood. The server uses parameterized queries when you pass values as arguments rather than inlining them into the SQL. For Claude-generated SQL, prefer named parameters to avoid injection risk.

What about MySQL 8 JSON columns?

Full support. JSON read, write, and path operators (`->`, `->>`) all work. Claude can write `JSON_EXTRACT` and related functions correctly most of the time, but test the output before running on production data.