前言:AI 写代码很爽,但一碰数据库就卡住了
我在公司日常开发里,其实已经大量用 AI 辅助写代码了。
比如:
- 让 AI 帮我写接口逻辑
- 让 AI 帮我补 SQL
- 让 AI 根据需求生成测试数据
- 让 AI 帮我分析一段查询为什么慢
- 让 AI 根据业务字段补 DTO、Service、Mapper
这些场景都挺好用,但只要进入数据库相关开发,就会遇到一个很烦的问题:AI 根本看不到我的本地 MySQL。
具体痛点非常真实。
第一,AI 不知道我本地库里有哪些表、字段、索引。
我问它:
帮我写一个查询订单列表的 SQL。
它只能凭空猜:
SELECT * FROM orders WHERE user_id = ?
但我的真实表可能叫 t_order_main,用户字段可能叫 buyer_id,状态字段可能是 order_status,索引也不一定在它猜的字段上。
第二,AI 没法生成贴合业务的测试数据。
它可以帮我写一堆 mock 数据,但这些数据经常和真实表结构对不上,比如字段缺失、枚举值不合法、必填字段没填、时间字段格式不对。
最后还是得我自己打开数据库工具,一个字段一个字段补。
第三,AI 写好的 SQL,我还得手动复制到 Navicat 里执行。
这个过程特别割裂:
- 在 AI 里让它生成 SQL
- 复制 SQL
- 切到 Navicat / DBeaver
- 粘贴执行
- 看报错
- 再复制错误信息回 AI
- 让它改
- 再来一遍
来回切工具,非常影响心流。
第四,AI 没法直接验证 SQL 对不对。
它写完 SQL 后,只能告诉我“理论上应该可以”。但到底字段对不对、数据查不查得出来、执行计划怎么样,最后还是要我兜底执行核对。
所以我后面意识到,问题不在 AI 不会写 SQL,而是:
AI 和本地数据库完全隔离,开发链路没有闭环。
于是我决定自己写一个 MySQL MCP 服务,把 AI 和本地 MySQL 打通。
什么是 MCP?简单说就是让 AI 能调用本地工具
MCP 全称是 Model Context Protocol。
不用把它想得太复杂,我自己的理解是:
MCP 就是一套协议,让 AI 可以安全地调用你本地暴露出来的工具。
比如我本地有一个工具叫:
mysql_list_tables
AI 就可以通过 MCP 调用它,拿到数据库里有哪些表。
再比如我暴露一个工具叫:
mysql_query
AI 就可以通过它执行查询 SQL,并把结果拿回来继续分析。
以前 AI 只能“聊天”,现在通过 MCP,它可以“干活”。
对数据库开发来说,这个能力非常关键。
因为只要我把 MySQL 的查询、表结构查看、SQL 执行这些能力封装成 MCP 工具,AI 就不再是闭着眼睛猜表结构了,而是可以直接读取真实数据库信息。
我的整体设计思路
这个项目我用的是:
- NestJS
- TypeScript
- mysql2
- MCP SDK
- dotenv 环境配置
整体思路不复杂,核心就是一句话:
把 MySQL 的常见开发操作封装成 MCP 工具,让 AI 可以按权限调用。
我主要做了几类能力。
1. 把数据库操作封装成 AI 可调用的工具
我在服务里定义了一批 MCP tools,比如:
mysql_list_databases
mysql_list_tables
mysql_describe_table
mysql_query
mysql_explain
mysql_execute
mysql_ddl
mysql_transaction
它们分别负责:
- 查看数据库列表
- 查看某个库下面的表
- 查看表字段、索引、建表语句
- 执行 SELECT 查询
- 执行 EXPLAIN
- 执行 INSERT / UPDATE / DELETE
- 执行 CREATE / ALTER 这类 DDL
- 执行事务
AI 连接上这个 MCP 服务后,就能看到这些工具。
比如我问:
列出 test 数据库里有哪些表。
AI 实际上会调用:
mysql_list_tables
然后 MCP 服务去连我的本地 MySQL,把结果返回给 AI。
这一步之后,AI 就不是瞎猜了,它拿到的是我本地数据库里的真实结构。
2. AI 可以直接查看表结构
以前我经常要把表结构复制给 AI:
SHOW CREATE TABLE xxx;
然后贴到对话框里。
现在不用了。
我只要问:
看一下 user 表结构,然后帮我写一个根据手机号查询用户的 SQL。
AI 会先调用 MCP 工具读取表结构,比如字段、索引、建表语句,然后再生成 SQL。
这样生成出来的 SQL 会贴合真实表结构,不会再出现那种字段名完全对不上的情况。
这点对后端开发太实用了
尤其是公司项目里,表名和字段名经常不是标准英文,有历史包袱,有缩写,有前缀,还有一些奇怪的状态字段。
AI 如果不知道真实结构,基本只能猜。
3. AI 可以生成并插入测试数据
这个能力也是我很需要的。
开发接口时,经常需要造一些测试数据。
以前我会手写 INSERT:
INSERT INTO user (...) VALUES (...);
写几个字段还好,字段一多就很烦。
现在流程变成了:
根据 order 表结构,帮我生成 5 条测试订单数据并插入。
AI 会先读取 order 表结构,然后根据字段类型、必填字段、默认值,生成 INSERT 语句,再通过 MCP 执行。
当然,这里不是说完全放任 AI 乱插。
我做了权限控制,默认不会开放高危能力。测试环境可以开读写,生产环境建议只读。
4. AI 写 SQL、执行 SQL、返回结果,形成闭环
这是我觉得最爽的地方。
以前链路是:
AI 写 SQL -> 我复制 -> 数据库工具执行 -> 我复制结果 -> AI 分析
现在变成:
AI 写 SQL -> MCP 执行 -> 返回结果 -> AI 继续分析
中间少了很多手动操作。
比如我开发一个业务查询接口,我可以直接说:
帮我查一下 test 库有哪些表,找到订单相关表,然后写一条查询用户最近 10 条订单的 SQL,并执行验证。
AI 会自己完成:
- 查库
- 查表
- 看表结构
- 写 SQL
- 执行 SQL
- 根据返回结果调整 SQL
这个体验和之前完全不一样。
它不只是“帮我写代码”,而是开始真正参与开发闭环。
权限控制:不能让 AI 随便操作数据库
数据库工具最怕什么?
不是 AI 不够聪明,而是它太敢干。
所以我在设计时没有直接把所有能力都暴露出去,而是做了权限分级。
目前主要分几种模式:
PERMISSION_MODE=read_only
PERMISSION_MODE=read_write
PERMISSION_MODE=full
read_only
只允许查询类操作,比如:
- 查看数据库
- 查看表
- 查看表结构
- SELECT 查询
- EXPLAIN
这个模式适合连接比较敏感的库,比如公司测试库、预发库,甚至只读账号的生产库。
read_write
允许:
- INSERT
- UPDATE
- DELETE
但是会限制一些危险操作,比如 UPDATE / DELETE 默认必须带 WHERE。
full
这个模式才允许 DDL,比如:
- CREATE TABLE
- ALTER TABLE
而且 DDL 还需要额外开关:
ENABLE_DDL=true
我这样做的目的很简单:
默认安全,不要因为图方便让 AI 拿到过大的权限。
尤其是 DROP、TRUNCATE 这种操作,我默认是关的。真要开,也必须显式配置。
日志审计:AI 执行了什么 SQL,必须能查
我还加了审计日志。
每次 AI 调用数据库工具,我都会记录:
- 调用的工具名
- 执行时间
- 目标数据库
- SQL hash
- 是否成功
- 错误信息
- 影响行数
- 执行耗时
为什么不默认完整记录 SQL 参数?
因为有些参数里可能有手机号、身份证、token、密码这类敏感数据。
所以我默认更保守,只记录 SQL hash。需要排查时,可以通过配置打开更详细的日志。
这个功能在公司内部用很有必要。
不然 AI 到底执行过什么 SQL,出了问题很难追。
项目大概是怎么跑起来的
项目启动后,不是开一个 HTTP 服务,而是通过 stdio 和 AI 客户端通信。
也就是说,Codex 或 Claude Code 会启动这个 Node.js 进程,然后通过标准输入输出和它交换 MCP 消息。
大概流程是这样:
AI 客户端
|
| MCP 协议调用工具
v
MySQL MCP Server
|
| mysql2 连接池
v
本地 MySQL
配置大概是这样:
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=root
DB_PASSWORD=your_password
DB_DATABASE=test
PERMISSION_MODE=read_write
AUDIT_LOG_ENABLED=true
AUDIT_LOG_DIR=./logs
构建:
npm run build
在 Codex 中注册:
codex mcp add mysql \
--env DB_HOST=127.0.0.1 \
--env DB_PORT=3306 \
--env DB_USER=root \
--env DB_PASSWORD=your_password \
--env DB_DATABASE=test \
--env PERMISSION_MODE=read_write \
--env AUDIT_LOG_ENABLED=true \
--env AUDIT_LOG_DIR=/path/to/mysql-mcp-nest/logs \
-- node /path/to/mysql-mcp-nest/dist/main.js
注册后重启 Codex,就可以在对话里直接让 AI 操作本地 MySQL。
实际展示效果:
核心亮点:完成AI开发闭环,提高开发效率问题
我做这个项目,不是为了搞一个复杂中间件。
本质上就是解决几个非常具体的后端开发痛点。
亮点 1:AI 可以直接读取本地 MySQL 表结构
以前要手动复制表结构。
现在 AI 自己查。
我不需要再反复贴:
SHOW CREATE TABLE xxx;
AI 拿到真实字段、索引、建表语句后,生成 SQL 的准确率明显高很多。
亮点 2:AI 可以生成并插入业务测试数据
很多接口开发卡在造数据。
尤其是多表关联时,要先插用户,再插订单,再插明细,还要保证状态值正确。
现在我可以让 AI 先看表结构,再生成 INSERT。
虽然我还是会看一眼它要执行什么,但整体比自己手写快很多。
亮点 3:SQL 生成、执行、验证可以闭环
这是体验提升最大的地方。
以前 AI 写完 SQL 后,我要自己复制执行。
现在 AI 可以直接执行,并根据结果继续改。
比如 SQL 报字段不存在,它能马上根据错误调整,而不是等我把错误复制回去。
亮点 4:权限可控,不怕 AI 乱操作
我没有把数据库权限一股脑放开。
读、写、DDL 是分开的。
默认情况下,高危操作是关的。
这点很重要,因为数据库不是玩具。AI 再好用,也不能让它无脑拿最高权限。
亮点 5:所有操作都有日志,方便审计和排查
AI 执行 SQL 以后,我本地都有记录。
什么时候执行的、执行了哪个工具、成功失败、耗时多少,都能查。
这对排查问题很有帮助。
尤其是团队里多人使用时,日志审计是必须的。
实际使用效果
我接入之后,最明显的感受是:少了很多机械切换。
以前写一个业务查询接口,我大概要这样操作:
- 打开需求
- 找表
- 看字段
- 写 SQL
- 打开数据库工具执行
- 报错后回头改
- 再执行
- 再把 SQL 塞进代码里
现在我可以直接让 AI 帮我走完前半段:
看一下 test 库里的订单相关表,帮我写一个查询用户订单列表的 SQL,并执行验证一下。
它会先查表结构,再生成 SQL,再执行验证。
我需要做的是判断业务逻辑是否符合预期,而不是一直复制粘贴。
这就是我想要的效果。
AI 不应该只是一个“代码生成器”,它应该能接上我的真实开发环境,帮我把一些重复、机械、容易出错的环节串起来。
总结
这个 MySQL MCP 服务解决的核心问题其实很简单:
让 AI 能看到、能理解、能操作我的本地 MySQL。
它把原来割裂的开发链路打通了:
看表结构 -> 写 SQL -> 执行 SQL -> 验证结果 -> 调整逻辑
以前这些动作都要我手动来回切工具,现在 AI 可以通过 MCP 参与进来。
github链接:github.com/huanglixinc…