Java 设计 MCP SSE 配置

@[toc]

简述

在开发一个结合了 Server-Sent Events (SSE) 和 Model Context Protocol (MCP) 的Java应用时,目标是构建一个能够实时与AI模型交互并接收更新的系统。这样的系统可以用于多种场景,比如实时数据分析、智能监控或个性化推荐等。下面是一个基于Spring Boot框架的示例,展示了如何使用Java来实现这种类型的集成。

当前 mcp 情况

默认方式 spring支持
stdio webflux sse
sse webmvc sse4.2
studio

使用 Cherry studio 作为 ai 引擎

配置 mcp 链接 选择 类型为 sse, 地址为spring boot 项目启动地址

问答情况

mcp 服务配置类

配置 McpServerConfig

java 复制代码
package com.mcp;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpSyncServer;
import io.modelcontextprotocol.server.transport.StdioServerTransportProvider;
import io.modelcontextprotocol.server.transport.WebFluxSseServerTransportProvider;
import io.modelcontextprotocol.spec.McpSchema;
import io.modelcontextprotocol.spec.McpServerTransportProvider;
import org.springframework.ai.mcp.McpToolUtils;
import org.springframework.ai.support.ToolCallbacks;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;

@Configuration
public class McpServerConfig {
	
    @Bean
    @ConditionalOnProperty(prefix = "transport", name = "mode", havingValue = "stdio")
    public StdioServerTransportProvider stdioServerTransportProvider() {
        return new StdioServerTransportProvider();
    }

    @Bean
    @ConditionalOnProperty(prefix = "transport", name = "mode", havingValue = "sse")
    public WebFluxSseServerTransportProvider sseServerTransportProvider() {
        return new WebFluxSseServerTransportProvider(new ObjectMapper(), "/mcp/message");
    }

    @Bean
    @ConditionalOnProperty(prefix = "transport", name = "mode", havingValue = "sse")
    public RouterFunction<?> mcpRouterFunction(WebFluxSseServerTransportProvider transportProvider) {
        return transportProvider.getRouterFunction();
    }

    @Bean
    public McpToolClient mcpToolClient() {
        return new McpToolClient();
    }
	
    @Bean
    public McpSyncServer mcpServer(McpServerTransportProvider transportProvider, McpToolClient mcpToolClient) { 

        var capabilities = McpSchema.ServerCapabilities.builder()
                .tools(true) 
                .logging() 
                .build();
		
        McpSyncServer server = McpServer.sync(transportProvider)
                .serverInfo("MCP Demo Weather Server", "1.0.0")
                .capabilities(capabilities)
                .tools(McpToolUtils.toSyncToolSpecifications(ToolCallbacks.from(mcpToolClient)))
                .build();

        return server;
    }


}

@ConditionalOnProperty

元素 说明
@Bean 告诉 Spring 容器:这是一个需要注册为 Bean 的方法。返回的对象会被加入 Spring 应用上下文中。
@ConditionalOnProperty(...) 只有在满足指定的配置属性时才创建这个 Bean。
prefix = "transport" 属性前缀,表示我们要检查的是以 transport. 开头的配置项。
name = "mode" 要检查的属性名是 mode,即完整的属性路径是 transport.mode
havingValue = "stdio" 只有当 transport.mode=stdio 时才会加载这个 Bean。
方法体 如果条件成立,则返回一个新的 StdioServerTransportProvider 实例。

STDIO 传输配置

作用:创建一个基于标准输入输出(stdin/stdout)的传输层。 条件加载:仅当 application.properties 中配置了 transport.mode=stdio 时才会加载。

java 复制代码
@Bean
@ConditionalOnProperty(prefix = "transport", name = "mode", havingValue = "stdio")
public StdioServerTransportProvider stdioServerTransportProvider() {
    return new StdioServerTransportProvider();
}

SSE 传输配置

作用:创建基于 HTTP + SSE 的传输层。 路径:/mcp/message 是客户端连接的端点。 依赖:需要 spring-boot-starter-webflux 支持。

java 复制代码
@Bean
@ConditionalOnProperty(prefix = "transport", name = "mode", havingValue = "sse")
public WebFluxSseServerTransportProvider sseServerTransportProvider() {
    return new WebFluxSseServerTransportProvider(new ObjectMapper(), "/mcp/message");
}

路由器

作用:将 MCP 服务绑定到 WebFlux 路由中,启动 HTTP 服务器。

java 复制代码
@Bean
@ConditionalOnProperty(prefix = "transport", name = "mode", havingValue = "sse")
public RouterFunction<?> mcpRouterFunction(WebFluxSseServerTransportProvider transportProvider) {
    return transportProvider.getRouterFunction();
}

工具客户端 Bean

作用:注册一个 MCP 工具客户端,用于处理 MCP 客户端发起的工具调用请求。

java 复制代码
@Bean
public McpToolClient mcpToolClient() {
    return new McpToolClient();
}

创建 MCP 同步服务器

参数说明:
  • transportProvider:根据配置选择的传输方式(stdio 或 sse)
  • weatherApiClient:提供工具调用逻辑的客户端
服务器功能说明:
  • 设置服务器能力:
    • 支持工具调用 .tools(true)
    • 支持日志功能 .logging()
  • 添加工具:
    • 使用 ToolCallbacks.from(...) 提取 @Tool 注解的方法
    • 使用 McpToolUtils.toSyncToolSpecifications(...) 转换为 MCP 工具规范
    • 构建并返回同步的 MCP 服务器实例
java 复制代码
@Bean
public McpSyncServer mcpServer(McpServerTransportProvider transportProvider, McpToolClient mcpToolClient) { 

    var capabilities = McpSchema.ServerCapabilities.builder()
            .tools(true) 
            .logging() 
            .build();
	
    McpSyncServer server = McpServer.sync(transportProvider)
            .serverInfo("MCP Demo Weather Server", "1.0.0")
            .capabilities(capabilities)
            .tools(McpToolUtils.toSyncToolSpecifications(ToolCallbacks.from(mcpToolClient)))
            .build();

    return server;
}

Client 类

@Tool(description = "Testing method, used to test whether the tool is called") 表示这是一个工具方法。 描述信息将被用于生成工具文档或提供给模型理解用途。

java 复制代码
package com.mcp;

import org.springframework.ai.tool.annotation.Tool;

import java.text.SimpleDateFormat;
import java.util.Date;

public class McpToolClient {


    @Tool(description = "Testing method, used to test whether the tool is called")
    public String helloworld(){
        return "hello, world";
    }

    @Tool(description = "获取当前时间")
    public String nowTime(){
        // 定义日期格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 获取当前时间
        Date now = new Date();
        // 转换为字符串
        String nowStr = sdf.format(now);
        return "当前时间: " + nowStr;
    }
}

yaml 文件配置

yaml 复制代码
server:
  port: 8080

spring:
  main:
    banner-mode: OFF

transport:
  mode: sse

logging:
  file:
    name: mcp.weather.log

项目maven 信息导入配置

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.5</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.mcp</groupId>
    <artifactId>mcp-test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mcp-test</name>
    <description>Demo project for Spring Boot</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.version>
        <mcp.version>0.10.0</mcp.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-model</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-mcp</artifactId>
        </dependency>

        <dependency>
            <groupId>io.modelcontextprotocol.sdk</groupId>
            <artifactId>mcp-spring-webflux</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>1.1.0-SNAPSHOT</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>io.modelcontextprotocol.sdk</groupId>
                <artifactId>mcp-bom</artifactId>
                <version>${mcp.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
        <repository>
            <id>central-portal-snapshots</id>
            <name>Central Portal Snapshots</name>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
</project>

项目地址

项目地址

相关推荐
许商2 分钟前
【stm32】【printf】
java·前端·stm32
JIngJaneIL11 分钟前
智慧物业|物业管理|基于SprinBoot+vue的智慧物业管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·论文·智慧物业管理系统
ANYOLY24 分钟前
Redis 面试题库
java·redis·面试
凌览29 分钟前
一键去水印|5 款免费小红书解析工具推荐
前端·javascript·后端
枫叶梨花30 分钟前
一次 Kettle 中文乱码写入失败的完整排查实录
数据库·后端
expect7g30 分钟前
Paimon源码解读 -- PartialUpdateMerge
大数据·后端·flink
懒惰蜗牛31 分钟前
Day63 | Java IO之NIO三件套--选择器(下)
java·nio·选择器·selector·半包粘包·tcp缓冲区
申阳35 分钟前
Day 16:02. 基于 Tauri 2.0 开发后台管理系统-项目初始化配置
前端·后端·程序员
bcbnb36 分钟前
游戏上架 App Store 的完整发行流程,从构建、合规到审核的多角色协同指南
后端
JavaGuide37 分钟前
美团2026届后端一二面(附详细参考答案)
java·后端