SpringBoot2 可以使用 SolonMCP 开发 MCP(江湖救急)

MCP 官方的 java-sdk 目前要求 java17+(直接使用 sdk 也比较复杂)。Spring-AI(有 MCP 内容)也是要求 java17+。

SpringBoot2 怎么办?

使用 SolonMCP,可以支持 java8、java11、java17、java21 开发,可以内嵌到 SpringMVC 和 SpringBoot2 Web 里。

1、SolonMCP 简介

SolonMCP(全称:solon-ai-mcp)是 solon 的一个扩展。支持内嵌到 jfinal,vert.x,springboot2,springboot3 等框架使用。

Maven 主要依赖包:

xml 复制代码
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-ai-mcp</artifactId>
</dependency>

具体的示例参考:

2、MCP 服务端开发

2.1、添加入口类 webapp.HelloApp

java 复制代码
@SpringBootApplication
public class HelloApp {
    public static void main(String[] args) {
        SpringApplication.run(HelloApp.class, args);
    }

2.2、添加个空接口 webapp.mcpserver.IMcpServerEndpoint

用于识别端点组件类

java 复制代码
public interface IMcpServerEndpoint { }

2.3、添加 webapp.mcpserver.McpServerConfig

拖管 solon 的生命周期。收集 IMcpServerEndpoint 组件,并转为 McpServerEndpointProvider

java 复制代码
@Configuration
public class McpServerConfig {
    @PostConstruct
    public void start() {
        Solon.start(McpServerConfig.class, new String[]{"--cfg=mcpserver.yml"});
    }

    @PreDestroy
    public void stop() {
        if (Solon.app() != null) {
            Solon.stopBlock(false, Solon.cfg().stopDelay());
        }
    }

    @Bean
    public McpServerConfig init(List<IMcpServerEndpoint> serverEndpoints) {
        for (IMcpServerEndpoint serverEndpoint : serverEndpoints) {
            //这里注意一下,如果有代理的话需要用 AnnotationUtils 获取注解
            McpServerEndpoint anno = AnnotationUtils.findAnnotation(serverEndpoint.getClass(), McpServerEndpoint.class);

            if (anno == null) {
                continue;
            }

            McpServerEndpointProvider serverEndpointProvider = McpServerEndpointProvider.builder()
                    .from(serverEndpoint.getClass(), anno)
                    .build();

            serverEndpointProvider.addTool(new MethodToolProvider(serverEndpoint));
            serverEndpointProvider.addResource(new MethodResourceProvider(serverEndpoint));
            serverEndpointProvider.addPrompt(new MethodPromptProvider(serverEndpoint));

            serverEndpointProvider.postStart();

            //可以再把 serverEndpointProvider 手动转入 SpringBoot 容器
        }

        //为了能让这个 init 能正常运行
        return this;
    }

    @Bean
    public FilterRegistrationBean mcpServerFilter() {
        FilterRegistrationBean<SolonServletFilter> filter = new FilterRegistrationBean<>();
        filter.setName("SolonFilter");
        filter.addUrlPatterns("/mcp/*");
        filter.setFilter(new SolonServletFilter());
        return filter;
    }
}

2.4、添加 webapp.mcpserver.tool.McpServer(实现 Handler、IPlugin 接口)

这里是重点了,添加 mcp server 端点(支持多个端点)。这里是正常的 SpringBoot 组件开发了。

java 复制代码
@Component //注意这个注解别用错了(solon 里也有同名的)
@McpServerEndpoint(name="demo1", sseEndpoint = "/mcp/demo1/sse")
public class McpServerTool implements IMcpServerEndpoint {
    //
    // 建议开启编译参数:-parameters (否则,最好再配置参数的 name)
    //
    @ToolMapping(description = "查询天气预报")
    public String getWeather(@Param(description = "城市位置") String location) {
        return "晴,14度";
    }

    @ResourceMapping(uri = "config://app-version", description = "获取应用版本号")
    public String getAppVersion() {
        return "v3.2.0";
    }

    @ResourceMapping(uri = "db://users/{user_id}/email", description = "根据用户ID查询邮箱")
    public String getEmail(@Param(description = "用户Id") String user_id) {
        return user_id + "@example.com";
    }

    @PromptMapping(description = "生成关于某个主题的提问")
    public Collection<ChatMessage> askQuestion(@Param(description = "主题") String topic) {
        return Arrays.asList(
                ChatMessage.ofUser("请解释一下'" + topic + "'的概念?")
        );
    }
}

2.5、编译后运行

或者开发时,直接运行 HelloApp:main 方法

3、MCP 客户端开发

客户端简单些

java 复制代码
public class McpClientTest {
    public static void main(String[] args) throws Exception {
        McpClientProvider toolProvider = McpClientProvider.builder()
                .apiUrl("http://localhost:8080/mcp/sse")
                .build();

        //工具调用
        Map<String, Object> map = Collections.singletonMap("location", "杭州");
        String rst = toolProvider.callToolAsText("getWeather", map).getContent();
        System.out.println(rst);
        assert "晴,14度".equals(rst);
        
        
        //资源读取
        resourceContent = toolProvider.readResourceAsText("config://app-version").getContent();
        System.out.println(resourceContent);
    }
}

4、MCP 客户端作为 LLM(ChatModel) 的工具集使用

也比较简单。使用 ollama 做为 llm 提供者,方便本地测试。

java 复制代码
public class McpClientTest {
    private static final String apiUrl = "http://127.0.0.1:11434/api/chat";
    private static final String provider = "ollama";
    private static final String model = "qwen2.5:1.5b"; //"llama3.2";//deepseek-r1:1.5b;
    
    public static void main(String[] args) throws Exception {
        //构建 mcp client
        McpClientProvider toolProvider = McpClientProvider.builder()
                .apiUrl("http://localhost:8080/mcp/sse")
                .build();

        //构建 llm 接口
        ChatModel chatModel = ChatModel.of(apiUrl)
                .provider(provider)
                .model(model)
                .defaultToolsAdd(toolProvider) //添加默认工具(这是 mcp client)
                .build();
        
        //请求
        ChatResponse resp = chatModel.prompt("杭州今天的天气怎么样?")
                .call();

        System.out.println(resp.getMessage());
    }
}
相关推荐
小信丶7 分钟前
Spring Cloud Stream EnableBinding注解详解:定义、应用场景与示例代码
java·spring boot·后端·spring
无限进步_11 分钟前
【C++】验证回文字符串:高效算法详解与优化
java·开发语言·c++·git·算法·github·visual studio
亚历克斯神12 分钟前
Spring Cloud 2026 架构演进
java·spring·微服务
七夜zippoe15 分钟前
Spring Cloud与Dubbo架构哲学对决
java·spring cloud·架构·dubbo·配置中心
海派程序猿15 分钟前
Spring Cloud Config拉取配置过慢导致服务启动延迟的优化技巧
java
call me by ur name20 分钟前
ERNIE 5.0 Technical Report论文解读
android·开发语言·人工智能·机器学习·ai·kotlin
阿维的博客日记26 分钟前
为什么不逃逸代表不需要锁,JIT会直接删掉锁
java
William Dawson28 分钟前
CAS的底层实现
java
九英里路39 分钟前
cpp容器——string模拟实现
java·前端·数据结构·c++·算法·容器·字符串
YDS82943 分钟前
大营销平台 —— 抽奖前置规则过滤
java·spring boot·ddd