
1. Java8 项目接 MCP Server 到底卡在哪如果你手上还有一堆跑在 JDK8 上的老服务最近又被 MCPModel Context Protocol这个词刷屏大概率会经历这样一个过程先搜「Java 开发 MCP Server」然后发现官方mcp-sdk要求 JDK17spring-ai-mcp-server要求 JDK17langchain4j-mcp-client也是 JDK17。一圈看下来结论好像是「想玩 MCP先把 JDK 升到 17」。但现实是很多后端团队的生产环境还锁在 JDK8编译链、依赖树、运维脚本、灰度流程全都围绕 JDK8 建好了为了一个协议层的能力去动整个运行时成本高得离谱。MCP 本身是一个协议框架它的价值在于「让模型能调用你的工具」而不是「逼你换 JDK」。所以真正的问题是有没有一个能在 JDK8 上直接跑起来的 MCP Server 实现我试过 Solon AI MCP 这条路它把 MCP Server 和 MCP Client 都做成了 JDK8 可用的依赖包同时兼容 JDK11/17/21。也就是说你不需要升级运行时只要在现有 Java8 工程里加一个依赖就能把工具方法注册成 MCP 端点让支持 MCP 的客户端比如 Claude Code、各类 Agent 框架来调用。这篇就按「能直接复制」的标准把 pom 依赖、启动类、config.toml骨架、以及通过 TaoToken 统一 Key/API 通道做一次工具调用验证的完整路径写清楚适合还在维护 Java8 项目的后端同学照着搭。2. 为什么选 Solon AI MCP 而不是官方 SDK先把几个主流方案的 JDK 要求摆出来这样你选型时不用来回翻文档方案JDK 要求说明mcp-sdkJDK17官方协议实现版本跟进快spring-ai-mcp-serverJDK17绑定 Spring 生态配置偏重spring-ai-mcp-clientJDK17同上langchain4j-mcp-clientJDK17偏客户端集成solon-ai-mcp-serverJDK8本篇主角服务端solon-ai-mcp-clientJDK8本篇主角客户端Solon AI 本身是一个 Java AI 全场景开发框架覆盖 LLM、Function Call、RAG、Embedding、Reranking、Flow、MCP Server、MCP Client 这些能力同时支持 Java8/11/17/21。它可以和 Solon 集成也能嵌到 SpringBoot2、jFinal、Vert.x 里用。对 Java8 团队来说关键点有两个一是依赖包本身不要求高版本 JDK二是它的 MCP Server 支持多端点一个进程里可以挂多个sseEndpoint这对老项目做能力拆分很友好。组件式写法长这样和写 MVC Controller 几乎一样McpServerEndpoint(name mcp-case1, sseEndpoint /case1/sse) public class McpServerTool { ToolMapping(description 查询天气预报) public String getWeather(ToolParam(description 城市位置) String location) { return 晴14度; } }如果你不想用注解也可以用原生 Java 方式构建McpServerEndpointProvider serverEndpoint McpServerEndpointProvider.builder() .name(mcp-case2) .sseEndpoint(/case2/sse) .build(); serverEndpoint.addTool(new MethodToolProvider(new McpServerTool())); serverEndpoint.postStart();客户端调用也很直接McpClientToolProvider clientToolProvider McpClientToolProvider.builder() .apiUrl(http://localhost:8080/case1/sse) .build(); String rst clientToolProvider.callToolAsText(getWeather, Map.of(location, 杭州));注意Map.of是 JDK9 才有的 APIJava8 下要换成Collections.singletonMap或HashMap这是后面排障章节会重点讲的一个坑。3. TaoToken 前置统一 Key 与 API 通道MCP Server 本身只负责「暴露工具」但工具背后往往要调模型或外部能力。如果每个服务各自维护一套 Key、各自拼一套 API 地址老项目里很快就会变成配置灾难。我的做法是走 TaoToken 的统一通道一个 Key 覆盖模型对话、编码计划、控制台等入口API 地址统一成https://taotoken.net/api这样 Java8 服务里只需要配一个 base url 和一个 token不用在代码里散落多家厂商的地址。具体入口按用途分模型对话验证https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_java8长期编码 / Agent 场景https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_java8控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_java8API Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_java8接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_java8Claude Code / Anthropic 相关https://taotoken.net/claudecode-anthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmcp_java8API 地址固定用https://taotoken.net/api不要加 UTM 参数避免拼进请求路径导致 404。拿到 Key 之后把它写进config.toml或环境变量Java8 代码里只读配置不硬编码。4. 可复制配置pom、启动类与 config.toml 骨架4.1 pom 依赖片段Java8 工程里加 Solon AI MCP 相关依赖注意版本号以你实际拉到的为准这里给的是结构properties java.version1.8/java.version solon.version2.9.0/solon.version solon.ai.version1.0.0/solon.ai.version /properties dependencies !-- Solon 核心 -- dependency groupIdorg.noear/groupId artifactIdsolon.boot.smarthttp/artifactId version${solon.version}/version /dependency !-- Solon AI MCP Server -- dependency groupIdorg.noear/groupId artifactIdsolon-ai-mcp-server/artifactId version${solon.ai.version}/version /dependency !-- Solon AI MCP Client用于本地验证 -- dependency groupIdorg.noear/groupId artifactIdsolon-ai-mcp-client/artifactId version${solon.ai.version}/version /dependency /dependencies如果你的老工程是 SpringBoot2也可以只引 MCP 依赖把 Solon 的启动方式嵌进去不必整体迁移。4.2 MCP Server 启动类下面是一个最小可跑的启动类注册两个端点一个注解式一个原生式方便你对比import org.noear.solon.Solon; import org.noear.solon.ai.mcp.server.McpServerEndpointProvider; import org.noear.solon.ai.mcp.server.tool.MethodToolProvider; public class McpServerApp { public static void main(String[] args) { Solon.start(McpServerApp.class, args, app - { // 原生方式注册第二个端点 McpServerEndpointProvider serverEndpoint McpServerEndpointProvider.builder() .name(mcp-case2) .sseEndpoint(/case2/sse) .build(); serverEndpoint.addTool(new MethodToolProvider(new McpServerTool())); serverEndpoint.postStart(); }); } }注解式的McpServerTool保持第 2 节里的写法即可Solon 启动时会自动扫描McpServerEndpoint。4.3 config.toml 骨架Solon 默认读resources/config.toml把 TaoToken 的 Key 和 API 地址放这里[server] port 8080 [taotoken] api_url https://taotoken.net/api api_key ${TAOTOKEN_API_KEY} [mcp] server_name java8-mcp-demo sse_endpoint /case1/sse${TAOTOKEN_API_KEY}从环境变量注入别把 Key 提交进仓库。启动前先export TAOTOKEN_API_KEY你的Key。5. 验证请求一次完整的工具调用5.1 启动服务export TAOTOKEN_API_KEYsk-你的Key mvn clean package -DskipTests java -jar target/java8-mcp-demo.jar看到 Solon 启动日志里出现mcp-case1和mcp-case2两个端点说明注册成功。5.2 用 MCP Client 调用工具写一个本地验证类走 Solon AI MCP Client 调getWeatherimport org.noear.solon.ai.mcp.client.McpClientToolProvider; import java.util.HashMap; import java.util.Map; public class McpClientDemo { public static void main(String[] args) { McpClientToolProvider clientToolProvider McpClientToolProvider.builder() .apiUrl(http://localhost:8080/case1/sse) .build(); MapString, Object params new HashMap(); params.put(location, 杭州); String rst clientToolProvider.callToolAsText(getWeather, params); System.out.println(工具返回: rst); } }Java8 下这里用HashMap而不是Map.of跑起来会输出工具返回: 晴14度5.3 通过 TaoToken 通道做模型侧验证工具能调通只说明 MCP Server 注册没问题还要确认模型侧能通过统一通道访问。用 curl 打一次 TaoToken 的 APIcurl -X POST https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: claude-sonnet-4-20250514, messages: [{role: user, content: 用一句话说明 MCP Server 的作用}] }返回里能看到正常的choices结构就说明 Key 和 API 通道都通了。把这一步和上面的工具调用串起来就是「Java8 MCP Server 注册成功 模型通道可用」的完整验证。6. 本篇常见错排查6.1Map.of编译报错Java8 没有Map.of报cannot find symbol。换成MapString, Object params new HashMap(); params.put(location, 杭州);6.2 SSE 端点 404检查sseEndpoint是否以/开头以及server.port是否和客户端apiUrl里的端口一致。Solon 默认端口是 8080如果你在config.toml里改了客户端也要同步改。6.3 依赖冲突导致启动失败老工程里可能已经有旧版 Solon 或其它 HTTP 框架用mvn dependency:tree看下solon-ai-mcp-server拉进来的 Solon 版本和现有版本对齐。必要时用exclusions排掉重复依赖。6.4 TaoToken 请求 401先确认环境变量TAOTOKEN_API_KEY真的导出到了当前 shellecho $TAOTOKEN_API_KEY能看到值。再确认 API 地址是https://taotoken.net/api没有多拼路径或 UTM 参数。Key 失效的话去 API Keys 页面重新生成。6.5 工具调用返回空callToolAsText返回空通常是工具方法名和ToolMapping注册名不一致或者参数名对不上。ToolParam里的description是给模型看的参数名要和params的 key 严格一致。7. 下一步把通道和端点固定下来Java8 跑 MCP Server 这件事卡点从来不是协议本身而是依赖的 JDK 门槛。Solon AI MCP 把服务端和客户端都压到 JDK8 可用等于给存量项目开了一条不用升级运行时的路。落地时建议把两件事固定成团队规范一是 MCP 端点统一走sseEndpoint命名规则二是模型通道统一走 TaoToken 的 Key 和 API 地址配置只从环境变量读。需要长期跑编码类 Agent 的话可以从 Coding Plan 入口拿更合适的额度只是验证模型连通性用模型对话页面就够接入细节和参数说明在接入文档里。把config.toml里的api_url和api_key换成你自己的这套骨架就能直接进你的 Java8 工程。