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

MCP 官方的 java-sdk 目前只支持 java17+。直接基于 mcp-java-sdk 也比较复杂。使用 SolonMCP,可以基于 java8 开发(像 MVC 的开发风格),且比较简单。

1、SolonMCP 简介

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

Maven 主要依赖包:

<dependency>     <groupId>org.noear</groupId>     <artifactId>solon-ai-mcp</artifactId> </dependency> 

具体的示例参考:

2、MCP 服务端开发

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

MCP 内部是基于响应式的,需要开启异步支持。

public class HelloApp extends JFinalConfig {     public static void main(String[] args) {         UndertowServer.create(HelloApp.class)                 .setDevMode(false)                 .setPort(8080)                 .onDeploy((cl, di) -> {                     di.getFilters().get("jfinal").setAsyncSupported(true); //注意这个,要开启异步支持                 }).start();     }      public void configConstant(Constants me) {         me.setDevMode(false);     }      public void configRoute(Routes me) {     }      public void configEngine(Engine me) {     }      public void configPlugin(Plugins me) {         me.add(mcpServerConfig);     }      public void configInterceptor(Interceptors me) {     }      public void configHandler(Handlers me) {         me.add(mcpServerConfig);     }      private McpServerConfig mcpServerConfig = new McpServerConfig(); } 

2.2、添加 webapp.mcpserver.McpServerConfig(实现 Handler、IPlugin 接口)

实现 IPlugin 对接 Solon 的生命周期。实现 Handler 对接 mcp 的请求处理。

public class McpServerConfig extends Handler implements IPlugin {     public boolean start() {         Solon.start(McpServerConfig.class, new String[]{"--cfg=mcpserver.yml"});         return true;     }      public boolean stop() {         if (Solon.app() != null) {             Solon.stopBlock(false, Solon.cfg().stopDelay());         }         return true;     }      @Override     public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {         if (target.startsWith("/mcp/")) {             Context ctx = new SolonServletContext(request, response);              try {                 //Solon处理(可能是空处理)                 Solon.app().tryHandle(ctx);                  if (isHandled != null && isHandled.length > 0) {                     isHandled[0] = true;                 }             } catch (Throwable e) {                 ctx.errors = e;                  throw e;             } finally {                 ContextUtil.currentRemove();             }         } else {             if (next != null) {                 next.handle(target, request, response, isHandled);             }         }     } } 

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

这里是重点了,添加 mcp server 端点(支持多个端点)

@McpServerEndpoint(sseEndpoint = "/mcp/sse") public class McpServer {     //     // 建议开启编译参数:-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.4、编译后运行

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

3、MCP 客户端开发

客户端简单些

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 提供者,方便本地测试。

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());     } } 

发表评论

评论已关闭。

相关文章