mcp转到mysql
MySQL和MariaDB的模型上下文协议(MCP)服务器,用Go编写。 允许Claude Desktop(或任何MCP客户端)通过以下方式探索和修改数据库 一套定义明确的小工具。
安全模型
两层,而且只有两层。删除了任何额外的“危险模式正则表达式” 因为它用清晰度和误报换取了数据库的保护 已经提供了更好的。
第1层——MySQL授权(主要)。 这才是真正的边界。MCP 与专用用户连接;用户的权限决定了实际是什么 可能的。用户没有 FILE 无法阅读 /etc/passwd 不管怎样 SQL是有语法的。用户没有 CREATE USER 无法创建用户。拿到这个 第三层,其余大部分都是偏执狂。
第二层——动词分类器(此代码)。 深层防御 第1层配置错误的情况(根用户、授权范围太广等)。每 语句在删除注释后按其前导SQL动词进行分类。 分类器:
- 总是拒绝 权限管理和文件系统访问:
GRANT, REVOKE, SET, FLUSH, RESET, KILL, SHUTDOWN, LOAD, HANDLER, INSTALL, UNINSTALL, LOCK, UNLOCK.也拒绝 INTO OUTFILE / INTO DUMPFILE 其他合法选择中的条款。
- 拒绝DDL (
CREATE,DROP,ALTER,TRUNCATE,RENAME)除非
ALLOW_DDL=true.
- 拒绝堆叠语句 (
SELECT 1; DROP DATABASE foo). - 拒绝未知动词 --这是白名单,不是黑名单。
- 允许
SELECT/WITH/SHOW/DESCRIBE/EXPLAIN/USE和
INSERT/UPDATE/DELETE/REPLACE/CALL.
加:A UPDATE 或 DELETE 这最终会影响到比 MAX_SAFE_ROWS 行需要 confirm_key 承诺。这赶上了,我忘了 “WHERE”情况下,不尝试解析SQL。
分类器故意做什么 不 做:
- 它的模式不匹配
SLEEP,BENCHMARK,EXTRACTVALUE等等。
这些是合法的SQL函数;经典的“基于时间的盲注射” 威胁模型假设用户输入被连接到SQL中 应用程序——这不是这里发生的事情。MCP客户端是LLM, 它直接写完整的语句。
- 它不会尝试检测丢失
WHERE带有正则表达式的子句(这些检查
有错误和误报)。行计数门覆盖了相同的用例 更可靠。
推荐MySQL用户
-- Create a dedicated user
CREATE USER 'mcp_user'@'%' IDENTIFIED BY 'secure_password';
-- Minimum privileges for read-only usage
GRANT SELECT, SHOW VIEW ON your_database.* TO 'mcp_user'@'%';
-- Read + write (most common)
GRANT SELECT, INSERT, UPDATE, DELETE, SHOW VIEW
ON your_database.* TO 'mcp_user'@'%';
-- DDL (only if you actually want Claude to alter the schema)
GRANT CREATE, ALTER, DROP, INDEX ON your_database.* TO 'mcp_user'@'%';
FLUSH PRIVILEGES;做 不 使用 root 或任何用户 GRANT OPTION / FILE / CREATE USER / SUPER分类器阻止了明显的滥用行为,但 赠款是从源头上阻止他们的东西。
工具
| 工具 | 它做什么 |
|---|---|
query | 运行SELECT/WITH/SHOW。只读。 |
execute | 运行INSERT/UPDATE/DELETE。要求 confirm_key 过去 MAX_SAFE_ROWS. |
tables | 列出带有元数据的表。 |
describe | 显示一个表的列、类型和键。 |
views | 列出视图。 |
indexes | 显示表的索引。 |
explain | 解释一个选择。 |
count | SELECT COUNT(*) 在桌子上。对于过滤计数,请使用 query. |
sample | 表的前N行(默认10行,最多100行)。 |
database_info | 服务器版本、当前用户、主机、端口、数据库。 |
安装
git clone https://github.com/scopweb/mcp-go-mysql.git
cd mcp-go-mysql
go mod tidy
go build -o mysql-mcp ./cmd
go test ./...配置
.env 在项目目录中,或在Claude中的环境变量中 桌面配置。
| 变量 | 必填 | 默认 | 备注 |
|---|---|---|---|
MYSQL_HOST | 是的 | localhost | |
MYSQL_PORT | 没有 | 3306 | |
MYSQL_USER | 是 | -- | 专用用户,而不是root用户。 |
MYSQL_PASSWORD | 是 | -- | |
MYSQL_DATABASE | yes | -- | 默认架构。 |
LOG_PATH | 没有 | mysql-mcp.log | 仅限于cwd、temp或 /var/log. |
ALLOWED_TABLES | no | 空(=允许所有表) | 逗号分隔的白名单 describe. |
ALLOW_DDL | 没有 | false | true 让DDL通过分类器。 |
SAFETY_KEY | 没有 | PRODUCTION_CONFIRMED_2025 | 需要>MAX_SAFE_ROWS 写。 |
MAX_SAFE_ROWS | 没有 | 100 |
如果出现以下情况,启动时会记录警告 SAFETY_KEY 保持默认状态-- 将其更改为任何非平凡的用途。
克劳德桌面版
配置文件:
| 操作系统 | 路径 |
|---|---|
| 窗户 | %APPDATA%\Claude\claude_desktop_config.json |
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
{
"mcpServers": {
"mysql": {
"command": "C:\\path\\to\\mysql-mcp.exe",
"args": [],
"env": {
"MYSQL_HOST": "localhost",
"MYSQL_PORT": "3306",
"MYSQL_USER": "mcp_user",
"MYSQL_PASSWORD": "secure_password",
"MYSQL_DATABASE": "your_database",
"SAFETY_KEY": "your-own-key",
"MAX_SAFE_ROWS": "100"
}
}
}
}重新启动克劳德桌面。在一次新的聊天中:“有哪些MySQL工具可用?” 应该列出十个工具。
示例
-- Allowed
SELECT * FROM products WHERE category = 'electronics' LIMIT 10
UPDATE orders SET status = 'shipped' WHERE order_id = 12345
WITH t AS (SELECT 1) SELECT * FROM t
-- Allowed, but >MAX_SAFE_ROWS rows → asks for confirm_key
UPDATE products SET discount = 0.1 WHERE category = 'clearance'
-- Rejected: privilege management
GRANT ALL ON *.* TO 'evil'@'%'
CREATE USER 'foo'@'%' IDENTIFIED BY 'bar'
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('x')
FLUSH PRIVILEGES
-- Rejected: filesystem
LOAD DATA INFILE '/etc/passwd' INTO TABLE x
SELECT * FROM users INTO OUTFILE '/tmp/data'
-- Rejected: stacked
SELECT 1; DROP DATABASE foo
-- Rejected unless ALLOW_DDL=true
DROP TABLE users
ALTER TABLE users ADD COLUMN x INT测试
go test ./... # everything
go test -v ./test/security/... # the verb classifier
go test -bench=. ./test/security/...test/security/security_tests.go 检查依赖关系哈希和 go.mod 诚信。 test/security/integration_test.go 练习每一类 动词分类器(允许、禁止、DDL门控、堆叠、未知)。
项目布局
cmd/ MCP protocol layer (stdin/stdout JSON-RPC)
main.go Entry point + .env loader + log path validation
handlers.go initialize / tools/list / tools/call routing
tools.go Tool definitions and dispatch
format.go AI-optimized result formatting
security.go stripSQLComments helper
sqlcheck.go isReadOnlyQuery / isWriteQuery / isDDLQuery
internal/ Database client + policy
client.go Connection, classifier, ValidateQuery, helpers
audit.go Audit event types (loggers pluggable)
timeout.go Per-operation timeout profiles
db_compat.go MySQL vs MariaDB detection and tuning
test/security/ Classifier tests + dependency-integrity tests
docs/ Architecture and security notes故障排除
| 症状 | 可能原因 |
|---|---|
connection refused | MySQL未在配置的主机/端口上运行 |
access denied | 错误的凭据或授权不包括架构。 |
statement "X" is not allowed | 一个被禁止的动词(GRANT、SET、LOAD…)。使用补助金。 |
DDL operations are blocked | 设置 ALLOW_DDL=true 如果你真的想要这个。 |
multiple statements are not allowed | 将您的通话拆分为单独的通话 query/execute 跑。 |
operation affects N rows (>M) | 通行证 confirm_key 匹配 SAFETY_KEY. |
日志转到 LOG_PATH (默认值 mysql-mcp.log 在cwd中)。 tail -f 与此同时 调试。
许可证
麻省理工学院——见许可证。
