news 2026/10/4 15:03:58

基于SpringBoot开发一个MCP Server:把本地工具接入TaoToken统一Key通道

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于SpringBoot开发一个MCP Server:把本地工具接入TaoToken统一Key通道

1. 为什么要把本地工具塞进 MCP Server 再统一走一个 Key

MCP Server 说白了就是一层“工具插座”:AI 客户端(Claude Code、Cursor、Cline 这类)通过标准协议问它“你有哪些工具”,它把本地方法暴露出去,客户端决定什么时候调、传什么参数。SpringBoot 写 MCP Server 的好处是,你团队里现成的 Service、Mapper、鉴权、日志、事务全都能直接复用,不用为了接 AI 再单独起一套 Python 脚本。

但真正落地时,麻烦往往不在“工具怎么写”,而在“模型从哪来”。本地工具跑通了,客户端要调模型,你得给每个客户端配一遍 Base URL、Key、模型名;换一个模型又要改一轮配置。我试过同时维护 Cursor、Cline、Claude Code 三套配置,改一次 Key 要翻三个文件,特别容易漏。

所以这篇的思路是:SpringBoot 负责把本地工具用 MCP 协议暴露出来,模型通道统一收敛到 TaoToken 的 Key/API 上。TaoToken 是一个兼容 OpenAI/Anthropic 风格接口的模型聚合通道,你拿一个 Key 就能在多个客户端里调不同模型,MCP Server 本身不碰模型,只负责工具;客户端那边统一填 TaoToken 的地址和 Key。这样职责清晰:工具归工具,模型归模型。

适合谁看:有 SpringBoot 基础、想把公司内部接口(员工查询、订单、工单、知识库)接给 AI 客户端的后端同学;或者已经在用 Cursor/Cline,但被多套 Key 配置搞烦的人。下面从依赖开始,一步步给可复制的代码和配置。

2. 前置准备:JDK、依赖与 TaoToken Key 通道

先说环境。JDK 必须 17 及以上,Spring AI 的 MCP starter 对版本有硬要求,JDK 8 直接编译不过。IDEA 用 2023 以后的版本,Maven 3.8+。我本地是 JDK 21 + Spring Boot 3.3.x,跑下来没问题。

Maven 依赖这块要选对 starter。Spring AI 提供了三个 MCP Server 包,协议支持不一样,选错了要么起不来要么客户端连不上:

starter 包名支持的传输协议适用场景
spring-ai-starter-mcp-serverstdio本地进程间通信,客户端拉起进程
spring-ai-starter-mcp-server-webmvcsseHTTP 远程通信,Web 环境
spring-ai-starter-mcp-server-webfluxsse响应式栈,WebFlux 项目

我们做的是能被 Cursor、Cline 通过 URL 连的远程 Server,所以用 webmvc 这个。pom 里加:

<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId> <version>1.0.0</version> </dependency>

注意版本号,Spring AI 1.0.0 是 GA 版本,MCP 相关 API 在这个版本才稳定。如果你用的是里程碑版本,@Tool注解的包路径可能不一样,建议直接对齐 1.0.0。

然后是 TaoToken 的 Key。打开 https://taotoken.net/api 对应的控制台,进 API Keys 页面创建一个 Key,复制出来先存好。这个 Key 后面要填到客户端的模型配置里,不是填到 SpringBoot 里——MCP Server 本身不调模型,所以它不需要这个 Key。这一点很多人第一次会搞混:以为 MCP Server 要配模型 Key,其实模型调用发生在客户端侧,MCP Server 只提供工具。

顺手把接入文档也开一个标签页:https://taotoken.net/doc ,里面写了 Base URL 和模型 ID 的对应关系,等会儿配客户端要用。Base URL 统一是https://taotoken.net/api,注意不要带 UTM 参数,客户端配置里带参数有的会解析失败。

3. 可复制配置:application.yml 与 MCP 工具注册

先写application.yml。MCP Server 的配置全在spring.ai.mcp.server下面:

server: port: 18888 spring: ai: mcp: server: name: local-tool-server version: 1.0.0 stdio: false sse-endpoint: /sse enabled: true type: SYNC

几个关键点解释一下。stdio: false是禁用标准输入输出协议,因为我们走 HTTP;sse-endpoint: /sse指定 SSE 端点路径,客户端就连http://127.0.0.1:18888/sse;type: SYNC表示同步工具调用,简单场景够用,如果你工具里有耗时操作再考虑 ASYNC。端口我用了 18888,你按自己习惯改,别和现有服务冲突。

接下来是工具类。用@Tool注解标记方法,注解目前只支持方法维度,类上标没用。写一个员工服务的例子:

@Service public class EmployeeServiceImpl implements EmployeeService { @Autowired private EmployeeMapper employeeMapper; @Override @Tool(name = "getEmployeeInfo", description = "根据员工ID获取员工详细信息") public Employee getEmployeeInfo(String employeeId) { return employeeMapper.selectById(employeeId); } @Override @Tool(name = "getEmployeeList", description = "获取全部员工列表") public List<Employee> getEmployeeList() { return employeeMapper.selectList(null); } @Override @Tool(name = "addEmployee", description = "新增一名员工,参数为员工对象") public boolean addEmployee(Employee employee) { return employeeMapper.insert(employee) > 0; } @Override @Tool(name = "updateEmployee", description = "更新员工信息,按ID匹配") public boolean updateEmployee(Employee employee) { return employeeMapper.updateById(employee) > 0; } }

description一定要写清楚,模型是靠这个判断什么时候调哪个工具的。写“获取员工信息”就比写“查询”强很多,参数含义也尽量在描述里点出来。

然后是注册配置类,把工具对象交给 MCP Server:

@Configuration public class McpConfig { @Bean public ToolCallbackProvider toolCallbackProvider(EmployeeService employeeService) { return MethodToolCallbackProvider.builder() .toolObjects(employeeService) .build(); } }

toolObjects可以传多个对象,比如你还有 OrderService、TicketService,逗号隔开一起塞进去,它们上面的@Tool方法都会被注册。启动 SpringBoot,控制台会打印注册的工具数量,看到 4 个就对了。

4. 验证请求:curl 拉工具列表 + 客户端调用链路

服务起来后,先别急着开客户端,用 curl 验证 SSE 端点通不通:

curl -N http://127.0.0.1:18888/sse

-N是关闭缓冲,你会看到一条event: endpoint的数据流,里面带一个 sessionId,类似:

event: endpoint data: /mcp/message?sessionId=8f3a...

这说明 SSE 通道建立成功。接着用这个 sessionId 发一个初始化请求:

curl -X POST "http://127.0.0.1:18888/mcp/message?sessionId=8f3a..." \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {} }'

返回里应该能看到getEmployeeInfo、getEmployeeList这些工具名和它们的参数 schema。这一步过了,说明 MCP Server 侧完全正常。

然后配客户端。以 Cursor 为例,在 MCP 配置里加:

{ "mcpServers": { "local-tool-server": { "url": "http://127.0.0.1:18888/sse", "type": "sse" } } }

刷新后能看到 4 个 tools 挂上来了。但这时候模型还没配。Cursor 的模型设置里,把 Base URL 填https://taotoken.net/api,API Key 填你在控制台建的那个,模型 ID 按文档里写的填(比如claude-sonnet-4-5这类)。三件套齐了:Base URL + Key + Model ID,缺一个都会报错。

配完在对话框里问“帮我查一下员工 ID 为 1001 的信息”,模型会先调getEmployeeInfo,拿到结果再组织语言回复。整条链路是:客户端 → TaoToken 通道 → 模型 → 决定调工具 → 回到本地 MCP Server → 查数据库 → 结果回传。你可以在 SpringBoot 日志里看到工具被调用的记录,确认链路真的走通了。

5. 常见报错排查:401、local proxy failed 与 OAuth

配的时候踩过几个坑,列出来对照。

401 Unauthorized。这个基本是 Key 的问题。检查三处:Key 有没有复制全(前后别带空格)、Base URL 是不是https://taotoken.net/api(别写成带/v1或带 UTM 的)、客户端里模型 ID 和 Key 是不是配在同一处。如果 Key 是在别的项目里用的,确认它没被删或者额度没用完。

local proxy failed / connection refused。客户端连不上 MCP Server。先确认 SpringBoot 真的起来了,curl http://127.0.0.1:18888/sse有没有响应。如果服务在远程机器上,127.0.0.1要换成实际 IP,并且防火墙放行端口。还有一种情况是客户端配置里type写成了stdio,但 URL 是 HTTP 的,协议对不上也会报这个。

reading choices 相关报错。这通常是模型返回格式和客户端预期不一致,多半是 Base URL 或模型 ID 填错了,客户端拿到的不是标准响应。回到 TaoToken 文档核对模型 ID 拼写,确认 Base URL 没多斜杠。

OAuth 报错。有些客户端默认走 OAuth 流程,但 TaoToken 用的是 API Key 鉴权。在客户端设置里找“使用 API Key”或“自定义 Header”的选项,把鉴权方式切成 Key,别让它去走 OAuth。

工具列表为空。SSE 连上了但看不到 tools,检查McpConfig里的toolObjects有没有真的注入进来,@Tool注解的包是不是org.springframework.ai.tool.annotation.Tool。注解导错包是最常见的,导成别的同名注解就不会被扫描。

排查顺序建议:先 curl 确认 Server 活着,再看客户端 MCP 连接状态,最后查模型 Key 配置。三段分开定位,比一股脑改配置快得多。

6. 把通道固定下来:长期编码与 Agent 场景的配置建议

工具和模型都跑通之后,建议把配置固定成模板,别每次重配。MCP Server 这边,application.yml里的端口、端点路径、工具注册类基本不变,团队里可以抽成一个公共 starter,各个业务模块只写自己的@Tool方法。

模型通道这边,如果你只是偶尔验证一下工具调用,用模型对话页面手动试就行:https://taotoken.net/model-chat 。但如果是长期在 Cursor、Cline 里写代码、跑 Agent,建议用 Coding Plan,把 Key 和额度统一管理,省得每个客户端单独配:https://taotoken.net/coding-plan 。

还有一个实用技巧:把 MCP Server 的工具描述当成接口文档来维护。模型选错工具,十有八九是description写得太模糊。我习惯在描述里带上参数示例,比如“根据员工ID获取信息,ID 形如 1001”,模型调用准确率会明显提升。工具多了以后,按业务域拆成多个ToolCallbackProviderBean,也方便排查是哪个域的工具出了问题。

最后,Key 别硬编码在代码或提交到仓库里。客户端配置里的 Key 用环境变量注入,SpringBoot 侧压根不存模型 Key,这样即使代码泄露也不影响通道安全。整套跑下来,本地工具通过标准协议暴露,模型调用统一走一个 Key,换模型只改客户端一处,维护成本能降不少。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/4 15:03:06

基于springboot + vue学生宿舍信息管理系统(源码+数据库+文档)

学生宿舍信息管理系统 目录 基于springboot vue学生宿舍信息管理系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 基于springboot vue学生宿舍信息管理系统 一、前…

作者头像 李华
网站建设 2026/10/4 15:02:58

基于MCP协议为IoT功耗计构建AI可调用的服务端

1. 从一个"反直觉"的痛点说起&#xff1a;为什么我要让 AI 去读功耗计 做 IoT 硬件开发的朋友大概率都经历过这种场景&#xff1a;板子跑起来了&#xff0c;功能也正常&#xff0c;但续航就是不对劲。你怀疑是某个外设在偷偷耗电&#xff0c;于是搬出功耗计&#xff…

作者头像 李华
网站建设 2026/10/4 15:02:54

单视频三维实时重构支撑水库大坝、闸站、泵站立体监控技术方案

技术权属说明&#xff1a;水工建筑物单视频三维实景重构、坝体闸站立体监测、泵站设备空间态势感知、水利构筑物形变智能识别、水利枢纽立体运维技术体系由华东师范大学浙江普陀时空大数据研究院团队原创研发&#xff0c;镜像视界&#xff08;浙江&#xff09;科技有限公司为唯…

作者头像 李华
网站建设 2026/10/4 15:01:53

Python字典入门:键值对、遍历与嵌套实战

学完列表和元组&#xff0c;很多刚开始学 Python 的同学都会卡在同一个地方&#xff1a;数据确实存进去了&#xff0c;但想取某个字段的时候&#xff0c;还得掰着手指头数“这个值是第几个”。举个例子&#xff0c;你在列表里存了一个学生信息&#xff0c;["001", &q…

作者头像 李华
网站建设 2026/10/4 15:01:07

人体跌倒视频数据集

摘要&#xff1a;该数据集面向基于计算机视觉的人体跌倒检测研究&#xff0c;由多个公开跌倒检测数据源整合构建&#xff0c;包含跌倒与非跌倒两类视频样本&#xff0c;并配套人体姿态关键点数据&#xff0c;可用于视频行为识别、人体姿态分析和智能监控等研究任务。数据集概述…

作者头像 李华