找回密码
 立即注册
首页 业界区 业界 jFinal 使用 SolonMCP 开发 MCP(拥抱新潮流) ...

jFinal 使用 SolonMCP 开发 MCP(拥抱新潮流)

坪钗 2025-6-2 23:40:21
MCP 官方的 java-sdk 目前只支持 java17+。直接基于 mcp-java-sdk 也比较复杂。使用 SolonMCP,可以基于 java8 开发(像 MVC 的开发风格),且比较简单。
1、SolonMCP 简介

SolonMCP(全称:solon-ai-mcp)是 solon 的一个扩展。支持内嵌到 jfinal,vert.x,springboot2,springboot3 等框架使用。
Maven 主要依赖包:
  1. <dependency>
  2.     <groupId>org.noear</groupId>
  3.     solon-ai-mcp</artifactId>
  4. </dependency>
复制代码
具体的示例参考:

  • https://gitee.com/opensolon/solon-ai-mcp-embedded-examples/tree/main/solon-ai-embedded-jfinal
  • https://gitee.com/opensolon/solon-ai-mcp-embedded-examples/tree/main/solon-ai-embedded-jfinal-newstyle
2、MCP 服务端开发

2.1、添加入口类 webapp.HelloApp(比较空,注意下 mcpServerConfig)

MCP 内部是基于响应式的,需要开启异步支持。
  1. public class HelloApp extends JFinalConfig {
  2.     public static void main(String[] args) {
  3.         UndertowServer.create(HelloApp.class)
  4.                 .setDevMode(false)
  5.                 .setPort(8080)
  6.                 .onDeploy((cl, di) -> {
  7.                     di.getFilters().get("jfinal").setAsyncSupported(true); //注意这个,要开启异步支持
  8.                 }).start();
  9.     }
  10.     public void configConstant(Constants me) {
  11.         me.setDevMode(false);
  12.     }
  13.     public void configRoute(Routes me) {
  14.     }
  15.     public void configEngine(Engine me) {
  16.     }
  17.     public void configPlugin(Plugins me) {
  18.         me.add(mcpServerConfig);
  19.     }
  20.     public void configInterceptor(Interceptors me) {
  21.     }
  22.     public void configHandler(Handlers me) {
  23.         me.add(mcpServerConfig);
  24.     }
  25.     private McpServerConfig mcpServerConfig = new McpServerConfig();
  26. }
复制代码
2.2、添加 webapp.mcpserver.McpServerConfig(实现 Handler、IPlugin 接口)

实现 IPlugin 对接 Solon 的生命周期。实现 Handler 对接 mcp 的请求处理。
  1. public class McpServerConfig extends Handler implements IPlugin {
  2.     public boolean start() {
  3.         Solon.start(McpServerConfig.class, new String[]{"--cfg=mcpserver.yml"});
  4.         return true;
  5.     }
  6.     public boolean stop() {
  7.         if (Solon.app() != null) {
  8.             Solon.stopBlock(false, Solon.cfg().stopDelay());
  9.         }
  10.         return true;
  11.     }
  12.     @Override
  13.     public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
  14.         if (target.startsWith("/mcp/")) {
  15.             Context ctx = new SolonServletContext(request, response);
  16.             try {
  17.                 //Solon处理(可能是空处理)
  18.                 Solon.app().tryHandle(ctx);
  19.                 if (isHandled != null && isHandled.length > 0) {
  20.                     isHandled[0] = true;
  21.                 }
  22.             } catch (Throwable e) {
  23.                 ctx.errors = e;
  24.                 throw e;
  25.             } finally {
  26.                 ContextUtil.currentRemove();
  27.             }
  28.         } else {
  29.             if (next != null) {
  30.                 next.handle(target, request, response, isHandled);
  31.             }
  32.         }
  33.     }
  34. }
复制代码
2.3、添加 webapp.mcpserver.tool.McpServer(实现 Handler、IPlugin 接口)

这里是重点了,添加 mcp server 端点(支持多个端点)
  1. @McpServerEndpoint(sseEndpoint = "/mcp/sse")
  2. public class McpServer {
  3.     //
  4.     // 建议开启编译参数:-parameters (否则,最好再配置参数的 name)
  5.     //
  6.     @ToolMapping(description = "查询天气预报")
  7.     public String getWeather(@Param(description = "城市位置") String location) {
  8.         return "晴,14度";
  9.     }
  10.     @ResourceMapping(uri = "config://app-version", description = "获取应用版本号")
  11.     public String getAppVersion() {
  12.         return "v3.2.0";
  13.     }
  14.     @ResourceMapping(uri = "db://users/{user_id}/email", description = "根据用户ID查询邮箱")
  15.     public String getEmail(@Param(description = "用户Id") String user_id) {
  16.         return user_id + "@example.com";
  17.     }
  18.     @PromptMapping(description = "生成关于某个主题的提问")
  19.     public Collection<ChatMessage> askQuestion(@Param(description = "主题") String topic) {
  20.         return Arrays.asList(
  21.                 ChatMessage.ofUser("请解释一下'" + topic + "'的概念?")
  22.         );
  23.     }
  24. }
复制代码
2.4、编译后运行

或者开发时,直接运行 HelloApp:main 方法
3、MCP 客户端开发

客户端简单些
  1. public class McpClientTest {
  2.     public static void main(String[] args) throws Exception {
  3.         McpClientProvider toolProvider = McpClientProvider.builder()
  4.                 .apiUrl("http://localhost:8080/mcp/sse")
  5.                 .build();
  6.         //工具调用
  7.         Map<String, Object> map = Collections.singletonMap("location", "杭州");
  8.         String rst = toolProvider.callToolAsText("getWeather", map).getContent();
  9.         System.out.println(rst);
  10.         assert "晴,14度".equals(rst);
  11.         
  12.         
  13.         //资源读取
  14.         resourceContent = toolProvider.readResourceAsText("config://app-version").getContent();
  15.         System.out.println(resourceContent);
  16.     }
  17. }
复制代码
4、MCP 客户端作为 LLM(ChatModel) 的工具集使用

也比较简单。使用 ollama 做为 llm 提供者,方便本地测试。
  1. public class McpClientTest {
  2.     private static final String apiUrl = "http://127.0.0.1:11434/api/chat";
  3.     private static final String provider = "ollama";
  4.     private static final String model = "qwen2.5:1.5b"; //"llama3.2";//deepseek-r1:1.5b;
  5.    
  6.     public static void main(String[] args) throws Exception {
  7.         //构建 mcp client
  8.         McpClientProvider toolProvider = McpClientProvider.builder()
  9.                 .apiUrl("http://localhost:8080/mcp/sse")
  10.                 .build();
  11.         //构建 llm 接口
  12.         ChatModel chatModel = ChatModel.of(apiUrl)
  13.                 .provider(provider)
  14.                 .model(model)
  15.                 .defaultToolsAdd(toolProvider) //添加默认工具(这是 mcp client)
  16.                 .build();
  17.         
  18.         //请求
  19.         ChatResponse resp = chatModel.prompt("杭州今天的天气怎么样?")
  20.                 .call();
  21.         System.out.println(resp.getMessage());
  22.     }
  23. }
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册