MCP Toolbox MySQL 执行 SQL 工具(mysql-execute-sql)完整指南:配置、原理与实战
2026/9/15 22:01:41 网站建设 项目流程

MCP Toolbox MySQL 执行 SQL 工具(mysql-execute-sql)完整指南:配置、原理与实战

【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox

本篇技术指南围绕 MCP Toolbox for Databases 开源项目中的mysql-execute-sql工具展开,详细讲解它如何通过 MCP Server 让 LLM/Agent 对 MySQL 数据库执行 SQL 语句,覆盖工具配置、数据源对接、参数说明、底层调用链与安全注解机制。读完本文,你将掌握如何在自己的 MySQL 实例上配置并使用该工具,理解它与mysql数据源之间的协作方式,并能基于源码与测试用例深入排查问题。

工具概述:mysql-execute-sql 是什么

mysql-execute-sql是 MCP Toolbox for Databases(项目根目录)为 MySQL 集成提供的一个工具(tool)。根据官方文档(mysql-execute-sql.md)的定义,它负责对 MySQL 数据库执行一条 SQL 语句

该工具的行为非常简单直接:

  • 接收一个输入参数sql(要执行的 SQL 语句字符串);
  • 将该语句在工具配置中指定的source(数据源)上执行,并返回执行结果。

注意(源自官方文档):此工具面向开发者辅助工作流(developer assistant workflows),强调 human-in-the-loop(人在回路),不应用于生产环境中的自动化 Agent。这是因为它可以执行任意 SQL(包括 DDL/DML 写操作),在生产场景下风险过高。

从源码看,该工具在 mysqlexecutesql.go 中以mysql-execute-sql为注册名,通过包内init()函数调用tools.Register注册到全局工具注册表,与 MySQL 集成下其他工具(如mysql-list-tablesmysql-get-query-plan等,见 tools 目录)并列。

兼容的数据源

mysql-execute-sql需要挂在某个数据源(source)之上。官方文档通过{{< compatible-sources others="integrations/cloud-sql-mysql">}}声明其兼容来源,即:

  • 原生 MySQL 数据源(type: mysql,详见 source.md);
  • Google Cloud SQL for MySQL 数据源(integrations/cloud-sql-mysql,见 cloud-sql-mysql 集成文档)。

这一约束在源码中有严格校验。工具定义了compatibleSource接口(mysqlexecutesql.go),要求数据源必须实现:

type compatibleSource interface { MySQLPool() *sql.DB RunSQL(context.Context, string, []any) (any, error) }

当调用方传入不兼容的数据源时,Invoke会返回客户端错误 "source used is not compatible with the tool"(mysqlexecutesql.go);ValidateSource也会在初始化阶段拒绝类型不匹配的数据源。原生mysql数据源(mysql.go)同时实现了MySQLPool()RunSQL(),因此天然兼容。

配置 mysql-execute-sql 工具

最小 YAML 配置示例

官方文档给出的工具配置示例如下:

kind: tool name: execute_sql_tool type: mysql-execute-sql source: my-mysql-instance description: Use this tool to execute sql statement.

四个字段均为必填,含义如下(依据 Reference 表格 与 Config 结构体):

fieldtyperequireddescription
kindstringtrue声明资源类型为工具,固定为tool
namestringtrue工具实例名称,在配置文件中唯一(例如execute_sql_tool
typestringtrue工具类型,必须为mysql-execute-sql
sourcestringtrue执行 SQL 的数据源名称,必须指向配置文件中已定义的type: mysql数据源
descriptionstringtrue传递给 LLM 的工具描述,LLM 会据此决定何时调用该工具,建议写清楚适用场景

namedescriptionauthRequired等通用字段来自tools.ConfigBase(内联到 Config 中)。其中descriptionInitialize阶段被强制校验——为空会直接报错description is required for tool %q(mysqlexecutesql.go)。

可选配置:authRequired 与 annotations

虽然官方文档的 Reference 只列了三个核心字段,但源码表明工具还支持两个可选配置项:

kind: tool name: execute_sql_tool type: mysql-execute-sql source: my-mysql-instance description: Use this tool to execute sql statement. authRequired: - my-google-auth-service annotations: destructiveHint: true
  • authRequired:声明调用该工具所需的认证服务列表,解析行为已被单元测试覆盖(见 mysqlexecutesql_test.go 中的TestParseFromYamlExecuteSql);
  • annotations:覆盖默认的 MCP Tool Annotations(destructiveHint/readOnlyHint/idempotentHint/openWorldHint),与 MCP 规范中的 tool annotations 对应(见 tools.go)。

配置 MySQL 数据源(source)

工具本身不携带连接信息,真正的数据库连接由mysql数据源负责。参考 source.md,一个完整的 source 配置如下:

kind: source name: my-mysql-instance type: mysql host: 127.0.0.1 port: 3306 database: my_db user: ${USER_NAME} password: ${PASSWORD} # Optional TLS and other driver parameters. For example, enable preferred TLS: # queryParams: # tls: preferred queryTimeout: 30s # Optional: query timeout duration
fieldtyperequireddescription
typestringtrue必须为mysql
hoststringtrue连接地址(如127.0.0.1
portstringtrue连接端口(如3306
userstringfalseMySQL 用户名
passwordstringfalse用户密码
databasestringfalse要连接的数据库名
queryTimeoutstringfalse查询执行超时时间(如30s2m),默认不设超时
queryParamsmap<string,string>false传递给驱动的任意 DSN 参数(如tls: preferredcharset: utf8mb4),可用于启用 TLS 或其他连接选项
sqlCommenterbooleanfalse覆盖全局--sql-commenter开关,设置时优先于全局标志,省略时遵循全局设置

在源码层面,数据源初始化逻辑位于 mysql.go 的initMySQLConnectionPool

  • 基于go-sql-driver/mysql构建 DSN,userpassword成对生效(无 user 时忽略 password);
  • 默认注入parseTime=true参数,用户自定义的queryParams会合并进参数表(空值被跳过);
  • queryTimeout通过time.ParseDuration解析后映射为驱动层的ReadTimeout,解析失败会返回 "invalid queryTimeout" 错误;
  • 将当前进程的 UserAgent 写入 DSN 的ConnectionAttributesprogram_name),便于在 MySQL 侧追踪流量来源;
  • 连接池建立后会执行PingContext验证连通性,失败则关闭连接池并报错(mysql.go)。

安全建议(源自官方文档 tip):使用${ENV_NAME}形式的环境变量替换(例如${MYSQL_USER}${MYSQL_PASSWORD}),不要把明文密钥硬编码进配置文件。仓库预置配置 mysql.yaml 正是这样做的。

底层执行原理:一条 SQL 的完整旅程

当 LLM 调用该工具时,MCP Server 会路由到Tool.Invoke,其执行链路(mysqlexecutesql.go)大致如下:

  1. 类型断言:将sources.Source断言为compatibleSource,失败则返回错误;
  2. 参数提取:从paramsMap中取出sql字符串,非字符串类型返回 Agent 错误;
  3. 日志记录:以 Debug 级别记录将要执行的 SQL(executing 'mysql-execute-sql' tool query: ...),便于排障;
  4. 执行:调用source.RunSQL(ctx, sqlStr, nil)执行,参数列表为空切片;
  5. 错误归一化:执行失败时通过util.ProcessGeneralError转换为统一格式的 ToolboxError 返回。

数据源侧 RunSQL 的实现

原生mysql数据源的RunSQL(mysql.go)完成真正的数据库交互:

  • 先用sqlcommenter.PrependComment为语句附加 SQLCommenter 注释(受全局--sql-commenter或 source 级sqlCommenter控制,该参数定义于 mysql.go);
  • 通过连接池QueryContext执行语句并取出列名与列类型;
  • 逐行Scan数据,使用mysqlcommon.ConvertToType做类型归一化;
  • 结果按orderedmap.Row保持列顺序组装为 JSON 友好的结构返回。

类型转换细节:JSON 列的防双重序列化

ConvertToType(mysqlcommon.go)有一个值得注意的细节:当列类型为字符串/字节/sql.NullString且数据库类型名为JSON时,会先对原始字节做json.Unmarshal再返回对象,避免后续再次序列化造成"双重编码";其余数值类型保持原样返回。这意味着查询JSON类型的列时,返回给 LLM 的是可直接使用的结构化对象,而非转义后的字符串。

安全注解:只读数据源下的动态降级

mysql-execute-sql默认被标记为**破坏性(destructive)**注解——Initialize中调用tools.NewDestructiveAnnotations作为默认值(mysqlexecutesql.go),因为任意 SQL 可能包含INSERT/UPDATE/DELETE/DDL

但源码实现了动态注解翻转(mysqlexecutesql.go):当所连接的数据源处于只读模式(src.IsReadOnly()返回 true)时,工具会自动把destructiveHint翻转为 false、readOnlyHint翻转为 true,同时保留用户自定义的idempotentHintopenWorldHint。这一行为在 TestGetAnnotations 中有完整覆盖:

  • nil source → 保持默认破坏性注解;
  • 读写 source → 保持默认破坏性注解;
  • 只读 source → 动态翻转为只读注解;
  • 只读 source + 显式只读 base → 仍为只读;
  • 只读 source + 自定义 hints → 仅翻转 readOnly/destructive 两项,保留其余自定义 hint。

这意味着在只读副本上配置该工具时,MCP 客户端与 LLM 会自动感知到它只读的属性,从而减少误写风险。

开箱即用:预置配置与工具集

仓库为 MySQL 提供了开箱即用的预置配置 mysql.yaml,其中:

  • 定义了一个名为mysql-source的 source,主机/端口/账号/密码全部通过环境变量注入(MYSQL_HOSTMYSQL_PORTMYSQL_DATABASEMYSQL_USERMYSQL_PASSWORD),queryTimeout预设为30s
  • 定义了名为execute_sqlmysql-execute-sql工具实例,直接指向mysql-source
  • 同时定义了两个工具集(toolset):
    • data:由execute_sqllist_tablesget_query_plan组成,面向数据读写与查询场景;
    • monitor:由get_query_planlist_active_querieslist_all_lockslist_table_fragmentationlist_table_statslist_tables_missing_unique_indexesshow_query_stats组成,面向实例监控与诊断。

你可以直接复用这份预置配置,只需把工具名改成符合自己语义的名字,并确保source字段与实际的 source 名称一致。

测试与验证:如何确认配置正确

仓库为mysql-execute-sql提供了单元测试 mysqlexecutesql_test.go,可用于验证:

  • YAML 解析正确性TestParseFromYamlExecuteSql):模拟一个包含authRequired的完整配置,断言解析出的Config(Name/Description/AuthRequired/Type/Source)与期望完全一致;
  • 注解动态翻转逻辑TestGetAnnotations):覆盖只读/读写数据源与自定义注解的各种组合。

在本地执行go test ./internal/tools/mysql/...即可运行上述测试,快速确认工具注册、配置解析链路没有问题(真实数据库联调则需要可访问的 MySQL 实例或 Cloud SQL for MySQL 环境)。

最佳实践小结

  1. 限定使用场景:仅在开发者辅助、human-in-the-loop 的工作流中使用;生产 Agent 不应直接暴露任意 SQL 执行能力;
  2. 严格的最小权限:为工具配置独立、最小权限的 MySQL 用户(该数据源仅使用标准认证,需先创建可登录的 MySQL 用户,参考 source.md);
  3. 使用环境变量注入密钥${ENV_NAME}占位符替代硬编码密码;
  4. 善用只读数据源:查询类场景可指向只读副本,工具注解会自动降级为只读,降低误写风险;
  5. 写好 description:该字段直接决定 LLM 何时选择调用此工具,描述应覆盖典型用途(如"执行 SQL 查询/写入语句")与限制;
  6. 合理设置 queryTimeout:避免长时间运行的查询拖垮连接池,30s是仓库预置配置的默认值。

更完整的 MySQL 工具集清单(查询计划、表统计、锁分析、碎片整理等)可在 tools 文档目录 中继续探索。

【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询