mysql-mcp-plugin

mysql-mcp-plugin

Provides MySQL access with configurable per-connection capabilities, enabling secure read-only or writable database operations through Claude Code and other MCP clients.

Category
访问服务器

README

mysql-mcp-plugin

MySQL access for Claude Code. Each user configures their own connections, and each connection grants a specific set of capabilities — so a production replica can be read-only while a scratch database is writable.

Install

/plugin marketplace add <your-github-user>/mysql-mcp-plugin
/plugin install mysql

Nothing to build and no paths to edit: dist/ ships prebuilt and self-contained. Node 20+ on PATH is the only requirement.

Add a connection

The settings form is the quickest route. Claude Code prompts for these fields when you enable the plugin, and you can reopen them any time:

/plugin configure mysql
Field Notes
Connection name Leave blank to skip the form entirely
MySQL host / port / user / database With a bastion set, the host is as resolved from the bastion
MySQL password Masked as you type; stored in your OS keychain, never in settings.json
SSH bastion host / user / key Blank key means agent auth, so no key material is stored
Allow read/write Adds INSERT, UPDATE, DELETE. Off by default
Allow schema changes Adds CREATE, ALTER, DROP, TRUNCATE. Off by default
Allow all queries Everything, including GRANT and SET GLOBAL. Off by default

Nothing is typed into the conversation, and the password is masked at entry.

The form holds one connection. It is a flat list of fields, so it cannot express several. For more than one — each with its own capabilities — use the commands:

/mysql:setup      guided, explains the model first
/mysql:add        straight to adding one

Those never ask for a password in the conversation either: they hand you a single line to run yourself, and the CLI prompts on your own terminal so the secret stays out of the transcript.

Both sources are merged, so you can use the form for your everyday database and /mysql:add for the rest. If a name appears in both, the file wins.

Then check the grants line up:

/mysql:test staging-replica

Commands

Command Purpose
/mysql:setup Guided first-time setup — explains the model, then adds a connection
/mysql:add Add a connection (prompts for password out-of-band)
/mysql:list Show connections and their capabilities
/mysql:test <name> Connect, show SHOW GRANTS, compare against declared caps
/mysql:grant <name> <caps> Widen what Claude may do
/mysql:revoke <name> <caps> Narrow it; --all disables the connection
/mysql:remove <name> Delete the connection and its stored password
/mysql:import Migrate a legacy MYSQL_SERVERS env setup

Capabilities

Cap Allows
select SELECT, WITH … SELECT, TABLE, VALUES
schema_read SHOW, DESCRIBE, EXPLAIN, USE
insert INSERT, REPLACE, LOAD DATA
update UPDATE
delete DELETE
ddl CREATE, ALTER, RENAME
drop DROP, TRUNCATE
admin GRANT, REVOKE, SET GLOBAL, user management, CALL

A connection with no capabilities is revoked: still configured, still credentialed, every query refused.

How enforcement works

1. PreToolUse hook   Claude Code only. Denies before the tool runs, so the model
                     never sees a result. Cannot be bypassed from context.
2. The server        Checks before executing. Works in ANY MCP client, so the
                     guarantee does not depend on Claude Code.
3. MySQL GRANTs      The real security boundary.

Layers 1 and 2 call the same authorize(), so their verdicts cannot drift apart. Layer 2 exists because the server is portable: point Cursor or any other MCP client at dist/index.js and capability checking still applies. The check runs before connecting, so a refused statement costs no handshake and opens no SSH channel.

Layer 3 is the one that actually protects the database. Layers 1 and 2 catch mistakes — a wrong connection name, a model error, something injected into the context — before they reach a database whose GRANTs might be wider than you intended. Give Claude a MySQL account holding only the privileges you are willing for it to have, and treat the capability list as a second pair of eyes rather than the lock.

Both fail closed: unreadable config, unparseable SQL, or anything unclassifiable is refused.

Batches are checked statement by statement. multipleStatements is enabled on the connection, so SELECT 1; DROP TABLE users really would run both — it needs select and drop, and is refused without them.

Connecting through a bastion

Set an ssh block and the plugin opens the tunnel itself — host/port then refer to the database as seen from the bastion:

{
  "version": 1,
  "defaultConnection": "staging-replica",
  "connections": {
    "staging-replica": {
      "host": "db.internal",
      "port": 3306,
      "database": "appdb",
      "user": "claude_ro",
      "password": { "keychain": "staging-replica" },
      "caps": ["select", "schema_read"],
      "ssh": {
        "host": "bastion.example.com",
        "port": 22,
        "user": "you",
        "auth": "agent"
      }
    }
  }
}

The tunnel is passed to the driver as a stream, so no local port is allocated and two people cannot collide on the same forwarded port. auth: "agent" uses SSH_AUTH_SOCK, which means the plugin never holds key material; auth: "key" with privateKeyPath is available where an agent is not.

If you would rather run your own tunnel, point the connection at 127.0.0.1 and set tunnelHint to the command that starts it — connection failures then tell you what to run.

Where configuration lives

Two sources, merged, with the file winning on a name clash:

Source Holds Secrets
Settings form (/plugin configure mysql) one connection password in OS keychain, via Claude Code
~/.config/claude-mysql/connections.json unlimited connections keychain or env reference only

The file path is overridable with MYSQL_MCP_CONFIG.

It contains no secrets, so a team can share a skeleton and each member populates their own keychain. Passwords are referenced as { "keychain": "name" } or { "env": "VARNAME" } — the latter for machines without an OS keychain, such as CI.

Tools

Two, unchanged from the pre-plugin server:

  • list_servers — configured connections, their capabilities, and the config path
  • execute_sql(server?, sql, database?) — run SQL on a connection

Development

npm install
npm run build      # typecheck + bundle to dist/
npm test           # 97 tests

Test coverage: SQL classification (19), authorization decisions (10), hook verdicts (21), the server driven over stdio as a bare MCP client (10), settings-form parsing and its capability toggles (17), onboarding notices (7), and the plugin manifests (14).

The stdio group verifies the portable guarantee — no Claude Code, no hook, and no database required, since refusals happen before the connection is opened. The manifest group exists because a published version once shipped author as a string instead of an object, which made the plugin uninstallable while every other test passed and CI was green.

Verified against a real environment: /mysql:import migrating connections out of ~/.claude.json, and the keychain write-then-read path via /mysql:list.

Still unverified, because both need a reachable database: a query executing through an SSH tunnel, and /mysql:test's comparison against live SHOW GRANTS output.

dist/ is committed. Bundling (rather than plain tsc) is what makes it self-contained — tsc output would still import mysql2, ssh2, and the MCP SDK at runtime, and node_modules is not shipped. npm run verify-dist checks the committed output matches src/.

Contributing

See CONTRIBUTING.md. One thing to know up front: dist/ is committed, so any src/ change needs npm run build committed alongside it — CI fails otherwise, and the tests alone won't catch it.

Design notes and rationale: docs/specs/.

License

MIT — see LICENSE.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选