初恋这件事 發表於 2025-5-15 11:13:00

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

<p>MCP 官方的 java-sdk 目前要求 java17+(直接使用 sdk 也比较复杂)。Spring-AI(有 MCP 内容)也是要求 java17+。</p>
<p>SpringBoot2 怎么办?</p>
<p>使用 SolonMCP,可以支持 java8、java11、java17、java21 开发,可以内嵌到 SpringMVC 和 SpringBoot2 Web 里。</p>
<h3 id="1solonmcp-简介">1、SolonMCP 简介</h3>
<p>SolonMCP(全称:solon-ai-mcp)是 solon 的一个扩展。支持内嵌到 jfinal,vert.x,springboot2,springboot3 等框架使用。</p>
<p>Maven 主要依赖包:</p>
<pre><code class="language-xml">&lt;dependency&gt;
    &lt;groupId&gt;org.noear&lt;/groupId&gt;
    &lt;artifactId&gt;solon-ai-mcp&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre>
<p>具体的示例参考:</p>
<ul>
<li>https://gitee.com/opensolon/solon-ai-mcp-embedded-examples/tree/main/solon-ai-embedded-springboot2</li>
<li>https://gitee.com/opensolon/solon-ai-mcp-embedded-examples/tree/main/solon-ai-embedded-springboot3-newstyle</li>
</ul>
<h3 id="2mcp-服务端开发">2、MCP 服务端开发</h3>
<h4 id="21添加入口类-webapphelloapp">2.1、添加入口类 <code>webapp.HelloApp</code></h4>
<pre><code class="language-java">@SpringBootApplication
public class HelloApp {
    public static void main(String[] args) {
      SpringApplication.run(HelloApp.class, args);
    }
</code></pre>
<h4 id="22添加个空接口-webappmcpserverimcpserverendpoint">2.2、添加个空接口 <code>webapp.mcpserver.IMcpServerEndpoint</code></h4>
<p>用于识别端点组件类</p>
<pre><code class="language-java">public interface IMcpServerEndpoint { }
</code></pre>
<h4 id="23添加-webappmcpservermcpserverconfig">2.3、添加 <code>webapp.mcpserver.McpServerConfig</code></h4>
<p>拖管 solon 的生命周期。收集 IMcpServerEndpoint 组件,并转为 McpServerEndpointProvider</p>
<pre><code class="language-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&lt;IMcpServerEndpoint&gt; 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&lt;SolonServletFilter&gt; filter = new FilterRegistrationBean&lt;&gt;();
      filter.setName("SolonFilter");
      filter.addUrlPatterns("/mcp/*");
      filter.setFilter(new SolonServletFilter());
      return filter;
    }
}
</code></pre>
<h4 id="24添加-webappmcpservertoolmcpserver实现-handleriplugin-接口">2.4、添加 <code>webapp.mcpserver.tool.McpServer</code>(实现 Handler、IPlugin 接口)</h4>
<p>这里是重点了,添加 mcp server 端点(支持多个端点)。这里是正常的 SpringBoot 组件开发了。</p>
<pre><code class="language-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&lt;ChatMessage&gt; askQuestion(@Param(description = "主题") String topic) {
      return Arrays.asList(
                ChatMessage.ofUser("请解释一下'" + topic + "'的概念?")
      );
    }
}
</code></pre>
<h4 id="25编译后运行">2.5、编译后运行</h4>
<p>或者开发时,直接运行 <code>HelloApp:main</code> 方法</p>
<h3 id="3mcp-客户端开发">3、MCP 客户端开发</h3>
<p>客户端简单些</p>
<pre><code class="language-java">public class McpClientTest {
    public static void main(String[] args) throws Exception {
      McpClientProvider toolProvider = McpClientProvider.builder()
                .apiUrl("http://localhost:8080/mcp/sse")
                .build();

      //工具调用
      Map&lt;String, Object&gt; 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);
    }
}
</code></pre>
<h3 id="4mcp-客户端作为-llmchatmodel-的工具集使用">4、MCP 客户端作为 LLM(ChatModel) 的工具集使用</h3>
<p>也比较简单。使用 ollama 做为 llm 提供者,方便本地测试。</p>
<pre><code class="language-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());
    }
}
</code></pre><br><br>
来源:https://www.cnblogs.com/noear/p/18877378
頁: [1]
查看完整版本: SpringBoot2 可以使用 SolonMCP 开发 MCP(江湖救急)