ARTICLE DETAIL

资讯详情

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

Spring AI实战:本地与在线MCP客户端接入TaoToken统一配置

Spring AI实战:本地与在线MCP客户端接入TaoToken统一配置 1. 为什么 Spring AI 项目里 MCP 客户端配置总让人头疼如果你正在用 Spring AI 做 AI 应用大概率会遇到这样一个场景本地想跑 Ollama 上的 Qwen3 做私有化调试线上又想切到 ZhiPu AI 的 GLM 系列做快速验证同时两边都要挂 MCPModel Context Protocol工具链让模型能读写文件、查系统信息、调内部接口。听起来很合理但真动手配的时候问题就来了——本地 Ollama 的 base-url 是http://127.0.0.1:11434在线 ZhiPu AI 走的是另一套鉴权和 endpoint两套 ChatModel、两套 ChatClient.Builder、两套 api-keyapplication.yml越写越长Bean 冲突、Key 散落、切换环境要改代码维护成本直接起飞。MCP 客户端接入本身不复杂复杂的是本地 在线双通道并存时的统一管理。这篇就围绕这个痛点用 TaoToken 作为统一 Key / API 通道骨架把本地 Ollama 与在线 ZhiPu AI 两条 MCP 客户端链路收敛到一套配置里。你会拿到可直接复制的application.yml、MCP 客户端 Bean 配置片段以及启动后验证两条链路连通性的具体命令和预期日志。适合已经上手 Spring AI、正在做 MCP 工具接入、被多模型配置折磨过的后端同学。先说清楚 TaoToken 在这里扮演什么角色它是一个统一的模型 API 接入通道把不同厂商的模型调用收敛到一套 Key 和一套 base-url 下省去你在每个 starter 里分别填不同厂商密钥的麻烦。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 通道地址是 https://taotoken.net/api 这个不加 UTM。下面所有配置都基于这个骨架展开。2. TaoToken 前置准备Key、通道与依赖坐标动手写配置前先把三件事准备好否则后面 yml 填到一半会卡住。第一是拿 Key。进控制台创建 API Key路径是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 创建完复制那串sk-开头的密钥后面application.yml里要用。如果你还没决定用哪些模型可以先到模型对话页 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 试一下 GLM 系列和 Qwen 系列的返回效果确认工具调用tool call能力正常再往下走。第二是确认依赖坐标。Spring AI 的 starter 命名在不同版本间有差异我实测下来比较稳的组合是本地侧用spring-ai-ollama-spring-boot-starter在线侧用spring-ai-openai-spring-boot-starter因为 TaoToken 的在线通道兼容 OpenAI 协议格式ZhiPu AI 的 GLM 模型可以通过这个 starter 走统一通道MCP 客户端能力用spring-ai-mcp-spring-boot-starter。三个依赖的版本建议统一到同一个 Spring AI BOM 下避免传递依赖打架。第三是本地 Ollama 要提前跑起来并且拉好支持工具调用的模型。Qwen3 是当前对 MCP 工具调用支持比较完整的选择执行ollama pull qwen3:latest拉取然后ollama list确认模型在列。Ollama 默认监听11434如果你的机器上端口被占记得在启动参数里改掉后面 yml 里的 base-url 要跟它对齐。注意MCP 工具调用会消耗较多 token尤其是把工具描述、参数 schema 一起塞进上下文时。本地 Ollama 不花钱但吃显存在线通道按量计费调试阶段建议先用本地跑通工具注册再切在线验证。3. 可复制配置application.yml 与 MCP 客户端 Bean这一节是全文核心配置分三层模型通道层、MCP 客户端层、Bean 装配层。先看application.yml。spring: application: name: spring-ai-mcp-demo ai: # 本地 Ollama 通道 ollama: base-url: http://127.0.0.1:11434 chat: options: model: qwen3:latest temperature: 0.7 embedding: enabled: true options: model: nomic-embed-text # 在线统一通道TaoToken 兼容 OpenAI 协议 openai: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY} chat: options: model: glm-4-plus temperature: 0.7 # MCP 客户端配置 mcp: client: enabled: true name: spring-ai-mcp-client version: 1.0.0 request-timeout: 60s type: SYNC stdio: servers-configuration: classpath:config/mcp-servers.json几个关键点解释一下。openai.base-url指向 TaoToken 的 API 通道api-key用环境变量注入别硬编码进仓库。mcp.client.stdio.servers-configuration指向 classpath 下的 MCP server 清单文件这个文件决定客户端能拉起哪些工具进程。接着是src/main/resources/config/mcp-servers.json这里挂两个 server一个文件系统工具一个自定义的系统信息工具。{ mcpServers: { filesystem: { command: npx, args: [ -y, modelcontextprotocol/server-filesystem, /Users/yourname/mcp-workspace ] }, computer-info: { command: java, args: [ -jar, /opt/mcp/ai-mcp-server-computer-1.0.0.jar ] } } }Windows 下npx要写成npx.cmd路径分隔符用双反斜杠或正斜杠都行但别混用。filesystem的最后一个参数是允许操作的目录MCP 客户端只会在这个目录范围内读写超出会被拒绝这是安全边界别图省事写成根目录。然后是 Bean 装配。本地和在线两个 ChatClient.Builder 分开定义但都注入同一个ToolCallbackProvider这样 MCP 工具对两条链路都可见。Configuration public class McpClientConfig { Bean public ChatClient.Builder ollamaChatClientBuilder(OllamaChatModel model) { return ChatClient.builder(model); } Bean public ChatClient.Builder onlineChatClientBuilder(OpenAiChatModel model) { return ChatClient.builder(model); } Bean public ToolCallbackProvider mcpToolCallbackProvider( ToolCallbackResolver resolver) { return ToolCallbackProvider.from(resolver); } }ToolCallbackProvider.from(resolver)会把 MCP 客户端从 stdio server 拉起的工具统一注册进来。如果你用的是较新的 Spring AI 版本ToolCallbackResolver由 MCP starter 自动装配不用手动 new。装配完成后两个 Builder 在调用时通过.defaultTools(toolCallbackProvider)挂上工具即可。4. 验证请求两条链路的连通性命令与预期日志配置写完启动应用前先确认 MCP server 能被拉起。单独测 stdio server 是否可用可以直接在终端跑npx -y modelcontextprotocol/server-filesystem /Users/yourname/mcp-workspace正常的话进程会挂起等待 stdin 输入说明 server 可执行。按 CtrlC 退出。如果报command not found检查 Node.js 和 npm 是否在 PATH 里。启动 Spring Boot 应用后重点看启动日志里 MCP 客户端的初始化输出。预期能看到类似这样的行INFO o.s.a.m.c.StdioMcpClient - Initializing MCP client: spring-ai-mcp-client INFO o.s.a.m.c.StdioMcpClient - Starting MCP server: filesystem INFO o.s.a.m.c.StdioMcpClient - Starting MCP server: computer-info INFO o.s.a.m.c.StdioMcpClient - Discovered 6 tools from MCP serversDiscovered N tools这行是关键N 大于 0 说明工具注册成功。如果 N 是 0往下看第 5 节的排查。接着写一个测试方法分别验证本地和在线两条链路能否调用工具。先测本地 OllamaSpringBootTest class McpLocalTest { Resource private ChatClient.Builder ollamaChatClientBuilder; Resource private ToolCallbackProvider mcpToolCallbackProvider; Test void testLocalToolCall() { String result ollamaChatClientBuilder .defaultTools(mcpToolCallbackProvider) .build() .prompt(列出当前工作目录下的所有文件) .call() .content(); System.out.println(result); } }预期输出里会包含模型对工具调用结果的总结比如当前目录下有 a.txt、b.md 两个文件。如果模型直接回答我无法访问文件系统说明工具没挂上回到 Bean 装配检查defaultTools是否生效。再测在线通道SpringBootTest class McpOnlineTest { Resource private ChatClient.Builder onlineChatClientBuilder; Resource private ToolCallbackProvider mcpToolCallbackProvider; Test void testOnlineToolCall() { String result onlineChatClientBuilder .defaultTools(mcpToolCallbackProvider) .build() .prompt(当前有哪些工具可用请列出工具名称) .call() .content(); System.out.println(result); } }在线通道的预期输出会列出filesystem和computer-info下的具体工具名比如read_file、write_file、get_computer_info。能列出来说明 TaoToken 通道 MCP 工具注册这条链路是通的。5. 本篇常见错排查错误一Discovered 0 tools工具一个都没注册上。九成是mcp-servers.json路径不对或 JSON 格式有误。先确认文件在src/main/resources/config/下打包后能在target/classes/config/找到。JSON 里多一个逗号、少一个引号都会导致解析失败用jq . mcp-servers.json校验一下。另外command字段在 Windows 上要写npx.cmd写npx会静默失败。错误二本地 Ollama 报Connection refused。检查 Ollama 是否在跑curl http://127.0.0.1:11434/api/tags能不能返回模型列表。如果 Ollama 跑在 Docker 里127.0.0.1在容器内指向容器自己要换成宿主机 IP 或host.docker.internal。错误三在线通道返回 401。大概率是TAOTOKEN_API_KEY环境变量没注入或者 Key 复制时带了空格。在 IDE 的 Run Configuration 里显式配环境变量别依赖 shell 的 export。如果 Key 确认没问题还是 401到 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 重新生成一个再试。错误四工具调用超时。MCP 工具拉起子进程、初始化、握手需要时间默认超时可能不够。在 yml 里把spring.ai.mcp.client.request-timeout调到60s或更高。如果computer-info那个 jar 启动慢单独给它加启动等待。错误五本地和在线 Bean 冲突。两个ChatClient.Builder类型相同Spring 注入时会报NoUniqueBeanDefinitionException。解决办法是给 Bean 起不同名字注入时用Qualifier(ollamaChatClientBuilder)和Qualifier(onlineChatClientBuilder)区分。别用Primary糊弄那会让另一条链路拿错 Builder。错误六MCP 工具操作了预期外的目录。filesystemserver 的目录参数是硬边界但如果你在 prompt 里让模型操作绝对路径模型可能尝试越界。实测下来越界请求会被 server 拒绝并返回错误模型会转述这个错误。生产环境务必把目录限制在专用工作区别指向用户主目录。6. 长期编码与 Agent 场景的接入建议如果你只是偶尔切模型调试上面这套配置够用了。但如果你在做长期编码助手、Agent 工作流这类需要频繁调用、上下文长、工具链复杂的场景建议把在线通道换成 Coding Plan 来管理配额和调用策略入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。它更适合持续性的编码任务不用每次手动切 Key。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有针对 Spring AI、Claude Code 等不同客户端的配置示例遇到协议细节对不上时可以对照查。如果你用的是 Claude Code 做 Agent 开发Anthropic 兼容通道的说明在 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-code-anthropicutm_campaignrewrite 配置思路和这篇的 MCP 客户端接入是一致的都是把工具链挂到统一通道上。最后留一个我踩过的坑MCP 工具的 schema 描述别写太长模型在决定调哪个工具时会把所有工具描述塞进上下文描述越啰嗦token 消耗越大本地 Ollama 的响应也越慢。工具描述控制在两句话以内参数说明用ToolParam精确标注比写一大段自然语言管用。
返回列表