☰
SpringBoot MCP 实战:让 AI 大模型安全调用你的业务逻辑,TaoToken 统一 Key 接入
2026/10/4 19:40:00 网站建设 项目流程

1. 为什么要把 SpringBoot 业务逻辑交给大模型调用

很多团队手里已经有一套跑得好好的 SpringBoot 服务,里面封装了订单查询、客户检索、库存校验这些核心业务逻辑。与此同时,大模型工具链(Claude Code、Cursor、Cline 这类客户端)越来越能干,但它们的默认能力只停留在“读写文件、跑命令”这一层,根本碰不到你数据库里的真实数据。于是问题就来了:能不能让大模型在受控权限下,直接调用我 SpringBoot 里已经写好的方法,而不是让它瞎猜?

答案就是 MCP(Model Context Protocol)。你可以把它理解成一套“给 AI 用的 USB 接口标准”:你的 SpringBoot 应用是设备,MCP Server 是那根数据线,AI 客户端是主机。只要按协议把业务方法注册成 Tool,AI 就能像调用本地函数一样调用你的业务逻辑,而且调用范围完全由你决定——你注册哪个方法,它才能碰哪个方法。

这篇要解决的核心场景很具体:你有一个已有的 SpringBoot 服务,想通过 MCP 协议把业务能力暴露出去,让 AI 大模型在受控权限下直接调用内部逻辑,同时用 TaoToken 的统一 Key 完成端到端验证。适合谁看?有 SpringBoot 基础、想接入大模型工具链的后端同学,以及正在做 AI Agent 落地、需要把内部系统接进模型工具链的工程师。

我试过把 CRM 查询、订单状态这类只读逻辑先暴露出去,实测下来最稳的路径是:SpringBoot 侧用 Spring AI 的 MCP Server starter 注册 Tool,客户端侧用 TaoToken 统一 Key 接入模型,两边各管各的鉴权,互不越界。下面从依赖配置一路写到端到端验证,每一步都能直接抄。

2. TaoToken 统一 Key 接入前置准备

在动手写 MCP Server 之前,先把模型侧的入口理清楚。MCP 解决的是“AI 怎么调用你的业务”,但 AI 本身得先能跑起来、能连上模型,这一步用 TaoToken 来做统一接入最省事。它的作用是给你一个统一的 API 入口和 Key,不用在多个模型供应商之间来回切换配置,客户端里填一次 Base URL 和 Key 就能用。

你需要准备三样东西,我把它列成表格,方便对照:

项目值说明
Base URLhttps://taotoken.net/api所有客户端统一填这个
API Key在控制台创建形如sk-xxxx,只显示一次
Model ID按需选择例如claude-sonnet-4-5这类模型标识

获取 Key 的路径很直接:打开官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,进控制台,在 API Keys 页面新建一个 Key。创建完立刻复制保存,页面刷新后就看不到完整值了,这是很多人第一次踩的坑。

注意:Key 属于敏感凭证,不要写进前端代码、不要提交到 Git 仓库。建议放在环境变量或客户端的本地配置里,MCP Server 侧如果需要调用模型,也走环境变量注入。

如果你只是想先验证模型通不通,可以直接用模型对话页面发一条消息试试:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。能正常返回,说明 Key 和 Base URL 没问题,再往下做 MCP 接入就少一个变量。

对于长期做编码和 Agent 的场景,可以考虑 Coding Plan,它更适合高频调用:https://taotoken.net/coding-plan?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= ,API Keys 管理页在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。这几步做完,模型侧的前置就算齐了。

3. SpringBoot MCP Server 依赖配置与工具注册

这一节是全文技术核心,篇幅给足。目标是把一个普通 SpringBoot 应用改造成 MCP Server,暴露两个业务方法:查询全部客户、按姓名查客户。先看依赖。

在pom.xml里加 Spring AI 的 MCP Server starter。如果你用 STDIO 传输(本地客户端直接拉起 jar),用下面这个:

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

如果你想让客户端通过 HTTP 远程连接(SSE 传输),换成 WebMVC 版本:

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

两者区别很关键:STDIO 是本地进程通信,客户端负责启动你的 jar,适合个人开发机;SSE 是网络通信,你的服务部署在哪都行,客户端填个 URL 就能连,适合团队共享。选哪个取决于你的部署形态,不是随便挑的。

接着配置application.properties。STDIO 模式下要关掉 Web 容器,否则启动会冲突:

spring.application.name=crm-mcp-server spring.main.web-application-type=none spring.ai.mcp.server.name=${spring.application.name} spring.ai.mcp.server.version=1.0.0

如果是 SSE 模式,把web-application-type=none去掉,服务启动后会自动发布/sse端点。

然后定义数据模型。用 Java record 最干净,不可变、自带构造和访问器:

package com.example.mcpserver; public record Customer(String id, String name, String email, String phone, String company) {}

核心在 Service 层。@Tool注解负责把方法暴露给 MCP 框架,name是 AI 看到的工具名,description是 AI 判断何时调用的依据,写清楚很重要:

package com.example.mcpserver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Service; import jakarta.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; @Service public class CustomerService { private static final Logger log = LoggerFactory.getLogger(CustomerService.class); private final List<Customer> customers = new ArrayList<>(); @Tool(name = "get_customers", description = "获取 CRM 系统中的全部客户列表") public List<Customer> getCustomers() { log.info("MCP 调用: get_customers, 返回 {} 条", customers.size()); return customers; } @Tool(name = "get_customer_by_name", description = "根据姓名查询单个客户信息") public Customer getCustomerByName(String name) { log.info("MCP 调用: get_customer_by_name, name={}", name); return customers.stream() .filter(c -> c.name().equals(name)) .findFirst() .orElse(null); } @PostConstruct public void init() { customers.addAll(List.of( new Customer("1", "张三", "zhangsan@example.com", "13800138001", "示例科技A"), new Customer("2", "李四", "lisi@example.com", "13800138002", "示例科技B"), new Customer("3", "王五", "wangwu@example.com", "13800138003", "示例科技C") )); } }

最后在主类里把 Service 注册成 ToolCallback。ToolCallbacks.from()会自动扫描所有@Tool方法,不用一个个手写:

package com.example.mcpserver; import org.springframework.ai.tool.ToolCallback; import org.springframework.ai.tool.ToolCallbacks; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import java.util.List; @SpringBootApplication public class McpServerApplication { public static void main(String[] args) { SpringApplication.run(McpServerApplication.class, args); } @Bean public List<ToolCallback> crmTools(CustomerService customerService) { return List.of(ToolCallbacks.from(customerService)); } }

到这里 Server 侧就完成了。注意一个安全原则:只暴露只读或幂等的方法,写操作(下单、扣库存)要么不暴露,要么在方法内部再做一层权限校验。MCP 的“受控”不是自动的,是你注册什么它才能调什么。

4. 客户端配置与端到端调用验证

Server 写完了,得让 AI 客户端连上它。这里分两种传输方式讲,配置片段都能直接复制。

先说 STDIO 方式。先打包:

mvn clean package -DskipTests

产物在target/目录下,比如crm-mcp-server-0.0.1-SNAPSHOT.jar。然后在客户端(以 Cursor 为例)的 MCP 配置里加:

{ "mcpServers": { "crm-demo-mcp": { "command": "java", "args": ["-jar", "/absolute/path/to/crm-mcp-server-0.0.1-SNAPSHOT.jar"] } } }

路径一定用绝对路径,相对路径在客户端拉起进程时经常找不到 jar,这是高频坑。

再说 SSE 方式。服务正常启动后监听 8080,客户端配置改成 URL 形式:

{ "mcpServers": { "crm-demo-mcp": { "url": "http://localhost:8080/sse" } } }

如果你用的是 Cline 或 Claude Code 这类客户端,配置结构类似,核心三件套是 Base URL、Key、Model ID。以模型接入为例,客户端里填:

{ "baseUrl": "https://taotoken.net/api", "apiKey": "sk-你的Key", "model": "claude-sonnet-4-5" }

MCP Server 的配置和模型配置是两套东西,别混在一起:前者告诉客户端“去哪调用业务工具”,后者告诉客户端“用哪个模型来思考”。

配置保存后重启客户端,在工具列表里应该能看到get_customers和get_customer_by_name。然后发一条自然语言指令验证:

使用 MCP 服务器,获取所有 CRM 客户信息。

预期结果是模型调用get_customers,返回三条客户记录。再试一条精确查询:

使用 MCP 服务器,查找姓名为"张三"的客户信息。

模型应该调用get_customer_by_name,参数name=张三,返回对应记录。同时你的 SpringBoot 控制台会打印MCP 调用: get_customer_by_name, name=张三,这条日志就是端到端打通的铁证。如果日志没打印,说明请求根本没到 Server,问题在客户端配置或进程启动;如果日志打印了但客户端没结果,问题在返回序列化。

5. 常见报错排查对照

接入过程里最容易卡在几个固定报错上,我按真实遇到的整理成对照表,方便你直接定位。

报错/现象根因处理方式
401 UnauthorizedKey 错误或未带检查apiKey是否为控制台新建的完整值,注意别带空格
local proxy failed客户端网络配置异常检查 Base URL 是否为https://taotoken.net/api,不要多加斜杠或路径
reading choices解析失败返回体非预期 JSON确认 Model ID 拼写正确,换一个模型标识重试
OAuth 相关报错客户端走了错误的鉴权模式改用 API Key 模式,不要启用 OAuth 流程
工具列表为空Server 未注册 ToolCallback检查@Bean是否返回了ToolCallbacks.from(...)
客户端连不上 SSE端口或路径不对确认服务监听 8080 且端点为/sse

重点说两个。401和local proxy failed基本都出在模型接入这一层,跟 MCP Server 无关,先把模型对话页面调通再排查 MCP。reading choices通常是 Model ID 写错,客户端拿到的是错误响应体,解析自然失败。

还有一个隐蔽的坑:STDIO 模式下如果application.properties没关 Web 容器,jar 启动会卡住或直接退出,客户端表现为“连接超时”。这时候去看 Server 的启动日志,如果有 Tomcat 相关输出,就是这个问题。

如果你用的是 Codex 的auth.json或 CC Switch 这类配置管理工具,记住三件套必须齐全:Base URL、Key、Model ID,缺一个都会报鉴权或路由错误。Cline 的 MCP 配置同理,Server 配置和模型配置分开写,别把 MCP 的 command 塞进模型配置里。

6. 把业务逻辑安全交给 AI 的落地建议

走到这里,你已经有一个能跑的 SpringBoot MCP Server,AI 能通过 TaoToken 统一 Key 接入后调用你的业务方法。最后给几条实战建议,都是踩过坑总结的。

第一,权限边界靠“注册粒度”控制,不靠模型自觉。你只注册get_customers,AI 就永远调不到删除方法。写操作要暴露的话,在方法内部加参数校验和操作日志,别指望模型帮你把关。

第二,Tool 的description要写成人话。模型是根据描述判断该不该调用的,写“查询客户”比写“customer query method”命中率高得多。参数名也要语义化,name就比n好。

第三,STDIO 适合本地开发,SSE 适合团队共享。本地调试用 STDIO 快,但部署到服务器给多人用时,SSE 的 URL 接入更省事,客户端不用装 jar。

第四,模型侧和业务侧分开排障。模型不通看401/local proxy failed,业务不通看 Server 日志有没有打印调用记录。两边日志一对,问题立刻定位。

需要长期跑编码和 Agent 任务的,Coding Plan 的额度模型更适合高频场景:https://taotoken.net/coding-plan?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= ,Key 管理在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。先把只读查询跑通,再逐步放开更多业务能力,这条路最稳。

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

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

立即咨询