☰
使用 Spring AI 创建 MCP 服务器:TaoToken 统一 Key 接入与配置骨架
2026/9/27 16:57:27 网站建设 项目流程

1. 为什么要在 Spring Boot 里手搓一个 MCP 服务器

如果你最近在折腾 AI 编码助手,大概率听过 MCP(Model Context Protocol)这个词。简单说,它是一套让大模型能"调用外部工具"的标准化协议:模型本身不知道你公司内部的订单表结构,也不知道你本地那台测试机的部署脚本长什么样,但只要把这些能力包装成 MCP 工具,模型就能在对话里主动调用它们。Spring AI 从 1.0 开始提供了spring-ai-starter-mcp-server,让你用几个注解就能把普通的 Spring Bean 变成模型可调用的工具。

这篇要解决的问题很具体:在 Spring Boot 项目里用 Spring AI 搭一个能跑起来的 MCP 服务器,同时把模型调用的出口统一收敛到 TaoToken 的 Key/API 通道上,避免每个工具、每个客户端各配一套密钥。适合谁?有 Java/Spring Boot 基础、想让本地 AI 助手接入自己业务数据的后端同学。我会给出settings.json和config.toml两份配置骨架,再演示启动后怎么验证 MCP 服务真的可用,而不是"看起来启动了其实工具没注册上"。

MCP 服务器本身不负责推理,它只暴露工具;真正干活的是背后的模型。所以"统一 Key"这件事的意义在于:你的 MCP 客户端(比如编码插件、Agent 框架)在调用模型时,走的是同一个 TaoToken 通道,换模型、换额度、看用量都在一处,不用在五六个配置文件里改 base_url。

2. TaoToken 前置:把 Key 和通道先备好

在写代码之前,先把模型侧的通道准备好,否则后面验证工具调用时会卡在"模型请求发不出去"。

第一步,打开官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 注册账号。注册流程很常规,邮箱加密码即可,这里不展开。

第二步,进控制台创建 API Key。地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,在 API Keys 页面点新建,复制出来的 Key 形如sk-xxxxxxxx,只显示一次,先存到密码管理器里。API Keys 管理页直达:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。

第三步,确认 API 基地址。TaoToken 的 API 入口是 https://taotoken.net/api ,注意这个地址不带任何查询参数,配置里直接写它就行。它兼容 OpenAI 风格的/v1/chat/completions,所以 Spring AI 的 OpenAI starter 和大多数 MCP 客户端都能直接对接。

注意:Key 属于敏感凭据,不要提交到 Git 仓库。本地开发建议用环境变量TAOTOKEN_API_KEY注入,配置文件里写占位符。

如果你只是想先验证模型能不能通,可以打开模型对话页 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite 发一句话试试,确认 Key 有效再往下走。长期跑编码类 Agent 的话,Coding Plan 页面 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 有更划算的额度方案,这个后面按需看。

3. 可复制配置:settings.json 与 config.toml 骨架

MCP 生态里有两类配置文件最常见:一类是客户端侧的settings.json(很多编码插件、桌面客户端用它声明要连哪些 MCP 服务器),另一类是config.toml(部分 Agent 框架和 CLI 工具用它)。下面两份骨架你可以直接抄,改路径和 Key 即可。

3.1 settings.json:声明 MCP 服务器与模型通道

{ "mcpServers": { "my-spring-mcp": { "command": "/usr/lib/jvm/java-21-openjdk/bin/java", "args": [ "-jar", "/home/dev/mymcpserver/target/mymcpserver-0.0.1-SNAPSHOT.jar" ], "env": { "SPRING_AI_MCP_SERVER_NAME": "my-spring-mcp", "SPRING_AI_MCP_SERVER_VERSION": "0.0.1" } } }, "model": { "provider": "openai-compatible", "baseUrl": "https://taotoken.net/api", "apiKey": "${TAOTOKEN_API_KEY}", "model": "gpt-4o-mini" } }

几个关键点。command必须是 java 可执行文件的绝对路径,用which java查一下,别写java两个字,很多客户端不解析 PATH。args里的 jar 路径同理,用绝对路径。env块把服务器名和版本透传给 Spring 应用,这样application.properties里可以不写死。model块就是统一 Key 的落点:baseUrl指向 TaoToken 的 API 入口,apiKey用环境变量引用,避免明文。

3.2 config.toml:Agent 框架侧的等价配置

[mcp_servers.my_spring_mcp] command = "/usr/lib/jvm/java-21-openjdk/bin/java" args = ["-jar", "/home/dev/mymcpserver/target/mymcpserver-0.0.1-SNAPSHOT.jar"] startup_timeout_sec = 20 tool_timeout_sec = 60 [mcp_servers.my_spring_mcp.env] SPRING_AI_MCP_SERVER_NAME = "my-spring-mcp" SPRING_AI_MCP_SERVER_VERSION = "0.0.1" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY" wire_api = "chat"

startup_timeout_sec给 20 秒比较稳,Spring Boot 冷启动加 JVM 初始化有时会超过默认的 10 秒,超时了客户端会以为服务器挂了。wire_api = "chat"表示走 chat completions 协议,兼容性最好。

3.3 Spring Boot 侧 application.properties

spring.main.web-application-type=none spring.ai.mcp.server.name=${SPRING_AI_MCP_SERVER_NAME:my-spring-mcp} spring.ai.mcp.server.version=${SPRING_AI_MCP_SERVER_VERSION:0.0.1} spring.main.banner-mode=off logging.pattern.console=

web-application-type=none是因为 STDIO 传输不需要 Web 容器,起了反而占端口。logging.pattern.console=置空很关键:STDIO 模式下 stdout 是协议通道,任何一行日志混进去都会让客户端解析失败,这是新手最容易踩的坑。

3.4 pom.xml 依赖

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

Spring AI 的版本用 BOM 管理,在dependencyManagement里引spring-ai-bom即可,别单独写版本号,容易和 starter 对不上。

4. 工具类与启动验证:确认 MCP 服务真的可用

配置写完了,得让工具真正注册进去,并且验证客户端能发现它们。

4.1 定义两个工具

@Service public class ArtistService { private final List<Artist> artists = new ArrayList<>(); @Tool(name = "get_artists", description = "获取我喜爱的艺术家完整列表") public List<Artist> getArtists() { return artists; } @Tool(name = "search_artist", description = "按名称搜索单个艺术家") public Artist searchArtist(String name) { return artists.stream() .filter(a -> a.name().equalsIgnoreCase(name)) .findFirst() .orElse(null); } @PostConstruct public void init() { artists.addAll(List.of( new Artist("Bruce Springsteen"), new Artist("JJ Johnson") )); } }

@Tool的description是给模型看的,写清楚"这个工具干什么、参数是什么",模型靠它决定调不调。searchArtist的参数name会被自动映射成 JSON Schema 里的 required 字段。

4.2 注册工具回调

@SpringBootApplication public class MyMcpServerApplication { public static void main(String[] args) { SpringApplication.run(MyMcpServerApplication.class, args); } @Bean public ToolCallbackProvider mcpTools(ArtistService artistService, SongService songService) { return MethodToolCallbackProvider.builder() .toolObjects(artistService, songService) .build(); } }

漏了这个 Bean,工具类上的@Tool不会被扫描,客户端连上后会显示"找到 0 个工具"。

4.3 构建并启动

mvn clean verify java -jar target/mymcpserver-0.0.1-SNAPSHOT.jar

启动后进程会挂起等待 STDIO 输入,这是正常的,别以为卡死了。

4.4 验证工具被发现

在客户端的 MCP 设置里点"测试连接并获取工具",成功时按钮文案会变成类似"连接成功!找到 4 个工具"。如果显示 0 个,回到 4.2 检查 Bean 是否注册。这一步过了,再发一句"给我一个我喜爱的艺术家列表",模型应该会请求调用get_artists,客户端弹出人工确认,批准后返回结果。整个链路通了,说明 MCP 服务器 + TaoToken 通道都正常。

5. 本篇常见错排查

报错一:客户端连上但工具数为 0。九成是ToolCallbackProviderBean 没注册,或者@Tool注解加在了 private 方法上。检查方法可见性,必须是 public。

报错二:客户端报 "Failed to parse server response"。大概率是 stdout 混入了日志。确认logging.pattern.console=为空,并且没有其他库往 System.out 打印。Spring Boot 的 banner 也要关掉。

报错三:启动超时。把客户端的startup_timeout_sec调到 20 以上,或者给 JVM 加-Xshare:auto加速启动。首次运行还要下载依赖,慢是正常的。

报错四:模型请求 401。检查TAOTOKEN_API_KEY环境变量是否在当前 shell 生效,echo $TAOTOKEN_API_KEY看一眼。另外确认baseUrl写的是https://taotoken.net/api,末尾不要多加/v1,starter 会自己拼。

报错五:工具调用返回 null 但模型说"没找到"。这是业务逻辑问题不是协议问题。比如searchArtist大小写不敏感匹配失败,或者数据没在@PostConstruct里初始化。加一行日志确认artists列表非空。

6. 接下来怎么走

工具跑通之后,下一步通常是把它接到真实数据源上,比如把ArtistService里的内存列表换成 JPA 查询。这时候要注意:MCP 工具直接连生产库是危险操作,建议加一层只读视图或者人工确认。如果你要长期跑编码类 Agent,把模型通道固定到 Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 会比按量付费省心。接入过程中遇到协议层报错,先翻接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,大部分 base_url 和鉴权问题那里都有说明。想快速验证某个模型对工具调用的支持程度,直接用模型对话 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite 发一条带工具的请求最直观。

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

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

立即咨询