news 2026/9/28 18:57:52

Spring AI 搭建 MCP 服务并实现概率计算:TaoToken 统一 Key 接入与配置骨架

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring AI 搭建 MCP 服务并实现概率计算:TaoToken 统一 Key 接入与配置骨架

1. 从「投档分数 500 对 480」说起:为什么要把概率计算塞进 MCP

先明确这篇要解决的事:在 Spring Boot + JDK17 环境里,用 Spring AI 搭一个 MCP 服务,把「概率计算」这类业务能力暴露成工具,再让 Trae 这类 AI 工具通过统一 Key 通道调用它。MCP 全称 Model Context Protocol,你可以把它理解成 AI 和外部程序之间的「标准插座」——AI 负责理解你说的话,插座负责把参数递给真正干活的 Java 方法。适合谁看:手里有传统业务系统、想改造成聊天式交互的后端同学;已经在用 Spring Boot 3.x、想试水 MCP 的开发者;以及需要在 Trae 里挂自建工具、又不想每个模型单独配 Key 的人。

我拿一个具体场景贯穿全文:用户说「我的投档分数为 500,预计院校要求投档最低分为 480,求概率」。这句话里有分数、有院校线,AI 不该自己瞎算,而应该解析出参数、调用我们写好的概率服务、把结果原样返回。整个过程分两半:Java 侧把方法注册成 MCP 工具,AI 工具侧通过配置连上这个服务。中间那层「统一 Key 接入」用 TaoToken 来做,好处是模型通道和 MCP 通道的凭证管理收在一处,换模型不用改业务代码。

下面按「环境准备 → 服务端骨架 → 统一 Key 配置 → 验证调用 → 排错」的顺序走,命令和配置都能直接抄。

2. 前置准备:JDK17、Spring Boot 3.2 与 TaoToken 统一 Key

2.1 版本对齐,别在这步翻车

Spring AI 的 MCP starter 对版本比较敏感,我实测下来这套组合最稳:

组件版本说明
JDK17MCP starter 要求 17+,别用 8 或 11
Spring Boot3.2.4与 spring-ai-bom 1.0.0-M7 匹配
spring-ai-bom1.0.0-M7统一管理 Spring AI 依赖版本
Trae1.2+支持手动添加 MCP Server

注意:MCP starter 有三个变体,选错传输方式会连不上。STDIO 用spring-ai-starter-mcp-server,Spring MVC 的 SSE 用spring-ai-starter-mcp-server-webmvc,WebFlux 的 SSE 用spring-ai-starter-mcp-server-webflux。本文走 STDIO,因为 Trae 本地拉起 jar 最省事。

2.2 拿一个统一 Key

到 TaoToken 控制台创建 API Key,这个 Key 同时用于模型对话和后续的通道配置。地址是 https://taotoken.net/api ,Key 生成后先存好,后面settings.json和config.toml都要填。如果你还没决定用哪个模型,可以先在模型对话页面试一条,确认通道通了再往下走:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=model_chat

提示:Key 只显示一次,建议直接写进本地环境变量或配置文件,别贴在聊天记录里。

3. 可复制配置:MCP 服务端骨架与统一 Key 片段

3.1 pom.xml 依赖

父工程用 dependencyManagement 锁版本,子模块只引实际用到的 starter。关键点:spring-ai-bom用import作用域,spring-ai-starter-mcp-server-webmvc放在dependencies里。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.hippo.spring.tools.ai</groupId> <artifactId>springboot-ai-demos</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.hippo.spring.tools.ai.springai.mcp</groupId> <artifactId>springai-mcp-server-demo</artifactId> <packaging>jar</packaging> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>1.0.0-M7</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.4</version> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.hippo.spring.tools.ai.springai.mcp.McpApp</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>17</source> <target>17</target> </configuration> </plugin> </plugins> </build> </project>

3.2 把概率计算注册成 @Tool

服务接口先定义清楚,参数和返回值都用 DTO 包住,AI 解析参数时才有明确结构。

public interface IJointExecItemService { ProbExecResult getJointExamItemCalculateResult(ValidChainParamsDTO validChainParamsDTO); }

实现类上用@Tool标注,description 写清楚这个工具干什么——AI 就是靠这句话决定要不要调用它。方法内部先做校验链(省批次线、院校控制线、分数限制、科目限制),校验不过直接返回错误类型,通过后再走概率计算。

@Tool(description = "获取统考计算概率结果值") @Override public ProbExecResult getJointExamItemCalculateResult(ValidChainParamsDTO validChainParamsDTO) { if (null == validChainParamsDTO) { return null; } jointScorePassingLineHandle.next(batchLineHandle); batchLineHandle.next(schoolControllerLineHandle); schoolControllerLineHandle.next(scoreLimitHandle); scoreLimitHandle.next(subjectLimitHandle); ValidChainResultDTO validChainResultDTO = jointScorePassingLineHandle.doValid(validChainParamsDTO); if (null != validChainResultDTO.getLineLimitType()) { return ProbExecResult.error(validChainResultDTO.getLineLimitType()); } return parallelCalculate.getProbability(validChainParamsDTO); }

3.3 工具配置类

用MethodToolCallbackProvider把多个 service 的@Tool方法一次性注册进去,这样新增工具只要加 bean 就行。

@Configuration public class ToolConfig { @Bean public ToolCallbackProvider userTools(IUserService userService, IJointExecItemService jointExecItemService) { return MethodToolCallbackProvider.builder() .toolObjects(userService, jointExecItemService) .build(); } }

3.4 统一 Key 的 settings.json 与 config.toml

Trae 侧手动添加 MCP Server,配置里 command 指向 JDK17 的 java,args 里带上 STDIO 开关和 jar 路径。这段是 MCP 服务本身的启动配置:

{ "mcpServers": { "hippo-mcp-server": { "command": "/Library/Java/JavaVirtualMachines/liberica-jdk-17.jdk/Contents/Home/bin/java", "args": [ "-Dspring.ai.mcp.server.stdio=true", "-Dspring.main.web-application-type=none", "-Dlogging.pattern.console=", "-jar", "/Users/yourname/target/springai-mcp-server-demo-1.0-SNAPSHOT.jar" ], "env": {} } } }

模型通道的 Key 单独放在 config.toml 里,和 MCP 配置解耦。这样换模型只改这一处,MCP 服务不用动:

# TaoToken 统一 Key 通道配置 [provider] name = "taotoken" api_base = "https://taotoken.net/api" api_key = "sk-你的统一Key" [model] default = "claude-sonnet" timeout_seconds = 60

注意:api_base用 https://taotoken.net/api ,不要带多余路径;Key 建议用环境变量注入,别硬编码进仓库。

4. 验证请求:一次概率计算工具调用的完整动作

4.1 打包并确认 jar 可独立启动

先mvn clean package,产物在 target 下。手动跑一次确认 STDIO 模式能起来:

java -Dspring.ai.mcp.server.stdio=true \ -Dspring.main.web-application-type=none \ -Dlogging.pattern.console= \ -jar target/springai-mcp-server-demo-1.0-SNAPSHOT.jar

启动后进程会挂起等待标准输入,这是正常的——STDIO 模式下它不监听端口,只等 Trae 通过管道发消息。

4.2 在 Trae 里挂载并检查工具注册

进入 Trae 主界面,右侧对话上方的设置 → MCP → 手动添加,把 3.4 的 JSON 贴进去保存。启动后应该能看到注册了三个服务(用户信息、计算配置查询、概率计算)。如果只显示两个,多半是ToolConfig里漏了某个 service。

4.3 创建自定义智能体并提问

选择「创建自定义智能体」,MCP 选刚加的自定义服务,工具全选后保存。然后选这个智能体、指定项目保存位置,输入:

我的投档分数为 500,预计的院校要求投档最低分为 480,求概率。

预期行为:智能体先分析语义,匹配到getJointExamItemCalculateResult工具,把 500 和 480 解析成ValidChainParamsDTO的字段,调用服务,返回概率值。如果它开始自己编答案而不是调工具,说明 description 写得不够明确,或者工具没注册成功。

4.4 用 curl 直连通道做旁路验证

想确认 Key 通道本身没问题,可以绕过 MCP 直接打一次模型接口:

curl -X POST https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer sk-你的统一Key" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet", "messages": [{"role": "user", "content": "ping"}] }'

返回正常说明 Key 和通道都通,问题就缩小到 MCP 配置层了。

5. 本篇常见错排查清单

5.1 工具没被调用,AI 自己编答案

最常见。先看 Trae 的 MCP 面板里工具数量对不对;再看@Tool的 description 是不是太模糊,比如写成「计算」就不如「获取统考计算概率结果值」明确。参数 DTO 的字段名也要语义清晰,AI 靠字段名做映射。

5.2 启动报 web-application-type 冲突

STDIO 模式下必须加-Dspring.main.web-application-type=none,否则 Spring Boot 会尝试起 Web 容器,和 STDIO 抢标准流。如果你用的是 webmvc 变体走 SSE,则反过来不能加这个参数。

5.3 java 命令找不到或版本不对

command里写绝对路径,别依赖 PATH。macOS 上可以用/usr/libexec/java_home -v 17查真实路径。Windows 下路径要转义反斜杠。

5.4 概率返回 null 或错误类型

检查校验链是否被正确串联,doValid返回的lineLimitType不为空时会直接返回 error。另外确认parallelCalculate.getProbability对边界值(比如分数刚好等于线)有处理,否则会出现除零或空指针。

5.5 Key 通道 401

确认api_base是 https://taotoken.net/api 且没有多余斜杠;Key 有没有过期;请求头是不是Authorization: Bearer。如果 MCP 服务和模型通道用了两个 Key,检查是不是混用了。

6. 接下来怎么走:把通道和工具都收进统一管理

到这一步,Java 侧的概率计算已经能通过 MCP 被 Trae 调用了,模型通道也走统一 Key。下一步建议做两件事:一是把更多业务方法加上@Tool注册进来,让智能体能组合调用;二是把 Key 和模型配置集中管理,避免每个工具单独配一套凭证。需要长期跑编码或 Agent 任务的,可以看 Coding Plan 的额度方案:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=coding_plan

接入文档里有完整的参数说明和示例,配置卡住时对着查最快:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=doc

Key 管理入口在这里,新建或轮换都从这进:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=api_keys

如果你用的是 Claude Code 这类终端工具,Anthropic 兼容通道的配置方式单独整理过:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=claude_code

最后留一个我踩过的坑:STDIO 模式下日志千万别往标准输出打,-Dlogging.pattern.console=这行就是干这个的,去掉它日志会污染协议流,表现为 Trae 一直连不上但进程明明活着。

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

CodeX 团队推广路径与培训方案:用 TaoToken 统一 Key 打通组织接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 18:56:12

WeWrite架构:Prompt负责判断、Python负责确定性的3层解耦设计

WeWrite架构&#xff1a;Prompt负责判断、Python负责确定性的3层解耦设计 【免费下载链接】wewrite 公众号内容全流程 Skill&#xff0c;从热点抓取到微信草稿箱&#xff0c;一句话跑完整条内容管道 项目地址: https://gitcode.com/gh_mirrors/wew/wewrite WeWrite 架构…

作者头像 李华
网站建设 2026/9/28 18:55:58

WinDbg蓝屏分析实战:从DMP转储文件定位崩溃驱动

看到蓝屏&#xff0c;大多数人第一反应是重启&#xff0c;坏了就重装系统。但如果你愿意花半小时&#xff0c;用 WinDbg 打开蓝屏生成的 DMP 文件&#xff0c;你会发现每次蓝屏其实都留了一份“遗书”。这篇文章不讲玄学&#xff0c;只讲实操&#xff1a;如何从系统里拿到 DMP …

作者头像 李华
网站建设 2026/9/28 18:55:29

openclaw安装实战:Win10(WSL)与Ubuntu24双环境配置TaoToken接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 18:55:12

详解 Cursor 核心能力:代码库索引、AI 审查重构、隐私模式、模型选择、自定义 Rules、外部文档知识库与 MCP 服务器配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华