Cool
Cool
Published on 2025-04-25 / 11 Visits
0
0

用java对已有的项目搭建 mcpServer

用java对已有的项目搭建 mcpServer
运行环境:java17 springboot 3.0

首先导入两个依赖坐标

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

注册mcp config 的bean

import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.ServerResponse;

@Configuration
public class McpConfig implements WebMvcConfigurer {
    @Bean
    public WebMvcSseServerTransportProvider webMvcSseServerTransportProvider(ObjectMapper mapper) {
        return new WebMvcSseServerTransportProvider(mapper, "/message","/sse");
    }
    @Bean
    public RouterFunction<ServerResponse> mvcRouterFunction(WebMvcSseServerTransportProvider webMvcSseServerTransportProvider) {
        return webMvcSseServerTransportProvider.getRouterFunction();
    }
}

编写mcp sever的信息和注册器

@Service
public class MyServer {
    @Autowired
    WebMvcSseServerTransportProvider provider;

    @PostConstruct
    public void start() {
        //创建并配置mcp同步服务器
        McpSyncServer syncServer = McpServer.sync(provider)
                .serverInfo("my-server", "1.0.0")
            .capabilities(McpSchema.ServerCapabilities.builder().tools(true).logging().build())
                .build();
       
    }}

一个mcp server 可以有很多工具 所以定义一个工具
先定义接口,我的接口参数是 keyword,可以参考mcp 官方的写法:https://docs.openwebui.com/openapi-servers/mcp


 //定义表示参数列表的json字符串
        var schema = """
            {
              "type" : "object",
              "id" : "urn:jsonschema:Operation",
              "properties" : {
                "keyword" : {
                  "type" : "string"
                }
              }
            }
            """;

一个工具需要两个参数

  //定义工具
        McpServerFeatures.SyncToolSpecification syncToolSpecification = new McpServerFeatures.SyncToolSpecification(tool, call);

接下来定义 tool 和定义 call

 //定义函数名称(函数) 描述 参数列表 函数体
        McpSchema.Tool tool = new McpSchema.Tool("getMagnets", "根据关键字keyword查询演员或者番号的磁力文件", schema);
        BiFunction<McpSyncServerExchange, Map<String, Object>, McpSchema.CallToolResult> call = new BiFunction<>() {
            @Override
            public McpSchema.CallToolResult apply(McpSyncServerExchange exchange, Map<String, Object> objectMap) {
                List<McpSchema.Content> result = new ArrayList<>();

                Object o_keyword = objectMap.get("keyword");
                if (o_keyword == null) {
                    result.add(new McpSchema.TextContent("错误:关键字不能为空"));
                    return new McpSchema.CallToolResult(result, true);
                }
                System.out.println(o_keyword.toString());
                String keyword = o_keyword.toString();
                String body = HttpRequest.get("http://127.0.0.1:5000/api/mcp/searchByKeyWord?keyword=" + keyword).execute().body();

                //调用远程服务查询
                String resultText = body;
                if (!resultText.isEmpty()) {
                    result.add(new McpSchema.TextContent(resultText));
                } else {
                    result.add(new McpSchema.TextContent("搜索错误"));
                }
                return new McpSchema.CallToolResult(result, false);
            }
        };

有了工具之后,就可以在mcp服务器给添加上了

   //添加服务器
        syncServer.addTool(syncToolSpecification);

以下是完整代码:

package com.fangliang.javdbmcpserver.server;

import cn.hutool.http.HttpRequest;
import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.server.McpSyncServer;
import io.modelcontextprotocol.server.McpSyncServerExchange;
import io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider;
import io.modelcontextprotocol.spec.McpSchema;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;

@Service
public class MyServer {
    @Autowired
    WebMvcSseServerTransportProvider provider;

    @PostConstruct
    public void start() {
        //创建并配置mcp同步服务器
        McpSyncServer syncServer = McpServer.sync(provider)
                .serverInfo("my-server", "1.0.0")
                .capabilities(McpSchema.ServerCapabilities.builder().tools(true).logging().build())
                .build();
        getMagnets(syncServer);
    }


    public void getMagnets(McpSyncServer syncServer) {
        //定义表示参数列表的json字符串
        var schema = """
                {
                  "type" : "object",
                  "id" : "urn:jsonschema:Operation",
                  "properties" : {
                    "keyword" : {
                      "type" : "string"
                    }
                  }
                }
                """;

        //定义函数名称(函数) 描述 参数列表 函数体
        McpSchema.Tool tool = new McpSchema.Tool("getMagnets", "根据关键字keyword查询演员或者番号的磁力文件", schema);
        BiFunction<McpSyncServerExchange, Map<String, Object>, McpSchema.CallToolResult> call = new BiFunction<>() {
            @Override
            public McpSchema.CallToolResult apply(McpSyncServerExchange exchange, Map<String, Object> objectMap) {
                List<McpSchema.Content> result = new ArrayList<>();

                Object o_keyword = objectMap.get("keyword");
                if (o_keyword == null) {
                    result.add(new McpSchema.TextContent("错误:关键字不能为空"));
                    return new McpSchema.CallToolResult(result, true);
                }
                System.out.println(o_keyword.toString());
                String keyword = o_keyword.toString();
                String body = HttpRequest.get("http://127.0.0.1:5000/api/mcp/searchByKeyWord?keyword=" + keyword).execute().body();

                //调用远程服务查询
                String resultText = body;
                if (!resultText.isEmpty()) {
                    result.add(new McpSchema.TextContent(resultText));
                } else {
                    result.add(new McpSchema.TextContent("搜索错误"));
                }
                return new McpSchema.CallToolResult(result, false);
            }
        };
        //定义工具
        McpServerFeatures.SyncToolSpecification syncToolSpecification = new McpServerFeatures.SyncToolSpecification(tool, call);
        //添加服务器
        syncServer.addTool(syncToolSpecification);

        System.out.println("已添加磁力文件搜索");
    }
}

mcpserver 配置到我们的idea cursor 等工具
打开配置文件,因为我们的是基于http,所以写接口地址就行,javdb 就是我创建的mcpserver

{
    "mcpServers": {
        "javdb": {
            "url": "http://159.75.79.235:5002/sse",
            "env": {
                "API_KEY": "value"
            }
        }
    }
}

还有一种写法 目前没验证过 应该是用不了的 和这套框架不匹配

"javdb": {
            "timeout": 90,
            "command": "C:\\Users\\Cool\\.jdks\\openjdk-22.0.1\\bin\\java",
            "args": [
                "-Dspring.ai.mcp.server.stdio=true",
                "-jar",
                "D:\\workspace\\javdbmcpserver\\target\\javdbmcpserver-0.0.1-SNAPSHOT.jar"

            ],
            "env": {},
            "transportType": "stdio"
        }

Comment