新闻详情

新闻详情

首页 / 资讯中心 / 详情

从零开始用Java搭建Spring AI MCP Server:STDIO模式配置与验证指南

发布时间:2026/9/27 20:11:55来源:尧图网络
从零开始用Java搭建Spring AI MCP Server:STDIO模式配置与验证指南
1. 为什么 Java 开发者需要一个 STDIO 模式的 MCP Server如果你正在用 Spring Boot 写业务系统又想让自己写的工具方法被 Claude、Cursor、TRAE 这类支持 MCP 的客户端直接调用那么 Spring AI 提供的 MCP Server Boot Starter 就是最省事的路径。MCP 全称 Model Context Protocol它做的事情可以类比成「给大模型装 USB 接口」你按协议把工具暴露出去客户端就能发现并调用不用为每个模型单独写适配层。STDIO 模式是四种传输方式里门槛最低的一种。它不走 HTTP、不占端口客户端启动一个子进程通过标准输入输出收发 JSON-RPC 消息。适合命令行工具、桌面应用内嵌服务、本地单机场景。你写完一个 jar客户端配置里写一行java -jar握手成功就能用。这篇聚焦 STDIO 这一条链路从依赖坐标、application.yml 骨架、Tool工具定义到打包、客户端 config.toml 配置、握手验证和工具调用目标是一次跑通。模型侧统一走 TaoToken 的 Key 和 API 通道这样客户端和 Server 的鉴权配置可以收敛到一处不用在多个平台之间来回切换。适合谁看有 Java 基础、用过 Spring Boot、想快速把本地能力接进 AI 客户端的开发者。不需要你提前懂 MCP 协议细节跟着配置走即可。2. 前置准备TaoToken Key 与 Spring AI 版本对齐2.1 拿到统一 KeyTaoToken 的定位是给 AI 应用提供统一的模型调用入口。你只需要在控制台创建一个 API Key后续客户端里配置 base-url 和 api-key 就能调用模型。地址如下官网入口https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentAPI 通道https://taotoken.net/api控制台创建 Keyhttps://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteKey 管理页https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite创建完把 Key 存到环境变量里别硬编码进代码export TAOTOKEN_API_KEYsk-你的key2.2 版本矩阵Spring AI 的 MCP 支持在 1.1.x 才比较完整STDIO starter 的坐标和早期版本有差异务必对齐组件版本要求说明JDK17Spring AI 1.1 最低要求推荐 21Spring Boot3.2与 Spring AI 1.1 兼容Spring AI BOM1.1.0-M2 或更高统一管理 starter 版本Maven3.8构建工具注意如果你之前用过spring-ai-mcp-server-spring-boot-starter这种旧坐标1.1.x 已经改成spring-ai-starter-mcp-server写错会直接报找不到依赖。3. 可复制配置STDIO MCP Server 骨架3.1 父工程 BOM先建一个父 pom把版本收口子模块不用重复写版本号?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.5.6/version relativePath/ /parent groupIdcom.example/groupId artifactIdmcp-parent/artifactId version0.0.1-SNAPSHOT/version packagingpom/packaging modules modulestdio-mcp/module /modules properties java.version21/java.version spring-ai.version1.1.0-M2/spring-ai.version /properties dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement /project3.2 子模块依赖STDIO 模式只需要一个 starter不要引入 web 相关依赖否则会启动 Tomcat 破坏标准输入输出通道?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdcom.example/groupId artifactIdmcp-parent/artifactId version0.0.1-SNAPSHOT/version relativePath../pom.xml/relativePath /parent artifactIdstdio-mcp/artifactId dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-server/artifactId /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin /plugins /build /project3.3 application.yml 骨架STDIO 模式的关键是关掉 web 容器、关掉 banner、关掉控制台日志因为 stdout 要留给协议消息任何多余输出都会污染握手spring: main: banner-mode: off web-application-type: none ai: mcp: server: enabled: true stdio: true name: stdio-time-server version: 1.0.0 type: SYNC capabilities: tool: true resource: true prompt: true request-timeout: 30s logging: pattern: console: file: name: ./logs/stdio-mcp.log注意logging.pattern.console:后面留空是故意的表示不向控制台输出日志。日志改写到文件方便排查又不干扰协议。3.4 定义工具用Tool注解标记方法Spring AI 会自动生成 JSON Schema 并注册到 MCP 能力列表package com.example.stdiomcp.tools; import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; Service public class TimeToolService { Tool(description 获取当前本地时间返回时间戳、可读时间和星期信息) public String getTime() { LocalDateTime dateTime LocalDateTime.now(ZoneId.of(Asia/Shanghai)); long timestamp System.currentTimeMillis(); DateTimeFormatter formatter DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss); String formatted dateTime.format(formatter); int dayOfWeek dateTime.getDayOfWeek().getValue(); int dayOfYear dateTime.getDayOfYear(); return String.format(时间戳: %d, 时间: %s, 星期%d, 本年第%d天, timestamp, formatted, dayOfWeek, dayOfYear); } }3.5 注册工具回调光有Tool还不够需要显式注册ToolCallbackProvider否则客户端tools/list拿到的是空列表package com.example.stdiomcp.config; import com.example.stdiomcp.tools.TimeToolService; import org.springframework.ai.tool.ToolCallbackProvider; import org.springframework.ai.tool.method.MethodToolCallbackProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class ToolsConfig { Bean public ToolCallbackProvider timeTools(TimeToolService timeToolService) { return MethodToolCallbackProvider.builder() .toolObjects(timeToolService) .build(); } }3.6 打包mvn -pl stdio-mcp -am clean package -DskipTests产物在stdio-mcp/target/stdio-mcp-0.0.1-SNAPSHOT.jar记住这个绝对路径客户端配置要用。4. 客户端 config.toml 与握手验证4.1 客户端侧配置不同客户端的配置文件格式略有差异但核心字段一致command、args、env。以通用 JSON 形式举例Claude Desktop 用的是claude_desktop_config.jsonCursor 和 TRAE 用mcp.json字段结构相同{ mcpServers: { stdio-time-server: { command: java, args: [ -Dspring.ai.mcp.server.stdiotrue, -Dlogging.pattern.console, -jar, /absolute/path/to/stdio-mcp-0.0.1-SNAPSHOT.jar ], env: { TAOTOKEN_API_KEY: sk-你的key } } } }如果你用的是支持 TOML 的客户端等价写法[mcp_servers.stdio-time-server] command java args [ -Dspring.ai.mcp.server.stdiotrue, -Dlogging.pattern.console, -jar, /absolute/path/to/stdio-mcp-0.0.1-SNAPSHOT.jar ] [mcp_servers.stdio-time-server.env] TAOTOKEN_API_KEY sk-你的key注意-jar后面必须是绝对路径。相对路径在客户端启动子进程时工作目录不确定会直接报找不到 jar。4.2 手动握手验证在接入客户端之前建议先用命令行手动验证一次确认 Server 能正常响应 initialize 请求。MCP 的 STDIO 传输是每行一个 JSON-RPC 消息你可以用管道喂进去printf %s\n \ {jsonrpc:2.0,id:1,method:initialize,params:{protocolVersion:2024-11-05,capabilities:{},clientInfo:{name:cli-test,version:1.0}}} \ | java -Dspring.ai.mcp.server.stdiotrue -Dlogging.pattern.console \ -jar /absolute/path/to/stdio-mcp-0.0.1-SNAPSHOT.jar正常返回类似{jsonrpc:2.0,id:1,result:{protocolVersion:2024-11-05,capabilities:{tools:{listChanged:true}},serverInfo:{name:stdio-time-server,version:1.0.0}}}看到serverInfo里有你的服务名说明握手成功。4.3 验证工具列表接着发tools/list确认工具被正确注册printf %s\n \ {jsonrpc:2.0,id:1,method:initialize,params:{protocolVersion:2024-11-05,capabilities:{},clientInfo:{name:cli-test,version:1.0}}} \ {jsonrpc:2.0,method:notifications/initialized} \ {jsonrpc:2.0,id:2,method:tools/list,params:{}} \ | java -Dspring.ai.mcp.server.stdiotrue -Dlogging.pattern.console \ -jar /absolute/path/to/stdio-mcp-0.0.1-SNAPSHOT.jar返回里应该能看到getTime这个工具带 description 和 inputSchema。4.4 验证工具调用最后发tools/call实际执行一次printf %s\n \ {jsonrpc:2.0,id:1,method:initialize,params:{protocolVersion:2024-11-05,capabilities:{},clientInfo:{name:cli-test,version:1.0}}} \ {jsonrpc:2.0,method:notifications/initialized} \ {jsonrpc:2.0,id:3,method:tools/call,params:{name:getTime,arguments:{}}} \ | java -Dspring.ai.mcp.server.stdiotrue -Dlogging.pattern.console \ -jar /absolute/path/to/stdio-mcp-0.0.1-SNAPSHOT.jar返回的content数组里会带上格式化后的时间字符串。到这一步STDIO 链路就完整跑通了。5. 本篇常见错误排查5.1 客户端报「server disconnected」或握手超时最常见的原因是 stdout 被日志污染。检查三处banner-mode: off是否生效、logging.pattern.console:是否留空、有没有引入spring-boot-starter-web。任何一行非 JSON 输出都会让客户端解析失败。5.2 tools/list 返回空数组Tool方法所在类没有加Service或Component或者没有注册ToolCallbackProviderBean。两个条件缺一不可。另外确认spring.ai.mcp.server.capabilities.tool是 true。5.3 启动报 web 容器相关异常说明 classpath 里有 web 依赖。STDIO 模式必须web-application-type: none同时 pom 里不能有spring-boot-starter-web或spring-boot-starter-webflux。如果确实需要 HTTP 能力应该改用 SSE 或 Streamable-HTTP 模式而不是在 STDIO 里混用。5.4 中文返回乱码客户端和 Server 的编码不一致。在启动参数里加-Dfile.encodingUTF-8并确认Tool返回的字符串本身是 UTF-8。5.5 工具调用报「method not found」tools/call里的name必须和tools/list返回的完全一致大小写敏感。如果你改了方法名客户端缓存可能还是旧的重启客户端即可。6. 下一步把模型通道也接上STDIO Server 本身只负责暴露工具真正让模型「用起来」还需要客户端侧配置模型通道。如果你希望客户端调用模型时也走统一入口可以在客户端配置里把 base-url 指向 TaoToken 的 API 地址api-key 用同一个 Key模型对话调试入口https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite长期编码 / Agent 场景https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite这样工具调用和模型推理共用一套鉴权排查问题时只需要看一个 Key 的用量和日志。STDIO 这条链路跑通之后再切到 SSE 或 Streamable-HTTP 只是换 starter 和 yml 的事工具代码可以原样复用。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

macOS Sequoia 15中spctl精细化授权‘任何来源’的正确方法 2026/9/27 20:53:56

macOS Sequoia 15中spctl精细化授权‘任何来源’的正确方法

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

阅读更多 →
PageHelper 分页原理、Spring Boot 集成与 count 优化实战 2026/9/27 20:53:55

PageHelper 分页原理、Spring Boot 集成与 count 优化实战

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

阅读更多 →
108解读《华为以客户为中心的流程建设框架:从战略到执行的全流程落地》 2026/9/27 20:53:36

108解读《华为以客户为中心的流程建设框架:从战略到执行的全流程落地》

本 108 页 PPT 适配集团组织变革、流程体系、IPD/LTC 咨询方案编制。借鉴流程再造理论,拆解流程型组织设计方法论,区分 OES/POS 流程架构,解析管理权与指挥权分离的双向指挥体系。深度复盘华为组织迭代,完整剖析 IPD 研发、LTC 营…

阅读更多 →
SQLSERVER存储过程解密实战:用 TaoToken 统一 Key 打通 AI 辅助排查链路 2026/9/27 20:53:29

SQLSERVER存储过程解密实战:用 TaoToken 统一 Key 打通 AI 辅助排查链路

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

阅读更多 →
飞书 Streaming Card / CardKit 实战:OpenClaw 流式更新落地与 reply-dispatcher.ts 配置避坑指南(含 TaoToken 接入) 2026/9/27 20:53:29

飞书 Streaming Card / CardKit 实战:OpenClaw 流式更新落地与 reply-dispatcher.ts 配置避坑指南(含 TaoToken 接入)

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

阅读更多 →
高斯光束传输计算:复参数q与ABCD矩阵的MATLAB实现指南 2026/9/27 20:53:29

高斯光束传输计算:复参数q与ABCD矩阵的MATLAB实现指南

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

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉