ava生态的MCP服务器开发:构建企业级模型上下文协议服务



在MCP(Model Context Protocol)生态系统日益壮大的今天,Java开发者同样可以构建强大的MCP服务器,无需依赖Python技术栈。本文将深入探讨如何使用Java构建功能完整的MCP服务器,并集成到现代AI应用中。


## Java MCP服务器基础架构


基于Java的MCP服务器具备类型安全、高性能和强大的生态系统支持等优势。


```java

// MCP协议核心定义

public class MCPProtocol {

    

    public static class MCPRequest {

        private String jsonrpc = "2.0";

        private String id;

        private String method;

        private Map params;

        

        // 构造函数、getter、setter

        public MCPRequest(String method, Map params) {

            this.id = UUID.randomUUID().toString();

            this.method = method;

            this.params = params;

<"www.tongchuan.gov.cn.felli.cn">

<"www.miaoli.gov.cn.felli.cn">

<"www.zhanghua.gov.cn.felli.cn">

        }

    }

    

    public static class MCPResponse {

        private String jsonrpc = "2.0";

        private String id;

        private Map result;

        private MCPError error;

        

        // 构造函数、getter、setter

        public static MCPResponse success(String requestId, Map result) {

            MCPResponse response = new MCPResponse();

            response.id = requestId;

            response.result = result;

            return response;

        }

        

        public static MCPResponse error(String requestId, int code, String message) {

            MCPResponse response = new MCPResponse();

            response.id = requestId;

            response.error = new MCPError(code, message);

            return response;

        }

    }

    

    public static class MCPError {

        private int code;

        private String message;

        

        public MCPError(int code, String message) {

            this.code = code;

            this.message = message;

        }

    }

}


// MCP服务器基类

public abstract class MCPServer {

    protected final Gson gson = new Gson();

    protected final Map tools = new ConcurrentHashMap<>();

    protected final Map resources = new ConcurrentHashMap<>();

    

    public MCPServer() {

        initializeTools();

        initializeResources();

<"www.nantou.gov.cn.felli.cn">

<"www.yunlin.gov.cn.felli.cn">

<"www.huangshi.gov.cn.felli.cn">

    }

    

    protected abstract void initializeTools();

    protected abstract void initializeResources();

    

    public MCPResponse handleRequest(String jsonRequest) {

        try {

            MCPRequest request = gson.fromJson(jsonRequest, MCPRequest.class);

            

            switch (request.getMethod()) {

                case "initialize":

                    return handleInitialize(request);

                case "tools/list":

                    return handleToolsList(request);

                case "tools/call":

                    return handleToolCall(request);

                case "resources/list":

                    return handleResourcesList(request);

                case "resources/read":

                    return handleResourceRead(request);

                default:

                    return MCPResponse.error(request.getId(), -32601, "Method not found");

            }

        } catch (Exception e) {

            return MCPResponse.error(null, -32700, "Parse error: " + e.getMessage());

        }

    }

    

    protected MCPResponse handleInitialize(MCPRequest request) {

        Map result = new HashMap<>();

        result.put("protocolVersion", "2024-11-07");

        result.put("capabilities", Map.of(

            "tools", Map.of("listChanged", true),

            "resources", Map.of("listChanged", true)

        ));

        result.put("serverInfo", Map.of(

            "name", getServerName(),

            "version", "1.0.0"

<"www.shiyan.gov.cn.felli.cn">

<"www.yichang.gov.cn.felli.cn">

<"www.xiangyang.gov.cn.felli.cn">

        ));

        return MCPResponse.success(request.getId(), result);

    }

    

    protected MCPResponse handleToolsList(MCPRequest request) {

        List> toolsList = tools.values().stream()

            .map(Tool::toMap)

            .collect(Collectors.toList());

        

        return MCPResponse.success(request.getId(), Map.of("tools", toolsList));

    }

    

    protected MCPResponse handleToolCall(MCPRequest request) {

        @SuppressWarnings("unchecked")

        Map params = (Map) request.getParams();

        String toolName = (String) params.get("name");

        @SuppressWarnings("unchecked")

        Map arguments = (Map) params.get("arguments");

        

        Tool tool = tools.get(toolName);

        if (tool == null) {

            return MCPResponse.error(request.getId(), -32601, "Tool not found: " + toolName);

        }

        

        try {

            Object result = tool.execute(arguments);

            return MCPResponse.success(request.getId(), Map.of("content", result));

        } catch (Exception e) {

            return MCPResponse.error(request.getId(), -32603, "Tool execution failed: " + e.getMessage());

        }

    }

    

    protected abstract String getServerName();

}

```


## 工具系统实现


Java的类型系统为MCP工具提供了强大的类型安全和验证能力。


```java

// 工具系统核心接口

public interface Tool {

    String getName();

    String getDescription();

    Map getInputSchema();

    Object execute(Map arguments) throws Exception;

    default Map toMap() {

<"www.ezhou.gov.cn.felli.cn">

<"www.jingmen.gov.cn.felli.cn">

<"www.xiaogan.gov.cn.felli.cn">

        return Map.of(

            "name", getName(),

            "description", getDescription(),

            "inputSchema", getInputSchema()

        );

    }

}


// 抽象工具基类

public abstract class AbstractTool implements Tool {

    protected final String name;

    protected final String description;

    protected final Map inputSchema;

    

    protected AbstractTool(String name, String description, Map inputSchema) {

        this.name = name;

        this.description = description;

        this.inputSchema = inputSchema;

    }

    

    @Override

    public String getName() { return name; }

    

    @Override

    public String getDescription() { return description; }

    

    @Override

    public Map getInputSchema() { return inputSchema; }

}


// 具体工具实现

public class FileSystemTool extends AbstractTool {

    

    public FileSystemTool() {

        super("file_operation", "文件系统操作",

            Map.of(

                "type", "object",

                "properties", Map.of(

                    "operation", Map.of("type", "string", "enum", List.of("read", "write", "list")),

                    "path", Map.of("type", "string"),

                    "content", Map.of("type", "string")

                ),

                "required", List.of("operation", "path")

            )

        );

    }

    

    @Override

    public Object execute(Map arguments) throws Exception {

        String operation = (String) arguments.get("operation");

        String path = (String) arguments.get("path");

        

        switch (operation) {

            case "read":

                return readFile(path);

            case "write":

                String content = (String) arguments.get("content");

                return writeFile(path, content);

            case "list":

                return listFiles(path);

            default:

                throw new IllegalArgumentException("Unsupported operation: " + operation);

<"www.jingzhou.gov.cn.felli.cn">

<"www.baoji.gov.cn.felli.cn">

<"www.xianyang.gov.cn.felli.cn">

        }

    }

    

    private String readFile(String path) throws IOException {

        return new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8);

    }

    

    private String writeFile(String path, String content) throws IOException {

        Files.write(Paths.get(path), content.getBytes(StandardCharsets.UTF_8));

        return "File written successfully";

    }

    

    private List listFiles(String path) throws IOException {

        try (Stream stream = Files.list(Paths.get(path))) {

            return stream.map(Path::getFileName)

                        .map(Path::toString)

                        .collect(Collectors.toList());

        }

    }

}


// 数据库查询工具

public class DatabaseTool extends AbstractTool {

    private final DataSource dataSource;

    

    public DatabaseTool(DataSource dataSource) {

        super("database_query", "数据库查询工具",

            Map.of(

                "type", "object",

                "properties", Map.of(

                    "query", Map.of("type", "string"),

                    "parameters", Map.of("type", "object")

                ),

                "required", List.of("query")

            )

        );

        this.dataSource = dataSource;

    }

    

    @Override

    public Object execute(Map arguments) throws Exception {

        String query = (String) arguments.get("query");

        @SuppressWarnings("unchecked")

        Map params = (Map) arguments.get("parameters");

        

        try (Connection conn = dataSource.getConnection();

             PreparedStatement stmt = conn.prepareStatement(query)) {

            

            // 设置参数

            if (params != null) {

                int index = 1;

                for (Map.Entry entry : params.entrySet()) {

                    stmt.setObject(index++, entry.getValue());

                }

            }

            

            if (query.trim().toLowerCase().startsWith("select")) {

                return executeQuery(stmt);

            } else {

                return executeUpdate(stmt);

            }

        }

    }

    

    private List> executeQuery(PreparedStatement stmt) throws SQLException {

        List> results = new ArrayList<>();

        try (ResultSet rs = stmt.executeQuery()) {

            ResultSetMetaData metaData = rs.getMetaData();

            int columnCount = metaData.getColumnCount();

            

            while (rs.next()) {

                Map row = new HashMap<>();

                for (int i = 1; i <= columnCount; i++) {

                    row.put(metaData.getColumnName(i), rs.getObject(i));

                }

                results.add(row);

            }

        }

        return results;

    }

    

    private Map executeUpdate(PreparedStatement stmt) throws SQLException {

        int affectedRows = stmt.executeUpdate();

        return Map.of(

            "affectedRows", affectedRows,

            "message", "Query executed successfully"

<"www.weinan.gov.cn.felli.cn">

<"www.yanan.gov.cn.felli.cn">

<"www.hanzhong.gov.cn.felli.cn">

        );

    }

}

```


## Spring Boot集成实现


利用Spring Boot的自动配置和依赖注入,构建生产就绪的MCP服务器。


```java

// Spring Boot配置类

@Configuration

@EnableConfigurationProperties(MCPServerProperties.class)

public class MCPServerAutoConfiguration {

    

    @Bean

    @ConditionalOnMissingBean

    public MCPServer mcpServer(DataSource dataSource, ObjectProvider tools) {

        return new SpringMCPServer(dataSource, tools);

    }

    

    @Bean

    public FileSystemTool fileSystemTool() {

        return new FileSystemTool();

    }

    

    @Bean

    public DatabaseTool databaseTool(DataSource dataSource) {

        return new DatabaseTool(dataSource);

    }

    

    @Bean

    public WebSearchTool webSearchTool() {

        return new WebSearchTool();

    }

}


// 配置属性

@ConfigurationProperties(prefix = "mcp.server")

@Data

public class MCPServerProperties {

    private int port = 8080;

    private String host = "localhost";

    private boolean enabled = true;

    private List allowedOrigins = List.of("*");

}


// Spring Boot MCP服务器

@Component

public class SpringMCPServer extends MCPServer {

    

    private final DataSource dataSource;

    private final List customTools;

    

    public SpringMCPServer(DataSource dataSource, ObjectProvider tools) {

        this.dataSource = dataSource;

        this.customTools = tools.stream().collect(Collectors.toList());

    }

    

    @Override

    protected void initializeTools() {

        // 注册核心工具

        registerTool(new FileSystemTool());

        registerTool(new DatabaseTool(dataSource));

        registerTool(new WebSearchTool());

        registerTool(new CalculatorTool());

        

        // 注册自定义工具

        customTools.forEach(this::registerTool);

    }

    

    @Override

    protected void initializeResources() {

        // 初始化资源

        resources.put("config", new Resource("config", "Server configuration"));

        resources.put("logs", new Resource("logs", "Application logs"));

<"www.yuxi.gov.cn.felli.cn">

<"www.ankang.gov.cn.felli.cn">

<"www.shangluo.gov.cn.felli.cn">

    }

    

    @Override

    protected String getServerName() {

        return "Spring-MCP-Server";

    }

    

    private void registerTool(Tool tool) {

        tools.put(tool.getName(), tool);

    }

}


// REST控制器

@RestController

@RequestMapping("/mcp")

@CrossOrigin(origins = "*")

public class MCPController {

    

    private final MCPServer mcpServer;

    

    public MCPController(MCPServer mcpServer) {

        this.mcpServer = mcpServer;

    }

    

    @PostMapping

    public ResponseEntity handleMCPRequest(@RequestBody String request) {

        MCPResponse response = mcpServer.handleRequest(request);

        return ResponseEntity.ok(new Gson().toJson(response));

    }

    

    @GetMapping("/health")

    public ResponseEntity> healthCheck() {

        return ResponseEntity.ok(Map.of(

            "status", "healthy",

            "timestamp", Instant.now(),

            "tools", mcpServer.getTools().size()

        ));

    }

}

```


## 高级工具和资源管理


实现更复杂的工具和资源管理功能。


```java

// 高级工具:HTTP客户端工具

public class HttpClientTool extends AbstractTool {

    

    private final RestTemplate restTemplate;

    

    public HttpClientTool() {

        super("http_request", "HTTP请求工具",

            Map.of(

                "type", "object",

                "properties", Map.of(

                    "method", Map.of("type", "string", "enum", List.of("GET", "POST", "PUT", "DELETE")),

                    "url", Map.of("type", "string"),

                    "headers", Map.of("type", "object"),

                    "body", Map.of("type", "object")

                ),

                "required", List.of("method", "url")

            )

        );

        this.restTemplate = new RestTemplate();

    }

    

    @Override

    public Object execute(Map arguments) throws Exception {

        String method = ((String) arguments.get("method")).toUpperCase();

        String url = (String) arguments.get("url");

        @SuppressWarnings("unchecked")

        Map headers = (Map) arguments.get("headers");

        Object body = arguments.get("body");

        

        HttpHeaders httpHeaders = new HttpHeaders();

        if (headers != null) {

            headers.forEach(httpHeaders::set);

        }

        

        HttpEntity entity = new HttpEntity<>(body, httpHeaders);

        

        ResponseEntity response = restTemplate.exchange(url, 

            HttpMethod.valueOf(method), entity, String.class);

        

        return Map.of(

            "statusCode", response.getStatusCodeValue(),

            "headers", response.getHeaders().toSingleValueMap(),

            "body", response.getBody()

<"www.taibei.gov.cn.felli.cn">

<"www.beijing.gov.cn.felli.cn">

<"www.shanghai.gov.cn.felli.cn">

        );

    }

}


// 高级工具:数据转换工具

public class DataTransformTool extends AbstractTool {

    

    public DataTransformTool() {

        super("data_transform", "数据转换工具",

            Map.of(

                "type", "object",

                "properties", Map.of(

                    "operation", Map.of("type", "string", 

                                      "enum", List.of("filter", "sort", "map", "reduce")),

                    "data", Map.of("type", "array"),

                    "criteria", Map.of("type", "object")

                ),

                "required", List.of("operation", "data")

            )

        );

    }

    

    @Override

    @SuppressWarnings("unchecked")

    public Object execute(Map arguments) throws Exception {

        String operation = (String) arguments.get("operation");

        List data = (List) arguments.get("data");

        Map criteria = (Map) arguments.get("criteria");

        

        switch (operation) {

            case "filter":

                return filterData(data, criteria);

            case "sort":

                return sortData(data, criteria);

            case "map":

                return mapData(data, criteria);

            case "reduce":

                return reduceData(data, criteria);

            default:

                throw new IllegalArgumentException("Unsupported operation: " + operation);

        }

    }

    

    private List filterData(List data, Map criteria) {

        return data.stream()

            .filter(item -> meetsCriteria(item, criteria))

            .collect(Collectors.toList());

    }

    

    private List sortData(List data, Map criteria) {

        String sortBy = (String) criteria.get("sortBy");

        boolean ascending = (Boolean) criteria.getOrDefault("ascending", true);

        

        Comparator comparator = (a, b) -> {

            Object aValue = getFieldValue(a, sortBy);

            Object bValue = getFieldValue(b, sortBy);

            return compareValues(aValue, bValue);

        };

        

        if (!ascending) {

            comparator = comparator.reversed();

        }

        

        return data.stream()

            .sorted(comparator)

            .collect(Collectors.toList());

    }

    

    private boolean meetsCriteria(Object item, Map criteria) {

        // 实现条件判断逻辑

        return true;

    }

    

    private Object getFieldValue(Object obj, String field) {

        // 实现字段值提取逻辑

        return obj;

    }

    

    private int compareValues(Object a, Object b) {

        // 实现值比较逻辑

        return 0;

    }

}

```


## 客户端连接和测试


提供完整的客户端实现和测试方案。


```java

// Java MCP客户端

@Component

public class MCPClient {

    

    private final RestTemplate restTemplate;

    private final String serverUrl;

    

    public MCPClient(@Value("${mcp.server.url:http://localhost:8080/mcp}") String serverUrl) {

        this.serverUrl = serverUrl;

        this.restTemplate = new RestTemplate();

    }

    

    public List listTools() {

        MCPRequest request = new MCPRequest("tools/list", Map.of());

        MCPResponse response = sendRequest(request);

        

        @SuppressWarnings("unchecked")

        List> toolsData = (List>) 

            response.getResult().get("tools");

        

        return toolsData.stream()

            .map(data -> new ToolInfo(

                (String) data.get("name"),

                (String) data.get("description")

            ))

            .collect(Collectors.toList());

<"www.guangzhou.gov.cn.felli.cn">

<"www.chengdu.gov.cn.felli.cn">

<"www.chongqing.gov.cn.felli.cn">

    }

    

    public Object callTool(String toolName, Map arguments) {

        MCPRequest request = new MCPRequest("tools/call", 

            Map.of("name", toolName, "arguments", arguments));

        

        MCPResponse response = sendRequest(request);

        return response.getResult().get("content");

    }

    

    private MCPResponse sendRequest(MCPRequest request) {

        String requestJson = new Gson().toJson(request);

        

        ResponseEntity responseEntity = restTemplate.postForEntity(

            serverUrl, requestJson, String.class);

        

        return new Gson().fromJson(responseEntity.getBody(), MCPResponse.class);

    }

    

    public static class ToolInfo {

        private final String name;

        private final String description;

        

        public ToolInfo(String name, String description) {

            this.name = name;

            this.description = description;

        }

        

        // getters

    }

}


// 集成测试

@SpringBootTest

@TestPropertySource(properties = {

    "mcp.server.port=8080",

    "mcp.server.enabled=true"

})

class MCPServerIntegrationTest {

    

    @Autowired

    private MCPClient mcpClient;

    

    @Test

    void testListTools() {

        List tools = mcpClient.listTools();

        

        assertThat(tools).isNotEmpty();

        assertThat(tools).extracting("name")

            .contains("file_operation", "database_query", "http_request");

    }

    

    @Test

    void testFileOperation() {

        Map arguments = Map.of(

            "operation", "write",

            "path", "test.txt",

            "content", "Hello MCP Server!"

        );

        

        Object result = mcpClient.callTool("file_operation", arguments);

        assertThat(result).isEqualTo("File written successfully");

    }

    

    @Test

    void testDatabaseQuery() {

        Map arguments = Map.of(

            "query", "SELECT 1 as result",

            "parameters", Map.of()

        );

        

        Object result = mcpClient.callTool("database_query", arguments);

        assertThat(result).isInstanceOf(List.class);

<"www.wuhan.gov.cn.felli.cn">

<"www.nanjing.gov.cn.felli.cn">

<"www.tianjin.gov.cn.felli.cn">

    }

}


// 性能监控

@Component

public class MCPServerMetrics {

    

    private final MeterRegistry meterRegistry;

    private final Counter toolCallCounter;

    private final Timer toolExecutionTimer;

    

    public MCPServerMetrics(MeterRegistry meterRegistry) {

        this.meterRegistry = meterRegistry;

        this.toolCallCounter = Counter.builder("mcp.tool.calls")

            .description("Number of tool calls")

            .register(meterRegistry);

            

        this.toolExecutionTimer = Timer.builder("mcp.tool.execution.time")

            .description("Tool execution time")

            .register(meterRegistry);

    }

    

    public void recordToolCall(String toolName, long duration) {

        toolCallCounter.increment();

        toolExecutionTimer.record(duration, TimeUnit.MILLISECONDS);

        

        // 记录工具特定的指标

        Counter.builder("mcp.tool.calls")

            .tag("tool", toolName)

            .register(meterRegistry)

            .increment();

    }

}

```


通过Java构建MCP服务器,开发者可以充分利用Java生态系统的强大功能,包括类型安全、性能优化、监控指标和企业级集成能力。这种方案特别适合需要高可靠性、强类型检查和现有Java基础设施集成的生产环境。