
MCP Toolbox mysql-sql 工具完全指南用参数化 SQL 安全地为 Agent 暴露 MySQL 查询能力【免费下载链接】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-sql工具的官方文档展开讲解如何通过声明式 YAML 将一个预定义的 MySQL 查询封装为可供 LLM Agent 直接调用的 MCP 工具。读完本文你将掌握mysql-sql的两种参数注入方式基础参数与模板参数及其安全差异、完整配置字段含义、底层执行原理并能独立编写可投入生产使用的工具配置。关于 mysql-sql 工具mysql-sql是 MCP Toolbox 中针对 MySQL 数据源Source提供的一类工具其作用是在一个预定义的 SQL 语句基础上把查询逻辑暴露给大语言模型 Agent 调用。它与直接执行任意 SQL 的mysql-execute-sql不同mysql-sql的查询语句在配置文件中被预先固定Agent 只能通过声明好的参数影响查询行为从而在赋予 Agent 数据访问能力与控制查询边界之间取得平衡。该工具的核心特性是配置中指定的 SQL 语句以 MySQL 预处理语句prepared statement 的方式执行查询中的动态值必须以占位符?形式出现。这意味着 Agent 传入的值会作为绑定参数传递而不是被拼接进 SQL 文本从机制上阻断了 SQL 注入。兼容的数据源mysql-sql工具可以挂载在以下类型的数据源上执行自建 MySQLtype: mysql源Cloud SQL for MySQLtype: cloud-sql-mysql源在源码中这一点通过接口约束体现mysqlsql.go 定义了compatibleSource接口要求数据源必须实现MySQLPool()与RunSQL()方法mysql.go 中 MySQL 源实现了这两个方法Cloud SQL for MySQL 源同样如此。如果配置的source指向不兼容的类型工具在启动校验阶段就会报错ValidateSource返回 source ... is not a compatible type。前置条件配置 MySQL 数据源在定义mysql-sql工具之前需要先声明一个可用的 MySQL 数据源。参考 MySQL 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官方建议使用${ENV_NAME}环境变量占位符替换敏感信息避免把密码硬编码进配置文件。该配置在源码中的对应结构体见 mysql.go各字段含义如下字段类型必填说明typestring是固定为mysqlhoststring是数据库主机地址如127.0.0.1portstring是连接端口如3306userstring否连接使用的 MySQL 用户名passwordstring否对应用户密码databasestring否默认连接的数据库名queryTimeoutstring否查询最大等待时长如30s、2m默认不设超时queryParamsmapstring,string否透传给驱动go-sql-driver/mysql的任意 DSN 参数如tls: preferred、charset: utf8mb4常用于启用 TLS 等连接选项sqlCommenterboolean否覆盖全局--sql-commenter标志优先级更高从源码看queryTimeout会被解析为驱动的ReadTimeout同时连接池默认注入parseTime: true参数并通过program_name携带 User-Agent便于数据库侧追踪请求来源见 mysql.go。基础参数模式安全的?占位符mysql-sql最推荐的使用方式是利用基础参数parameters?占位符。文档给出了一个航班信息查询的完整示例kind: tool name: search_flights_by_number type: mysql-sql source: my-mysql-instance statement: | SELECT * FROM flights WHERE airline ? AND flight_number ? LIMIT 10 description: | Use this tool to get information for a specific flight. Takes an airline code and flight number and returns info on the flight. Do NOT use this tool with a flight id. Do NOT guess an airline code or flight number. A airline code is a code for an airline service consisting of two-character airline designator and followed by flight number, which is 1 to 4 digit number. For example, if given CY 0123, the airline is CY, and flight_number is 123. Another example for this is DL 1234, the airline is DL, and flight_number is 1234. If the tool returns more than one option choose the date closes to today. Example: {{ airline: CY, flight_number: 888, }} Example: {{ airline: DL, flight_number: 1234, }} parameters: - name: airline type: string description: Airline unique 2 letter identifier - name: flight_number type: string description: 1 to 4 digit number这个示例同时演示了三个关键实践占位符与参数的顺序对应statement中第 1 个?对应parameters列表中的第 1 个参数airline第 2 个?对应flight_number按声明顺序绑定。描述即Agent 使用手册description字段会原样传递给 LLM官方文档特意加入了不要使用 flight id不要猜测航司代码若返回多行取离今天最近的日期以及 JSON 调用示例等约束用于引导 Agent 正确传参。这段描述的质量直接决定 Agent 的调用准确率。安全边界文档明确指出——参数只能替换任意表达式不能替换标识符、列名、表名等 SQL 语法结构。参数值会作为绑定值传入预处理语句天然规避注入风险。参数声明规范parameters支持的类型包括string、integer、float、boolean、array每个参数对象的常用字段如下完整说明见 Tools 配置文档字段类型必填说明namestring是参数名与 statement 中?按顺序对应typestring是string/integer/float/boolean/array之一descriptionstring是给 Agent 看的自然语言说明default参数类型否提供后参数变为可选缺省调用使用默认值requiredbool否是否必填默认trueallowedValues[]string否输入白名单校验支持正则excludedValues[]string否输入黑名单校验支持正则minValue/maxValueint/float否仅限integer、float限制取值范围escapestring否仅限string指定转义分隔符用于模板参数场景注意参数默认必填。若 Agent 漏传参数调用会以parameter airline is required的形式被拒绝。模板参数模式灵活但高风险当需要让 Agent 决定表名、列名等 SQL 结构时基础参数无能为力此时可使用模板参数templateParameters。模板参数会在执行预处理语句之前被直接插入 SQL 文本kind: tool name: list_table type: mysql-sql source: my-mysql-instance statement: | SELECT * FROM {{.tableName}}; description: | Use this tool to list all information from a specific table. Example: {{ tableName: flights, }} templateParameters: - name: tableName type: string description: Table to select from模板参数使用 Go 模板语法{{.参数名}}在 SQL 语句中占位。与基础参数不同模板参数允许直接修改 SQL 语句——包括标识符、列名、表名因此更容易受到 SQL 注入攻击。官方文档对此给出了明确建议优先使用基础参数性能与安全俱佳若必须使用模板参数务必通过allowedValues白名单支持正则限制输入范围对string类型可使用escape字段如single-quotes、double-quotes、backticks、square-brackets为标识符加定界符但需注意仅转义并不能完全保证安全对integer/float类型可用minValue/maxValue限定取值范围。模板参数同样支持array类型元素必须为 string插入后外层引号会被移除因此向 SQL 中插入字符串时需要自行在值内显式添加引号。配置字段参考mysql-sql工具的完整配置字段如下对应源码结构体 mysqlsql.go字段类型必填说明typestring是固定为mysql-sqlsourcestring是SQL 要执行的目标数据源名称descriptionstring是工具的说明会传递给 LLM 用于决策statementstring是要执行的 SQL 语句预处理语句parametersparameters否以?占位符形式插入 SQL 的参数列表templateParameterstemplateParameters否在执行预处理语句前直接插入 SQL 文本的参数列表其中type、source、statement、description均带validate:required约束缺失会导致配置解析失败description为空时Initialize 阶段会直接返回description is required for tool ...错误。此外配置还支持可选的annotations字段MCP 工具语义注解如readOnlyHint、destructiveHint未指定时默认按写操作注解处理destructiveHint: true。底层执行原理一次调用的完整链路了解工具如何工作有助于排查问题和评估安全边界。从源码看一次mysql-sql调用经过以下步骤参数解析工具初始化时调用parameters.ProcessParameters合并模板参数与基础参数生成参数清单manifest描述与参数 schema 会进入 MCPtools/list响应供 LLM 感知见 mysqlsql.go。调用分发Invoke首先把运行时传入的paramsMap拆分为两部分——通过ResolveTemplateParams将模板参数渲染进statement文本这一步是 Go 模板求值见 parameters.go 引入的text/template再通过GetParams提取基础参数值并按声明顺序转为[]any切片见 mysqlsql.go。预处理执行渲染后的 SQL 与参数切片交给数据源的RunSQL。MySQL 源的实现位于 mysql.go先调用sqlcommenter.PrependComment为 SQL 注入可观测性注释再通过QueryContext(ctx, statement, params...)以绑定参数方式执行——这正是预处理语句的安全保证所在。结果归一化逐行扫描结果按列类型做转换。字符串与字节类型统一转成stringJSON类型列先做一次json.Unmarshal再返回避免返回给 MCP 客户端时发生双重序列化见 mysqlcommon.go。调用链速览MCP tools/call └─ mysqlsql.Tool.Invoke ├─ parameters.ResolveTemplateParams # 模板参数渲染进 SQL 文本 ├─ parameters.GetParams # 基础参数提取为有序切片 └─ mysql Source.RunSQL # sqlcommenter 预处理执行 └─ database/sql QueryContext # ? 占位符绑定测试验证配置解析的可靠性仓库中为mysql-sql提供了配置解析测试见 mysqlsql_test.goTestParseFromYamlMySQL验证包含基础参数、authRequired认证要求、以及authServices从 OIDC token 的user_idclaim 自动填充参数的完整 YAML 能被正确解析为工具配置TestParseFromYamlWithTemplateParamsMySQL验证基础参数与templateParameters含 string 与 array 类型混合声明的解析结果。两个测试都通过server.UnmarshalPrimitiveConfig走与真实启动相同的配置反序列化路径并用cmp.Diff对解析结果做严格比对。这意味着你在 YAML 中书写的任何字段组合都可以借助这些测试用例对照源码结构体确认其合法形态。生产实践建议结合文档与源码使用mysql-sql时有几点值得注意默认走基础参数只要动态值是字面量条件过滤、LIMIT 数量等一律用?parameters兼顾性能与防注入。模板参数必须加白名单确需暴露表名/列名时用allowedValues枚举合法值并配合escape转义永远不要接受 Agent 的任意输入直接拼入 SQL。description 写得越具体Agent 越可靠包含参数格式、边界规则、否定约束不要做什么和调用示例能显著减少幻觉参数与错误调用。敏感信息用环境变量数据源配置中的密码等一律以${ENV_NAME}注入parameters支持authServices从 OIDC token 自动填充用户身份字段可参考 Tools 配置文档 实现按用户隔离的数据访问。注意只读与安全语义mysql-sql底层走QueryContext可执行任意 SQL 语句如果工具只做查询可在annotations中显式声明readOnlyHint: true帮助 MCP 客户端理解工具的副作用边界。参考文档与源码索引本文主题文档mysql-sql 工具文档MySQL 数据源配置source.md工具与参数通用规范Tools 配置文档工具核心实现mysqlsql.goMySQL 源实现与 SQL 执行mysql.go结果类型转换mysqlcommon.go配置解析测试mysqlsql_test.goMySQL 预置配置mysql.yaml【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考