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

 更新时间:2025年07月09日 08:55:26   作者:带刺的坐椅  
MCP协议由Anthropic推出,支持stdio/SSE/Streaming通讯,提供工具、提示、资源原语,适用于AI与外部服务集成,兼容Java及多框架,具备鉴权、断线重连等生产特性,助力构建分布式系统,本文给大家介绍Java MCP实战之如何构建跨进程与远程的工具服务,感兴趣的朋友一起看看吧

一、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 提供的工具服务描述机制能够大大简化集成工作。

到此这篇关于Java MCP 实战:构建跨进程与远程的工具服务的文章就介绍到这了,更多相关Java MCP 实战:构建跨进程与远程的工具服务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Boot的无缝衔接实践案例

    Spring Boot的无缝衔接实践案例

    在快速迭代的软件开发环境中,无缝衔接是提升开发效率、降低维护成本、增强系统稳定性的关键,本文将深入解析Spring Boot无缝衔接的几大优势,并通过实际案例和深入分析,展示这些优势如何在项目中发挥作用
    2024-08-08
  • Java 异步编程实践_动力节点Java学院整理

    Java 异步编程实践_动力节点Java学院整理

    异步编程提供了一个非阻塞的,事件驱动的编程模型。下面通过本文给大家介绍Java 异步编程实践,感兴趣的的朋友一起看看吧
    2017-05-05
  • Java Socket 编程详解

    Java Socket 编程详解

    Java Socket 编程是指使用 Java 语言进行网络通信的过程,包括建立连接、传输数据和关闭连接等操作,本文将详细介绍Java Socket编程,需要的朋友可以参考下
    2023-05-05
  • java实现电话本系统

    java实现电话本系统

    这篇文章主要为大家详细介绍了java实现电话本系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • SpringBoot事务不回滚的解决方案

    SpringBoot事务不回滚的解决方案

    这篇文章主要介绍了SpringBoot事务不回滚的解决方案的相关资料,需要的朋友可以参考下
    2022-09-09
  • 详解Java高阶语法Volatile

    详解Java高阶语法Volatile

    这篇文章主要介绍了Java高阶语法Volatile,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • Idea中如何查看SpringSecurity各Filter信息

    Idea中如何查看SpringSecurity各Filter信息

    这篇文章主要介绍了Idea中如何查看SpringSecurity各Filter信息,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • 详解Java中NullPointerException的处理方法

    详解Java中NullPointerException的处理方法

    这篇文章将带大家来单独看一个很常见的异常--空指针异常,这个可以说是每个Java程序员都必知的异常,所以我们不得不单独学习一下,文中有详细的代码示例,需要的朋友可以参考下
    2023-08-08
  • java使用JNA(Java Native Access)调用dll的方法

    java使用JNA(Java Native Access)调用dll的方法

    java使用JNA(Java Native Access)调用windows系统的dll文件的例子
    2013-11-11
  • java反射机制的一些学习心得小结

    java反射机制的一些学习心得小结

    这篇文章主要给大家介绍了关于java反射机制的一些学习心得,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02

最新评论