easy-mysql-mcp
easy-mysql-mcp is a MySQL database interface server providing an MCP interface for AI assistants to inspect, query, and modify a MySQL database through the following tools:
mysql_query: Execute read-only SELECT statements for data retrieval.mysql_execute: Execute data modification statements (INSERT, UPDATE, DELETE) with optional parameterized inputs.explain_query: Run EXPLAIN on a SQL query to analyze its execution plan.list_tables: List all base tables with approximate row counts and comments.list_views: List all views in the current database.describe_table: Show column schema/structure for one or more tables.describe_index: Show indexes defined on a specific table.list_triggers: List all triggers in the current database.get_current_privileges: Check the current MySQL user's permissions and grants.
Database connection is configurable via environment variables.
Allows AI assistants to inspect and query a MySQL database through a safe, structured tool interface, including schema discovery, query execution, and privilege inspection.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@easy-mysql-mcpdescribe the users table"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
easy-mysql-mcp
A lightweight Model Context Protocol (MCP) server that lets AI assistants inspect and query a MySQL database through a safe, structured tool interface.
This project uses Node.js, TypeScript, the official MCP SDK, and mysql2/promise. It runs over stdio, so it can be used directly by MCP clients such as Claude Desktop.
Features
MySQL connection pooling powered by
mysql2/promiseRead-only query tool for data retrieval
Execute tool for data modification statements
Batch execution and CSV import/export helpers
Schema discovery tools for tables, views, indexes, and triggers
Query plan inspection with
EXPLAINCurrent user and privilege inspection
Requirements
Node.js 18 or newer
npm
A reachable MySQL-compatible database
Installation
Run the server directly with npx:
npx -y easy-mysql-mcpFor local development after cloning the repository:
cd easy-mysql-mcp
npm install
npm run buildConfiguration
Configure the server with environment variables. You can provide them through your MCP client configuration or by creating a local .env file.
Variable | Required | Default | Description |
| Yes | - | MySQL host name or IP address |
| No |
| MySQL port |
| Yes | - | MySQL user name |
| Yes | - | MySQL password |
| Yes | - | Default database/schema |
| No |
| Maximum number of active pool connections |
| No |
| Maximum number of idle pool connections |
| No |
| Idle connection timeout in milliseconds |
| No |
| Maximum queued connection requests, where |
| No |
| Whether the pool waits when all connections are busy |
| No |
| Whether TCP keep-alive is enabled |
| No |
| Initial TCP keep-alive delay in milliseconds |
| No |
| When |
| No |
| MCP policy mode. Use |
| No | - | Comma-separated table allowlist, such as |
| No | - | Comma-separated table denylist, such as |
| No |
| Maximum number of parameter sets per internal batch for |
| No | - | HTTP POST URL for external accept/reject/approval policy decisions |
| No |
| Number of seconds a pending approval remains valid |
Example .env:
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=root
MYSQL_PASSWORD=your_password
MYSQL_DATABASE=your_databaseUsage
Configure your MCP client to launch the package through npx.
For local development, build the TypeScript source first:
npm run buildStart the MCP server:
npm startThe server communicates over stdio and is normally launched by an MCP client rather than run manually.
Claude Desktop Example
{
"mcpServers": {
"easy-mysql-mcp": {
"command": "npx",
"args": ["-y", "easy-mysql-mcp"],
"env": {
"MYSQL_HOST": "localhost",
"MYSQL_PORT": "3306",
"MYSQL_USER": "YOUR USERNAME",
"MYSQL_PASSWORD": "YOUR PASSWORD",
"MYSQL_DATABASE": "YOUR DB NAME"
}
}
}
}Restart Claude Desktop after updating the configuration.
Codex config.toml Example
[mcp_servers.easy-mysql-mcp]
args = ["-y", "easy-mysql-mcp"]
command = "npx"
enabled = true
[mcp_servers.easy-mysql-mcp.env]
MYSQL_HOST = "localhost"
MYSQL_PORT = "3306"
MYSQL_USER = "YOUR USERNAME"
MYSQL_PASSWORD = "YOUR PASSWORD"
MYSQL_DATABASE = "YOUR DB NAME"OpenCode opencode.jsonc Example
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"easy-mysql-mcp": {
"type": "local",
"command": ["npx", "-y", "easy-mysql-mcp"],
"enabled": true,
"environment": {
"MYSQL_HOST": "localhost",
"MYSQL_PORT": "3306",
"MYSQL_USER": "YOUR USERNAME",
"MYSQL_PASSWORD": "YOUR PASSWORD",
"MYSQL_DATABASE": "YOUR DB NAME",
},
},
},
}Available Tools
Tool | Description |
| Execute a SQL query intended for data retrieval, such as |
| Execute a data modification statement, such as |
| Execute one data modification statement repeatedly with multiple parameter sets |
| Import a UTF-8 CSV file into a table using the header row as column names |
| Export all rows from a table to a UTF-8 CSV file |
| Run |
| List base tables in the current database, including approximate row counts and comments |
| List views in the current database |
| Show column information for one or more tables |
| Show indexes for a table |
| List triggers in the current database |
| Show the current MySQL user and grants |
| Run a pending command after approval, only registered when |
| List pending approval requests, only registered when |
| Cancel a pending approval request, only registered when |
When MYSQL_READ_ONLY=true or MYSQL_MCP_MODE=readonly, the mysql_execute, mysql_batch_execute, and mysql_import_csv tools are not registered.
Batch Execute
mysql_batch_execute runs the same parameterized write statement with multiple parameter arrays. It is useful for bulk inserts or repeated updates without enabling multi-statement SQL.
Example input:
{
"sql": "INSERT INTO users (name, email) VALUES (?, ?)",
"paramsList": [
["Alice", "alice@example.com"],
["Bob", "bob@example.com"]
],
"transaction": "all"
}The transaction option controls transaction scope:
Value | Behavior |
| Default. Wrap all rows in one transaction |
| Wrap each internal batch in its own transaction |
| Wrap each parameter set in its own transaction |
| Do not start explicit transactions |
everyone is accepted as an alias for each, but each is the preferred name.
The server splits paramsList into internal batches using MYSQL_BATCH_MAX_SIZE. For example, with the default size of 100, 250 parameter sets run as 100, 100, and 50.
Detailed per-row execution results are written to a timestamped .log file under logs/. The tool response only returns summary counts and the log file path. Log files older than seven days are cleaned up automatically when the server starts.
CSV Import and Export
mysql_import_csv reads a UTF-8 CSV file and inserts rows into a table. The first CSV row must contain column names, and every data row must have the same number of columns. Internally, the tool builds a parameterized INSERT statement and executes it through the same batch execution path as mysql_batch_execute.
Example import input:
{
"tableName": "users",
"filePath": "./data/users.csv",
"transaction": "all"
}mysql_export_csv exports all rows from a table to a UTF-8 CSV file. It writes a header row using the table's column names, even when the table has no rows.
Example export input:
{
"tableName": "users",
"filePath": "./exports/users.csv"
}CSV import/export uses standard comma-separated CSV with double-quote escaping. Empty CSV fields are imported as empty strings.
SQL Policy
The server applies a lightweight SQL policy before executing user-provided SQL:
mysql_queryallows only single-statementSELECT,SHOW,DESCRIBE, andEXPLAINqueries.explain_queryaccepts only a singleSELECTstatement and runsEXPLAINfor it.mysql_executeallows only single-statementINSERT,UPDATE,DELETE, andREPLACEstatements when write mode is enabled.mysql_batch_executeuses the same SQL policy asmysql_executeand applies the statement repeatedly with parameter arrays.mysql_import_csvuses table policy and the same batch execution path asmysql_batch_execute.mysql_export_csvuses table policy before exporting table data.Multi-statement SQL is rejected.
SELECT ... INTOand locking reads are rejected for read-query tools.MYSQL_MCP_DENY_TABLESrejects matching tables beforeMYSQL_MCP_ALLOW_TABLESis evaluated.If
MYSQL_MCP_ALLOW_TABLESis set, every detected table must be included in the allowlist.
Table policy matching is best-effort and based on SQL parsing. You can use either table or database.table entries. MySQL grants remain the final security boundary.
Policy Order
Policy checks run in this order:
Built-in SQL safety checks run first, such as single-statement enforcement and allowed statement types for each tool.
MYSQL_MCP_DENY_TABLESis checked next. If a detected table matches the denylist, the command is rejected immediately.MYSQL_MCP_ALLOW_TABLESis checked after the denylist. If an allowlist is configured, every detected table must be included in it.MYSQL_POLICY_HOOKruns only after the built-in SQL policy and table allow/deny policy pass.
If both MYSQL_MCP_ALLOW_TABLES and MYSQL_MCP_DENY_TABLES are configured, the denylist takes precedence. For example:
MYSQL_MCP_ALLOW_TABLES=users,orders,payments
MYSQL_MCP_DENY_TABLES=paymentsIn this configuration, users and orders are allowed, payments is rejected, and all other tables are rejected because they are not in the allowlist.
MYSQL_POLICY_HOOK cannot override built-in rejections. It can only decide what happens after a command has already passed local policy: accept, reject, or approval_required.
Policy Hook and Approvals
When MYSQL_POLICY_HOOK is configured, the server posts each tool action to the hook after built-in policy checks pass and before the command runs.
Example hook request:
{
"functionName": "mysql_execute",
"sql": "UPDATE users SET email = ? WHERE id = ?",
"statementType": "update",
"tableNames": ["users"],
"paramsPreview": ["new@example.com", 123],
"metadata": {
"database": "app_db",
"mode": "readwrite",
"timestamp": "2026-05-20T12:00:00.000Z"
}
}The hook must return one of:
{ "status": "accept" }{ "status": "reject", "message": "Writes are blocked outside maintenance windows." }{
"status": "approval_required",
"message": "User approval is required before updating users."
}For approval_required, the server does not execute the command. It stores the original pending command in memory and returns an approval_required response with a server-generated approvalId. The hook does not provide the approval id. After the MCP host obtains user approval, it can call:
{
"approvalId": "apv_..."
}with mysql_run_approved_command. Pending approvals are one-time use and expire after MYSQL_APPROVAL_TTL_SECONDS. mysql_list_pending_approvals and mysql_cancel_approval are also available while MYSQL_POLICY_HOOK is set.
This is an approval-friendly protocol. The server cannot verify that a human approved the action; the MCP host or external platform is responsible for presenting the approval request to a user.
Security Notes
Use a dedicated MySQL user with the minimum permissions your assistant needs.
Prefer read-only database credentials if you only need inspection and reporting.
Use
MYSQL_READ_ONLY=trueorMYSQL_MCP_MODE=readonlyto hide write execution from MCP clients.Use
MYSQL_MCP_ALLOW_TABLESandMYSQL_MCP_DENY_TABLESas MCP-level guardrails, not as a replacement for MySQL grants.Use
MYSQL_POLICY_HOOKwhen you need an external policy or approval workflow.Be careful with
mysql_execute, because it can modify data.Be careful with
mysql_import_csv, because it can insert many rows.Batch execution and CSV import logs include parameter values and per-row results. Treat files under
logs/as sensitive.CSV export writes table data to the local filesystem. Treat exported files as sensitive.
Multi-statement SQL is disabled in the MySQL client configuration.
Do not commit
.envfiles or real database credentials to GitHub.Review generated SQL before running it against production data.
Development
npm run devThis runs TypeScript in watch mode.
To create a production build:
npm run buildTo run the integration test suite, configure a test database in .env:
TEST_HOST=localhost
TEST_PORT=3306
TEST_USERNAME=test_user
TEST_PASSWORD=test_password
TEST_DB=test_databaseThen run:
npm run testThe tests create and drop temporary tables, a view, and a trigger in TEST_DB. If the TEST_* variables are missing, the integration test is skipped.
Project Structure
src/
config.ts Environment-driven MCP policy configuration
csv.ts CSV parsing and writing helpers
csvTools.ts CSV import/export tool implementations
db.ts MySQL pool and query helpers
index.ts MCP server and tool registration
logs.ts Batch execution log helpers
policyHook.ts External policy hook client and approval response helpers
sqlPolicy.ts SQL parsing and policy enforcement
toolHandlers.ts Shared tool handler implementations
approvalStore.ts In-memory pending approval storeLicense
MIT. See LICENSE.md.
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/chenkumi/easy-mysql-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server