ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

204-Spring AI Alibaba MCP Manual 示例:把 MCP 服务端配置改到 TaoToken

204-Spring AI Alibaba MCP Manual 示例:把 MCP 服务端配置改到 TaoToken 1. 本地 MCP 跑通之后模型入口反而成了新麻烦Spring AI Alibaba 的 MCP Manual 示例解决的是「让 Java 应用通过标准协议调用外部工具」这件事。文件系统、GitHub、SQLite 三个子项目跑下来你会发现 MCP Server 本身并不难启动npx拉起 filesystemuvx拉起 sqliteMcpSyncClient初始化打印出MCP Initialized工具列表也能正常listTools。真正让人卡住的是下一步——这些工具最终要交给一个大模型去决策调用而模型调用的入口、密钥、计费、日志散落在每个子项目的application.yml里各写一份。我试过把ai-mcp-fileserver、ai-mcp-github、ai-mcp-sqlite三个项目分别配置模型结果就是三份不同的api-key、三套base-url改一个环境变量要翻三个目录。更麻烦的是当你想确认「这次工具调用到底走的是哪条通道」时日志里只有 MCP 的 stdio 交互看不到模型请求的出口。对于需要统一模型调用入口的开发者来说这显然不够。这篇内容面向的是已经能在本地跑通 MCP 服务端、但希望把模型调用收敛到一个统一入口的开发者。核心动作只有一个把 Spring AI Alibaba MCP Manual 示例里的模型配置从各子项目分散的dashscope或openai配置改成指向 TaoToken 的base-url与api-key。改完之后MCP 工具调用照常工作但所有模型请求都会经过同一条通道日志可查、密钥可管、切换模型不用动业务代码。你需要的前置条件很明确JDK 17、Maven 3.6、Node 环境npx可用、以及一个 TaoToken 的 API Key。MCP Server 那边该装的modelcontextprotocol/server-filesystem、mcp-server-sqlite保持原样我们只动 Spring AI 这一侧的模型接入层。下面从配置片段开始一步步把这件事落地。2. TaoToken 前置把模型入口从 dashscope 换成统一通道在动手改application.yml之前先把 TaoToken 这一侧准备好。TaoToken 在这里扮演的角色是「统一的模型调用入口」——你的 Spring AI 应用不再直接连某个模型厂商的地址而是把请求发到 TaoToken 的 API 地址由它转发到具体模型。对 MCP 示例来说这意味着ChatClient背后的ChatModel换了一个base-url工具回调、FunctionCallback、McpSyncClient这些逻辑完全不用改。第一步是拿到 API Key。访问https://taotoken.net/api-keys登录后创建一个新的 Key。建议按项目命名比如spring-ai-mcp-manual方便后面在日志里区分是哪个应用发出的请求。Key 创建后只显示一次复制到安全的地方后面要写进环境变量。第二步是确认 API 地址。TaoToken 的 API 根地址是https://taotoken.net/api注意这里不要加任何查询参数。Spring AI 的 OpenAI 兼容配置里base-url填这个根地址即可SDK 会自动拼接/v1/chat/completions这类路径。如果你之前用的是 dashscope 的地址现在要整体替换掉。第三步是选模型 ID。MCP 示例里工具调用对模型的 function calling 能力有要求建议选支持工具调用的模型。你可以在https://taotoken.net/models查看可用模型列表记下你要用的那个 Model ID比如gpt-4o或claude-3-5-sonnet这类。这个 ID 后面要写进application.yml的model字段。把这三样东西准备好API Key、Base URL、Model ID。它们就是后面配置片段里的三个核心变量。为了不在代码里硬编码密钥建议用环境变量注入Spring 的${TAOTOKEN_API_KEY}占位符可以直接读环境变量。这样本地跑、CI 跑、换机器跑都只需要改环境变量不用动仓库里的配置文件。注意TaoToken 是模型调用入口不是 MCP Server 的替代品。MCP Server 仍然由npx或uvx在本地拉起TaoToken 只负责模型那一侧的请求转发。两者职责不要混淆。3. 可复制配置application.yml 与 mcp-servers-config.json 改造现在进入具体改造。以ai-mcp-fileserver为例原始配置里模型走的是 dashscope我们要把它换成 TaoToken 的 OpenAI 兼容入口。Spring AI Alibaba 的 starter 同时支持 dashscope 和 openai 两种ChatModel这里我们用 openai 兼容模式因为 TaoToken 的 API 是 OpenAI 兼容的。先看application.yml的完整可复制片段spring: ai: openai: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY} chat: options: model: gpt-4o temperature: 0.7 mcp: client: stdio: servers-configuration: classpath:/mcp-servers-config.json这里有几个点要对照原文确认。第一base-url是https://taotoken.net/api不带/v1Spring AI 的 OpenAI 客户端会自己补路径。第二api-key用${TAOTOKEN_API_KEY}占位运行时从环境变量读。第三model填你在上一步记下的 Model ID。第四mcp.client.stdio.servers-configuration这一行保持原样指向 MCP Server 的配置文件不要动。接下来是mcp-servers-config.json这个文件定义 MCP Server 怎么启动。以 filesystem 为例内容如下{ mcpServers: { filesystem: { command: npx, args: [ -y, modelcontextprotocol/server-filesystem, /Users/yourname/mcp-data ] } } }Windows 下command要改成cmdargs前面加/c这一点和原文的 GitHub 示例一致{ mcpServers: { filesystem: { command: cmd, args: [ /c, npx, -y, modelcontextprotocol/server-filesystem, C:\\mcp-data ] } } }注意args最后那个路径是你允许 MCP 访问的本地目录按实际改。这个文件只负责 MCP Server 的启动参数和模型入口无关所以从原示例直接拿过来即可。如果你用的是ai-mcp-sqlite子项目mcp-servers-config.json换成 sqlite 的启动方式{ mcpServers: { sqlite: { command: uvx, args: [ mcp-server-sqlite, --db-path, /Users/yourname/spring-ai-alibaba-mcp-manual-example/sqlite/ai-mcp-sqlite/test.db ] } } }对应的application.yml里model可以换成更适合 SQL 生成的模型但base-url和api-key不变仍然是 TaoToken 的入口。这样三个子项目共用同一套模型接入配置只是 MCP Server 的启动参数不同。还有一个容易漏的点Spring AI 的 OpenAI starter 依赖要加进pom.xml。原示例用的是spring-ai-starter-mcp-client加 dashscope现在要补上 openai 的 starterdependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId version1.0.0-RC1/version /dependency版本号和你项目里其他 Spring AI 依赖保持一致。加完之后mvn clean install能过说明依赖没问题。4. 验证请求一次 MCP 工具调用如何确认走了 TaoToken配置改完接下来要验证两件事MCP 工具调用是否正常以及模型请求是否真的经过 TaoToken。验证方式是在CommandLineRunner里发一个会触发工具调用的问题然后看日志。以 filesystem 为例ChatClient构建时注入 MCP 工具回调Bean public CommandLineRunner predefinedQuestions( ChatClient.Builder chatClientBuilder, ListMcpFunctionCallback functionCallbacks, ConfigurableApplicationContext context) { return args - { var chatClient chatClientBuilder .defaultToolCallbacks(new SyncMcpToolCallbackProvider(mcpClient)) .build(); String userInput 读取 /Users/yourname/mcp-data/summary.md 的内容并总结; System.out.println(\n QUESTION: userInput); System.out.println(\n ASSISTANT: chatClient.prompt(userInput).call().content()); context.close(); }; }运行./mvnw spring-boot:run你会看到几段关键日志。第一段是 MCP 初始化MCP Initialized: InitializeResult[protocolVersion2024-11-05, capabilities...]这说明 MCP Server 已经通过 stdio 拉起工具列表可用。第二段是工具调用Tool call: read_file, arguments: {path: /Users/yourname/mcp-data/summary.md}这说明模型决定调用read_file工具MCP 客户端把请求转发给了 filesystem server。第三段是模型响应 ASSISTANT:后面跟着总结内容。要确认请求走了 TaoToken看两个地方。一是启动日志里 OpenAI 客户端的 base URLOpenAiApi baseUrl: https://taotoken.net/api二是 TaoToken 控制台的请求记录。登录https://taotoken.net/console在请求日志里能看到刚才那次chat/completions调用包含模型 ID、token 用量、时间戳。如果日志里出现了这次请求说明模型调用确实经过了 TaoToken 通道而不是直连其他厂商。如果你用的是 sqlite 示例验证问题可以换成String userInput 连接我的 SQLite 数据库告诉我有哪些产品以及它们的价格;预期日志里会出现Tool call: query或类似的 SQLite 工具调用然后模型基于查询结果生成回答。同样TaoToken 控制台能看到对应的模型请求记录。提示如果日志里只看到 MCP 初始化没有工具调用通常是模型不支持 function calling或者defaultToolCallbacks没注入成功。先确认model字段选的是支持工具调用的模型。5. 本篇常见错排查401、local proxy failed 与 choices 读取失败改造过程中最容易撞上三类报错这里逐个对照。第一类是 401 未授权。日志长这样401 Unauthorized: {error:{message:Invalid API key,type:invalid_request_error}}原因通常是TAOTOKEN_API_KEY环境变量没设置或者设置后没重启应用。Spring 启动时读一次环境变量改了要重启。检查方式是echo $TAOTOKEN_API_KEYWindows 用echo %TAOTOKEN_API_KEY%确认有值且没有多余空格。另一个可能是 Key 复制时漏了字符重新在https://taotoken.net/api-keys生成一个再试。第二类是local proxy failed或连接超时。日志里出现java.net.ConnectException: Connection refused或者 OpenAI 客户端报local proxy failed。这通常是base-url写错了比如多写了/v1或者写成了https://taotoken.net/api/v1。正确写法是https://taotoken.net/api不要带路径后缀。另外检查本机网络是否能正常访问该地址curl https://taotoken.net/api能返回响应即可。第三类是读取choices失败。日志长这样java.lang.NullPointerException: Cannot invoke java.util.List.get(int) because choices is null或者reading choices相关异常。这通常说明返回的 JSON 结构不符合 OpenAI 格式可能是model字段填了一个不存在的模型 ID导致服务端返回了错误结构。去https://taotoken.net/models核对 Model ID 拼写确认它在可用列表里。另一个可能是base-url指向了非 OpenAI 兼容的端点确认用的是https://taotoken.net/api。还有一类和 MCP 本身相关OAuth或initialize超时。日志里出现MCP Initialized: InitializeResult[...] 之后卡住或者 GitHub 示例里报 OAuth 相关错误。这通常是 MCP Server 启动参数不对比如npx路径找不到、GITHUB_PERSONAL_ACCESS_TOKEN没设置。检查mcp-servers-config.json里的command和argsWindows 下确认用了cmd /c。GitHub 示例还需要在环境变量里设置GITHUB_PERSONAL_ACCESS_TOKEN这个和 TaoToken 的 Key 是两回事不要混。把这三类报错对照完基本能覆盖改造过程中的大部分问题。核心原则是模型侧的报错看base-url、api-key、model三个字段MCP 侧的报错看mcp-servers-config.json的启动参数。两边分开排查不要混在一起改。6. 统一入口之后MCP 工具调用的下一步配置改完、验证通过之后你的 Spring AI Alibaba MCP Manual 示例就有了一个统一的模型调用入口。三个子项目——fileserver、github、sqlite——共用同一套base-url和api-key切换模型只需要改application.yml里的model字段不用动任何业务代码。MCP 工具回调、FunctionCallback、McpSyncClient这些逻辑保持原样工具发现和执行照常工作。接下来可以做的事有几件。一是把ai-mcp-sqlite-chatbot的交互式聊天也切到 TaoToken 入口这样自然语言查数据库的每一轮对话都走同一条通道日志集中可查。二是如果你要长期跑编码类 Agent可以了解 Coding Plan它更适合高频、长时间的模型调用场景。三是把 API Key 的管理收敛到环境变量或密钥管理服务不要写进仓库。我在实际改造时踩过的一个坑是application.yml里同时留了 dashscope 和 openai 两套配置Spring 启动时按 starter 顺序选了一个结果模型请求还是走了旧通道。后来把 dashscope 相关配置整段删掉只留 openai 兼容配置日志里才稳定出现 TaoToken 的 base URL。如果你也遇到「配置改了但没生效」先检查有没有残留的旧配置段。最后一步验证打开https://taotoken.net/console确认最近的请求记录里有你的 MCP 应用发出的chat/completions调用模型 ID 和application.yml里写的一致。到这一步模型入口就真正统一了。
返回列表