1. SpringAI 接入 MySQL MCP 服务时,Key 分散到底卡在哪
如果你正在做 SpringAI 项目,想让大模型直接查 MySQL,大概率会走到 MCP(Model Context Protocol)这条路。MySQL MCP 服务本质上是一个中间层:它把自然语言问题翻译成 SQL,执行完再把结果回传给模型。听起来很顺,但真正落地时,很多人第一步就卡住了——不是 MCP 不会配,而是 Key 太散。
我见过一个典型项目:application.yml里写着 OpenAI 兼容接口的api-key,MCP 客户端配置里又塞了一份数据库密码,再加上模型服务商自己的 Key,三套凭证散落在不同文件。改一次 Key 要翻三个地方,团队里谁动了配置根本说不清。更麻烦的是,SpringAI 的 MCP 客户端在启动时会读取stdio连接的环境变量,如果 Key 写错或者漏配,报错信息往往只告诉你“连接失败”,不告诉你是哪一层的问题。
这篇要解决的,就是把这个场景收敛成一条清晰链路:用 TaoToken 的统一 Key 替换掉分散的模型侧凭证,让 SpringAI 的application.yml和 MCP 客户端配置只维护一份模型访问凭证,数据库连接信息单独隔离。目标很明确——你跟着配完,能跑通一次真实的 MySQL 查询,并且知道每一步在验证什么。
适合谁看?正在用 SpringAI 做 AI 应用、需要让模型访问业务数据库的 Java 开发者;或者你已经跑通了纯对话,但想加 MCP 工具调用却不知道 Key 该怎么管。下面从环境准备开始,一步步给可复制的骨架。
2. TaoToken 统一 Key 的前置准备与 MCP 依赖安装
在动 SpringAI 配置之前,先把两件事做完:拿到统一 Key,装好 MySQL MCP Server。这两步不做,后面配置写得再漂亮也跑不起来。
2.1 获取 TaoToken 统一 Key
TaoToken 的作用是把模型访问凭证统一到一处。你不需要在 SpringAI 里分别填不同服务商的 Key,只需要一个统一 Key,配合 Base URL 就能调用。操作路径很直接:
打开官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,进入控制台后创建 API Key。创建完先别关页面,把 Key 复制到安全的地方,后面application.yml要用。
这里有个细节:TaoToken 的 API 地址是https://taotoken.net/api,注意这个地址不带任何查询参数,配置时直接写这个就行。模型 ID 根据你实际使用的模型填,比如gpt-4o或claude-3-5-sonnet这类,具体以控制台展示为准。
提示:Key 只显示一次,建议创建后立刻写入项目的环境变量或配置中心,不要硬编码在会提交到 Git 的文件里。
2.2 安装 MySQL MCP Server
MySQL MCP Server 是别人已经写好的组件,你拉下来用就行。它基于 MCP 协议,负责连接 MySQL 并把模型生成的 SQL 执行掉。安装方式有两种,按你的使用习惯选:
局部安装,适合只想在当前项目里用:
npm install mysql-mcp-server全局安装,适合多个项目共用:
npm -g install mysql-mcp-server装完之后,你可以用npx mysql-mcp-server测试一下是否能被调用。Windows 环境下命令是npx.cmd,Linux 和 macOS 用npx,这个差异在 SpringAI 的 MCP 配置里要体现出来,后面会写到。
2.3 确认 MySQL 连接信息
MCP Server 需要知道连哪个库。提前准备好这几个值:数据库地址(本地一般是localhost)、端口(默认3306)、用户名、密码、数据库名。这些信息不会放进 TaoToken 的 Key 体系里,它们属于数据库侧凭证,单独放在 MCP 的env配置中。
把这两步做完,你手里应该有一个 TaoToken Key、一个可执行的 MCP Server、一组 MySQL 连接参数。接下来进入 SpringAI 的配置文件。
3. application.yml 与 MCP 客户端可复制配置骨架
这一节是核心。SpringAI 项目里,模型访问凭证和 MCP 工具配置都集中在application.yml,我们把 TaoToken 的统一 Key 写进模型侧,把 MySQL 连接信息写进 MCP 侧,两边互不干扰。
3.1 完整 application.yml 骨架
下面这份配置可以直接复制,替换掉 Key、模型 ID 和数据库信息即可:
server: port: 8013 spring: application: name: springai-mysql-mcp-client ai: openai: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY} chat: options: model: gpt-4o temperature: 0.7 mcp: client: name: springai-mysql-mcp-client stdio: connections: mysql: command: "npx.cmd" args: - "mysql-mcp-server" env: MYSQL_HOST: "localhost" MYSQL_PORT: "3306" MYSQL_USER: "root" MYSQL_PASSWORD: "your_password" MYSQL_DATABASE: "your_database"几个关键点解释一下。base-url写 TaoToken 的 API 地址,api-key用环境变量${TAOTOKEN_API_KEY}注入,这样 Key 不会出现在代码仓库里。model填你在 TaoToken 控制台确认可用的模型 ID。MCP 部分,command在 Windows 下是npx.cmd,Linux/macOS 改成npx;args第一个参数是 MCP Server 名称,必须和安装的包名一致。
注意:
stdio.connections下的mysql是连接名,你可以改成别的,但要和后面 Java 配置里引用的名字保持一致。数据库密码建议同样用环境变量,避免明文。
3.2 MCP 客户端配置类
SpringAI 需要把 MCP 工具回调注册到 ChatClient 上,这样模型才知道可以调用 MySQL 查询。配置类如下:
package com.example.springai.mysql.config; import jakarta.annotation.Resource; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.mcp.SyncMcpToolCallbackProvider; import org.springframework.ai.openai.OpenAiChatModel; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ChatClientConfig { @Resource private OpenAiChatModel openAiChatModel; @Resource private SyncMcpToolCallbackProvider syncMcpToolCallbackProvider; @Bean("openAiChatClient") public ChatClient openAiChatClient() { return ChatClient.builder(openAiChatModel) .defaultToolCallbacks(syncMcpToolCallbackProvider) .build(); } }这里SyncMcpToolCallbackProvider会自动读取application.yml里配置的 MCP 连接,把 MySQL 工具暴露给模型。你不需要手动 new 任何 MCP 客户端,SpringAI 的自动配置会处理。
3.3 Controller 与启动类
Controller 负责接收问题并流式返回结果:
package com.example.springai.mysql.controller; import jakarta.annotation.Resource; import org.springframework.ai.chat.client.ChatClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; @RestController @RequestMapping("/mysql") public class MySQLController { @Resource private ChatClient openAiChatClient; @GetMapping(value = "/query", produces = "text/html;charset=utf-8") public Flux<String> query(@RequestParam("question") String question) { return openAiChatClient.prompt() .user(question) .stream() .content(); } }启动类就是标准的 Spring Boot 入口:
package com.example.springai.mysql; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringAiMysqlMcpApplication { public static void main(String[] args) { SpringApplication.run(SpringAiMysqlMcpApplication.class, args); } }配置到这里就齐了。模型侧走 TaoToken 统一 Key,MCP 侧走本地 MySQL 连接,两边职责清晰。接下来启动项目,做一次真实查询验证。
4. 启动项目并完成一次 MySQL 查询连通性验证
配置写完不代表通了,必须用一次真实请求验证整条链路:SpringAI 收到问题 → 模型决定调用 MySQL 工具 → MCP Server 执行 SQL → 结果回传。
4.1 设置环境变量并启动
先把 TaoToken Key 注入环境变量。Linux/macOS:
export TAOTOKEN_API_KEY="你的统一Key"Windows PowerShell:
$env:TAOTOKEN_API_KEY="你的统一Key"然后启动 Spring Boot 项目。观察控制台日志,重点看两处:一是 MCP 客户端是否成功启动mysql-mcp-server子进程,二是模型侧是否成功连上https://taotoken.net/api。如果这两处都有正常日志,说明配置被正确加载。
4.2 发起查询请求
假设你的数据库里有一张orders表,发一个自然语言问题:
curl "http://localhost:8013/mysql/query?question=查询orders表里最近10条订单记录"如果链路通了,你会看到流式返回的内容,里面包含模型对 SQL 的执行结果。第一次调用可能稍慢,因为 MCP Server 需要启动并建立数据库连接。
4.3 验证成功的判断标准
怎么算调通?三个信号同时出现:返回内容里包含真实数据(不是模型编的),MCP 日志里能看到 SQL 执行记录,数据库侧有对应查询。如果只返回了一段文字但没有数据,说明模型没有触发工具调用,需要检查defaultToolCallbacks是否注册成功。
实测下来,最容易出问题的是 MCP Server 的启动命令。Windows 上如果写成npx而不是npx.cmd,子进程会启动失败,但报错信息不一定直观。这一点在下一节展开。
5. 常见报错排查:401、local proxy failed、reading choices 与 OAuth
配置和验证过程中,有几类报错出现频率很高。逐个对照排查,能省不少时间。
5.1 401 Unauthorized
这个报错指向模型侧凭证。检查三件事:TAOTOKEN_API_KEY环境变量是否真的被注入(可以在启动日志里打印确认),base-url是否写成https://taotoken.net/api而不是带其他路径,Key 是否已过期或被删除。如果 Key 正确但依然 401,确认请求头里的认证格式是否符合 OpenAI 兼容规范。
5.2 local proxy failed
这个报错通常出现在 MCP 子进程启动阶段。原因可能是command写错,比如 Windows 下用了npx而不是npx.cmd;或者mysql-mcp-server没有安装成功,npx找不到包。解决办法:先在终端手动执行npx mysql-mcp-server,确认能启动,再回到 SpringAI 配置。
5.3 reading choices 相关报错
这类报错一般出现在解析模型响应时,说明返回结构不符合预期。常见原因是model填了一个 TaoToken 不支持的模型 ID,或者base-url指向了错误的地址。回到 TaoToken 控制台确认模型 ID,并确保base-url是https://taotoken.net/api。
5.4 OAuth 相关报错
如果你在 MCP 配置里看到 OAuth 字样,说明某个连接被要求走 OAuth 认证。MySQL MCP Server 本身走的是数据库账号密码,不需要 OAuth。出现这个报错通常是配置串了,检查stdio.connections下是否误加了认证相关字段。
5.5 三件套检查清单
无论哪种报错,先核对这三件套是否齐全且一致:
| 配置项 | 位置 | 示例值 |
|---|---|---|
| Base URL | application.yml 的spring.ai.openai.base-url | https://taotoken.net/api |
| API Key | 环境变量TAOTOKEN_API_KEY | 控制台创建的统一 Key |
| Model ID | application.yml 的spring.ai.openai.chat.options.model | gpt-4o |
这三项任何一项缺失或写错,都会导致模型侧调用失败。MCP 侧的数据库信息单独检查,不要和模型凭证混在一起。
6. 把统一 Key 用起来:后续接入与排障入口
配置跑通之后,你手里其实有了一套可复用的模式:模型访问走 TaoToken 统一 Key,工具调用走 MCP 本地连接。以后再加别的 MCP 服务,比如文件系统或 Redis,只需要在stdio.connections下新增一段,模型侧凭证完全不用动。
如果你在排障阶段需要重新生成 Key 或查看接入文档,直接去 API Keys 页面和接入文档:
- API Keys:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
- 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
想先验证模型对话是否正常,可以用模型对话页面快速测一条请求:
- 模型对话:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
如果你打算长期跑编码类或 Agent 类任务,Coding Plan 更适合持续调用:
- Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
最后说一个实际经验:MCP 的stdio连接在项目启动时就会拉起子进程,如果你本地 MySQL 没启动,SpringAI 启动阶段可能不会立刻报错,但第一次查询会失败。养成先确认数据库可连、再启动项目的习惯,能少走很多弯路。