Skip to content

Java SDK

Model Context Protocol (MCP) 的 Java SDK 提供了构建 MCP 服务器和客户端的完整工具集,支持 Java 8+ 和现代 Java 特性。

安装

Maven

xml
<dependency>
    <groupId>io.modelcontextprotocol</groupId>
    <artifactId>mcp-java-sdk</artifactId>
    <version>1.0.0</version>
</dependency>

Gradle

gradle
implementation 'io.modelcontextprotocol:mcp-java-sdk:1.0.0'

快速开始

创建 MCP 服务器

java
import io.mcp.server.McpServer;
import io.mcp.server.ServerOptions;
import io.mcp.server.tool.Tool;
import io.mcp.server.tool.ToolCall;
import io.mcp.server.tool.ToolSchema;
import io.mcp.common.JsonSchema;

import java.util.Map;
import java.util.concurrent.CompletableFuture;

public class MyMcpServer {
    public static void main(String[] args) {
        // 创建服务器
        McpServer server = McpServer.builder()
            .name("my-java-server")
            .version("1.0.0")
            .description("Java MCP 服务器示例")
            .build();
        
        // 注册工具
        server.registerTool(new EchoTool());
        
        // 启动服务器
        server.start();
    }
}

class EchoTool implements Tool {
    @Override
    public String getName() {
        return "echo";
    }
    
    @Override
    public String getDescription() {
        return "回显输入的消息";
    }
    
    @Override
    public JsonSchema getInputSchema() {
        return JsonSchema.builder()
            .type("object")
            .property("message", JsonSchema.builder()
                .type("string")
                .description("要回显的消息")
                .build())
            .required("message")
            .build();
    }
    
    @Override
    public CompletableFuture<Object> call(ToolCall call) {
        Map<String, Object> args = call.getArguments();
        String message = (String) args.get("message");
        
        Map<String, String> result = Map.of("echo", message);
        return CompletableFuture.completedFuture(result);
    }
}

创建 MCP 客户端

java
import io.mcp.client.McpClient;
import io.mcp.client.ClientOptions;
import io.mcp.transport.StdioTransport;
import io.mcp.transport.WebSocketTransport;

import java.util.Map;
import java.util.concurrent.CompletableFuture;

public class MyMcpClient {
    public static void main(String[] args) throws Exception {
        // 创建传输层
        StdioTransport transport = new StdioTransport();
        
        // 创建客户端
        McpClient client = McpClient.builder()
            .transport(transport)
            .connectTimeout(Duration.ofSeconds(10))
            .requestTimeout(Duration.ofSeconds(30))
            .build();
        
        // 连接到服务器
        client.connect().get();
        
        try {
            // 列出可用工具
            var tools = client.listTools().get();
            System.out.println("可用工具: " + tools);
            
            // 调用工具
            Map<String, Object> args = Map.of("message", "Hello from Java!");
            var result = client.callTool("echo", args).get();
            System.out.println("工具调用结果: " + result);
            
        } finally {
            client.close();
        }
    }
}

核心功能

服务器功能

工具注册

java
// 简单工具
server.registerTool(new SimpleCalculatorTool());

// 异步工具
server.registerTool(new AsyncDatabaseTool());

// 带验证的工具
server.registerTool(new ValidatedFileTool());

资源管理

java
import io.mcp.server.resource.Resource;
import io.mcp.server.resource.ResourceProvider;

class FileResourceProvider implements ResourceProvider {
    @Override
    public CompletableFuture<Resource> getResource(String uri) {
        return CompletableFuture.supplyAsync(() -> {
            // 读取文件内容
            String content = Files.readString(Paths.get(uri));
            return Resource.builder()
                .uri(uri)
                .mimeType("text/plain")
                .content(content)
                .build();
        });
    }
    
    @Override
    public CompletableFuture<List<String>> listResources() {
        return CompletableFuture.supplyAsync(() -> {
            // 返回可用资源列表
            return List.of("file:///path/to/file1.txt", "file:///path/to/file2.txt");
        });
    }
}

// 注册资源提供者
server.registerResourceProvider(new FileResourceProvider());

提示模板

java
import io.mcp.server.prompt.Prompt;
import io.mcp.server.prompt.PromptProvider;

class CodeReviewPromptProvider implements PromptProvider {
    @Override
    public CompletableFuture<Prompt> getPrompt(String name, Map<String, Object> arguments) {
        if ("code-review".equals(name)) {
            String code = (String) arguments.get("code");
            String language = (String) arguments.get("language");
            
            String promptText = String.format(
                "请审查以下 %s 代码并提供改进建议:\n\n```%s\n%s\n```",
                language, language, code
            );
            
            return CompletableFuture.completedFuture(
                Prompt.builder()
                    .name(name)
                    .description("代码审查提示")
                    .content(promptText)
                    .build()
            );
        }
        
        return CompletableFuture.failedFuture(
            new IllegalArgumentException("未知提示: " + name)
        );
    }
    
    @Override
    public CompletableFuture<List<String>> listPrompts() {
        return CompletableFuture.completedFuture(List.of("code-review"));
    }
}

// 注册提示提供者
server.registerPromptProvider(new CodeReviewPromptProvider());

客户端功能

连接管理

java
// 自动重连客户端
McpClient client = McpClient.builder()
    .transport(transport)
    .autoReconnect(true)
    .maxReconnectAttempts(5)
    .reconnectDelay(Duration.ofSeconds(2))
    .build();

// 连接状态监听
client.addConnectionListener(new ConnectionListener() {
    @Override
    public void onConnected() {
        System.out.println("已连接到服务器");
    }
    
    @Override
    public void onDisconnected() {
        System.out.println("与服务器断开连接");
    }
    
    @Override
    public void onError(Throwable error) {
        System.err.println("连接错误: " + error.getMessage());
    }
});

批量操作

java
// 批量调用工具
List<CompletableFuture<Object>> futures = List.of(
    client.callTool("tool1", args1),
    client.callTool("tool2", args2),
    client.callTool("tool3", args3)
);

CompletableFuture<List<Object>> allResults = CompletableFuture.allOf(
    futures.toArray(new CompletableFuture[0])
).thenApply(v -> futures.stream()
    .map(CompletableFuture::join)
    .collect(Collectors.toList())
);

List<Object> results = allResults.get();

传输协议

Stdio 传输

java
StdioTransport transport = StdioTransport.builder()
    .command("python", "server.py")
    .workingDirectory("/path/to/server")
    .environment(Map.of("ENV_VAR", "value"))
    .build();

WebSocket 传输

java
WebSocketTransport transport = WebSocketTransport.builder()
    .uri("ws://localhost:8080/mcp")
    .headers(Map.of("Authorization", "Bearer token"))
    .connectTimeout(Duration.ofSeconds(10))
    .build();

HTTP SSE 传输

java
SseTransport transport = SseTransport.builder()
    .uri("http://localhost:8080/mcp")
    .headers(Map.of("Authorization", "Bearer token"))
    .readTimeout(Duration.ofSeconds(30))
    .build();

高级特性

中间件支持

java
// 日志中间件
server.addMiddleware(new LoggingMiddleware());

// 认证中间件
server.addMiddleware(new AuthenticationMiddleware());

// 限流中间件
server.addMiddleware(new RateLimitingMiddleware());

class LoggingMiddleware implements Middleware {
    @Override
    public CompletableFuture<Object> handle(Request request, MiddlewareChain chain) {
        System.out.println("处理请求: " + request.getMethod());
        long startTime = System.currentTimeMillis();
        
        return chain.next(request).whenComplete((result, error) -> {
            long duration = System.currentTimeMillis() - startTime;
            System.out.println("请求完成,耗时: " + duration + "ms");
        });
    }
}

事件系统

java
// 服务器事件
server.addEventListener(ServerEvent.TOOL_CALLED, event -> {
    ToolCallEvent toolEvent = (ToolCallEvent) event;
    System.out.println("工具被调用: " + toolEvent.getToolName());
});

server.addEventListener(ServerEvent.ERROR, event -> {
    ErrorEvent errorEvent = (ErrorEvent) event;
    System.err.println("服务器错误: " + errorEvent.getError().getMessage());
});

// 客户端事件
client.addEventListener(ClientEvent.TOOL_RESULT, event -> {
    ToolResultEvent resultEvent = (ToolResultEvent) event;
    System.out.println("工具结果: " + resultEvent.getResult());
});

配置管理

java
// 从配置文件加载
McpConfig config = McpConfig.fromFile("mcp-config.yaml");

McpServer server = McpServer.builder()
    .config(config)
    .build();

// 程序化配置
McpConfig config = McpConfig.builder()
    .server(ServerConfig.builder()
        .name("my-server")
        .version("1.0.0")
        .maxConnections(100)
        .requestTimeout(Duration.ofSeconds(30))
        .build())
    .logging(LoggingConfig.builder()
        .level(LogLevel.INFO)
        .file("/var/log/mcp-server.log")
        .build())
    .build();

测试

单元测试

java
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import static org.junit.jupiter.api.Assertions.*;

class EchoToolTest {
    private EchoTool tool;
    
    @BeforeEach
    void setUp() {
        tool = new EchoTool();
    }
    
    @Test
    void testEcho() throws Exception {
        ToolCall call = ToolCall.builder()
            .name("echo")
            .arguments(Map.of("message", "test"))
            .build();
        
        Object result = tool.call(call).get();
        
        assertEquals(Map.of("echo", "test"), result);
    }
    
    @Test
    void testEchoWithMissingArgument() {
        ToolCall call = ToolCall.builder()
            .name("echo")
            .arguments(Map.of())
            .build();
        
        assertThrows(IllegalArgumentException.class, () -> {
            tool.call(call).get();
        });
    }
}

集成测试

java
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;

class McpIntegrationTest {
    private McpServer server;
    private McpClient client;
    
    @BeforeEach
    void setUp() throws Exception {
        // 启动测试服务器
        server = McpServer.builder()
            .name("test-server")
            .build();
        server.registerTool(new EchoTool());
        server.start();
        
        // 创建客户端
        StdioTransport transport = new StdioTransport();
        client = McpClient.builder()
            .transport(transport)
            .build();
        client.connect().get();
    }
    
    @AfterEach
    void tearDown() throws Exception {
        if (client != null) {
            client.close();
        }
        if (server != null) {
            server.stop();
        }
    }
    
    @Test
    void testToolCall() throws Exception {
        Map<String, Object> args = Map.of("message", "test");
        Object result = client.callTool("echo", args).get();
        
        assertEquals(Map.of("echo", "test"), result);
    }
}

部署

Spring Boot 集成

java
@SpringBootApplication
public class McpServerApplication {
    
    @Bean
    public McpServer mcpServer() {
        McpServer server = McpServer.builder()
            .name("spring-mcp-server")
            .version("1.0.0")
            .build();
        
        // 注册 Spring Bean 作为工具
        server.registerTool(applicationContext.getBean(DatabaseTool.class));
        server.registerTool(applicationContext.getBean(EmailTool.class));
        
        return server;
    }
    
    @EventListener
    public void onApplicationReady(ApplicationReadyEvent event) {
        mcpServer().start();
    }
    
    public static void main(String[] args) {
        SpringApplication.run(McpServerApplication.class, args);
    }
}

Docker 部署

dockerfile
FROM openjdk:17-jre-slim

WORKDIR /app

COPY target/mcp-server.jar app.jar

EXPOSE 8080

CMD ["java", "-jar", "app.jar"]

Kubernetes 部署

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mcp-server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mcp-server
  template:
    metadata:
      labels:
        app: mcp-server
    spec:
      containers:
      - name: mcp-server
        image: my-registry/mcp-server:1.0.0
        ports:
        - containerPort: 8080
        env:
        - name: MCP_SERVER_NAME
          value: "kubernetes-mcp-server"
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
  name: mcp-server-service
spec:
  selector:
    app: mcp-server
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: LoadBalancer

相关资源

社区支持

🚀 探索模型上下文协议的无限可能 | 连接 AI 与世界的桥梁 | 让智能更智能