您现在的位置是:首页 > 文章详情

Java MCP 实战:构建跨进程与远程的工具服务

日期:2025-07-08点击:15

一、MCP 协议简介

MCP(Model Context Protocol,模型上下文协议)是由Anthropic推出的一种开放标准协议,旨在为大语言模型(LLM)与外部数据源、工具和服务提供标准化、安全的集成方式。支持进程间(通过 stdio)和远程(通过 HTTP SSE/Streaming)通讯。它专为 AI 开发设计,可以方便地提供 Tool(工具服务)、Prompt(提示语服务)和 Resource(资源服务)三种原语内容。

MCP 的核心优势在于:

  • 支持多种通讯方式(stdio/SSE/Streaming)
  • 支持服务发现(客户端可查询服务端点提供的接口)
  • 与 AI 生态无缝集成(可直接作为大模型的工具使用)

MCP 架构示意图:

二、环境准备

首先在项目中添加 Java MCP 关键依赖:

 <dependency> <groupId>org.noear</groupId> <artifactId>solon-ai-mcp</artifactId> <version>最新版本</version> </dependency> 

支持 java8, java11, java17, java21, java24 。支持 solon,springboot,vert.x,jFinal 等框架集成。完整的示例参考:

三、构建 MCP 服务端

1、最简单的 SSE 服务

 @McpServerEndpoint(sseEndpoint = "/mcp/sse") public class SimpleMcpServer { @ToolMapping(description = "问候服务") public String hello(@Param(name="name", description = "用户名") String name) { return "你好, " + name; } } public class App { public static void main(String[] args) { Solon.start(App.class, args); } } 

2、多端点服务

 // 金融工具服务 @McpServerEndpoint(name="finance-tools", sseEndpoint = "/finance/sse") public class FinanceTools { @ToolMapping(description = "计算复利") public double compoundInterest( @Param(description = "本金") double principal, @Param(description = "年利率") double rate, @Param(description = "年数") int years) { return principal * Math.pow(1 + rate, years); } } // 教育工具服务 @McpServerEndpoint(name="edu-tools", sseEndpoint = "/edu/sse") public class EducationTools { @ToolMapping(description = "生成数学题") public String generateMathProblem( @Param(description = "难度级别") String level) { if("easy".equals(level)) { return "3 + 5 = ?"; } else { return "∫(x^2)dx from 0 to 1 = ?"; } } } 

3、动态管理工具

 @Controller public class ToolManager { @Inject("finance-tools") McpServerEndpointProvider financeEndpoint; @Mapping("/tool/add") public void addTool() { financeEndpoint.addTool(new FunctionToolDesc("calculateTax") .doHandle(params -> { double income = (double)params.get("income"); return income * 0.2; // 简单计算20%税 })); financeEndpoint.notifyToolsListChanged(); } @Mapping("/tool/remove") public void removeTool() { financeEndpoint.removeTool("calculateTax"); financeEndpoint.notifyToolsListChanged(); } } 

4、STDIO 服务

 @McpServerEndpoint(channel = McpChannel.STDIO) public class StdioCalculator { @ToolMapping(description = "加法计算") public int add(@Param int a, @Param int b) { return a + b; } @ToolMapping(description = "减法计算") public int subtract(@Param int a, @Param int b) { return a - b; } } 

注意:STDIO 服务不能开启控制台日志,否则会污染协议流。

四、构建 MCP 客户端

1、基本客户端调用

 public class McpClientDemo { public static void main(String[] args) { // 连接SSE服务 McpClientToolProvider sseClient = McpClientToolProvider.builder() .apiUrl("http://localhost:8080/mcp/sse") .build(); String greeting = sseClient.callToolAsText("hello", Map.of("name", "张三")); System.out.println(greeting); // 连接STDIO服务 McpClientToolProvider stdioClient = McpClientToolProvider.builder() .channel(McpChannel.STDIO) .serverParameters(McpServerParameters.builder("java") .args("-jar", "path/to/stdio-service.jar") .build()) .build(); int sum = stdioClient.callToolAsText("add", Map.of("a", 5, "b", 3)); System.out.println("5 + 3 = " + sum); } } 

2、集成到AI模型

 @Configuration public class AiConfig { @Bean public ChatModel chatModel( @Inject("${solon.ai.chat.config}") ChatConfig chatConfig, @Inject("mcp-weather") McpClientToolProvider toolProvider) { return ChatModel.of(chatConfig) .defaultToolsAdd(toolProvider.getTools()) .build(); } @Bean("mcp-weather") public McpClientToolProvider weatherToolProvider() { return McpClientToolProvider.builder() .apiUrl("http://weather-service/mcp/sse") .build(); } } @Service public class WeatherService { @Inject ChatModel chatModel; public String askWeather(String question) { ChatResponse response = chatModel.prompt(question).call(); return response.getContent(); } } 

五、高级特性

1、三种原语内容

 @McpServerEndpoint(sseEndpoint = "/mcp/sse") public class FullFeatureServer { // 工具服务 @ToolMapping(description = "汇率转换") public double exchangeRate( @Param(description = "源货币") String from, @Param(description = "目标货币") String to) { // 实现汇率转换逻辑 return 6.5; } // 资源服务 @ResourceMapping(uri = "config://app-info", description = "获取应用信息") public String getAppInfo() { return "AppName: WeatherService, Version: 1.0.0"; } // 提示语服务 @PromptMapping(description = "生成天气报告提示") public Collection<ChatMessage> weatherReportPrompt( @Param(description = "城市名称") String city) { return Arrays.asList( ChatMessage.ofSystem("你是一个天气报告助手"), ChatMessage.ofUser("请生成" + city + "的天气报告") ); } } 

2、代理模式

 // 将STDIO服务代理为SSE服务 @McpServerEndpoint(sseEndpoint = "/proxy/sse") public class StdioToSseProxy implements ToolProvider { private McpClientProvider stdioClient = McpClientProvider.builder() .channel(McpChannel.STDIO) .serverParameters(ServerParameters.builder("java") .args("-jar", "path/to/stdio-service.jar") .build()) .build(); @Override public Collection<FunctionTool> getTools() { return stdioClient.getTools(); } } // 将SSE服务代理为STDIO服务 @McpServerEndpoint(channel = McpChannel.STDIO) public class SseToStdioProxy implements ToolProvider { private McpClientProvider sseClient = McpClientProvider.builder() .apiUrl("http://remote-service/mcp/sse") .build(); @Override public Collection<FunctionTool> getTools() { return sseClient.getTools(); } } 

3、与Web API互通

 @Controller @McpServerEndpoint(sseEndpoint = "/mcp/sse") public class HybridService { // 同时作为Web API和MCP工具 @ToolMapping(description = "查询库存") @Mapping("/api/inventory") public int getInventory( @Param(description = "产品ID") String productId, @Header("Authorization") String auth) { // 验证逻辑... return 100; // 示例库存 } // 纯Web API @Mapping("/api/info") public String getInfo() { return "Service Info"; } // 纯MCP工具 @ToolMapping(description = "计算折扣") public double calculateDiscount( @Param(description = "原价") double price, @Param(description = "会员等级") String level) { if("VIP".equals(level)) { return price * 0.8; } return price; } } 

六、生产环境注意事项

1、鉴权设计:使用过滤器保护MCP端点

 @Component public class McpAuthFilter implements Filter { @Override public void doFilter(Context ctx, FilterChain chain) throws Throwable { if (ctx.pathNew().startsWith("/mcp/")) { String apiKey = ctx.header("X-API-KEY"); if(!validateApiKey(apiKey)) { ctx.status(401); return; } } chain.doFilter(ctx); } } 

2、客户端配置

 McpClientToolProvider.builder() .apiUrl("http://service/mcp/sse") .apiKey("your-api-key") .httpTimeout(HttpTimeout.builder() .connectTimeout(Duration.ofSeconds(5)) .readTimeout(Duration.ofSeconds(30)) .build()) .requestTimeout(Duration.ofSeconds(20)) .build(); 

3、断线重连:客户端默认支持断线重连,可通过心跳机制保持连接

 @McpServerEndpoint(sseEndpoint = "/mcp/sse", heartbeatInterval = "60s") public class HeartbeatService { // ... } 

七、总结

通过本文,我们学习了如何使用 Java 和 Solon MCP 构建强大的工具服务:

  • 可以创建多种类型的服务端点(SSE/STDIO)
  • 支持动态添加和移除工具
  • 可与 Web API 无缝集成
  • 支持代理模式实现协议转换
  • 提供完整的鉴权和配置方案

MCP 协议特别适合需要与 AI 系统集成的场景,能够将现有服务快速暴露给大模型使用,同时也支持传统的程序间调用。其灵活的通讯方式(进程内/远程)和原语支持(工具/提示/资源)使其成为构建现代分布式系统的有力工具。

在实际项目中,可以根据需求选择 SSE 或 STDIO 通讯方式,或者结合两者使用代理模式。对于需要与 AI 集成的场景,MCP 提供的工具服务描述机制能够大大简化集成工作。

原文链接:https://www.oschina.net/news/359382
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章