Skip to main content
前往 Java MCP 客户端 学习如何构建 MCP 客户端,或查看 Java MCP 概览 以了解 Java 中模型上下文协议(MCP)的总体介绍。

概览

MCP 服务器是模型上下文协议(MCP)架构中的基础组件,为客户端提供工具、资源和功能。它实现了协议的服务器端,负责:
  • 公开客户端可发现并执行的工具
  • 通过基于 URI 的访问模式管理资源
  • 提供提示模板并处理提示请求
  • 与客户端进行能力协商
  • 实现服务器端协议操作
  • 管理并发客户端连接
  • 提供结构化日志和通知
核心模块 io.modelcontextprotocol.sdk:mcp 提供了 STDIO 和 SSE 服务器传输实现,无需外部 Web 框架。Spring 专用的传输实现作为可选依赖项提供:io.modelcontextprotocol.sdk:mcp-spring-webfluxio.modelcontextprotocol.sdk:mcp-spring-webmvc,供 Spring Framework 用户使用。
这个基于 Spring AI MCP 的快速入门示例将向你展示如何构建一个 MCP 服务器。
服务器同时支持同步和异步 API,可在不同的应用上下文中灵活集成。
// 使用自定义配置创建服务器
McpSyncServer syncServer = McpServer.sync(transportProvider)
    .serverInfo("my-server", "1.0.0")
    .capabilities(ServerCapabilities.builder()
        .resources(false, true)  // 启用资源支持
        .tools(true)             // 启用工具支持
        .prompts(true)           // 启用提示支持
        .logging()               // 启用日志支持
        .completions()           // 启用补全支持
        .build())
    .build();

// 注册工具、资源和提示
syncServer.addTool(syncToolSpecification);
syncServer.addResource(syncResourceSpecification);
syncServer.addPrompt(syncPromptSpecification);

// 使用完毕后关闭服务器
syncServer.close();

服务器传输提供程序

MCP SDK 中的传输层负责处理客户端与服务器之间的通信。 它提供了多种实现,以支持不同的通信协议与模式。 SDK 内置了若干种传输提供程序实现:
创建基于进程内通信的传输:
StdioServerTransportProvider transportProvider = new StdioServerTransportProvider(new ObjectMapper());
通过标准输入/输出流提供双向 JSON-RPC 消息处理,具备非阻塞消息处理、序列化/反序列化以及优雅关闭支持。关键特性:
  • 通过 stdin/stdout 实现双向通信
  • 支持基于进程的集成
  • 简单设置与配置
  • 轻量级实现

服务器能力

服务器可以配置多种能力:
var capabilities = ServerCapabilities.builder()
    .resources(false, true)  // 资源支持,并启用列表变更通知
    .tools(true)            // 工具支持,并启用列表变更通知
    .prompts(true)          // Prompt 支持,并启用列表变更通知
    .logging()              // 启用日志支持(默认启用,日志级别为 INFO)
    .build();

日志支持

服务器提供结构化日志功能,允许以不同的严重级别向客户端发送日志消息:
// 向客户端发送日志消息
server.loggingNotification(LoggingMessageNotification.builder()
    .level(LoggingLevel.INFO)
    .logger("custom-logger")
    .data("自定义日志消息")
    .build());
客户端可以通过 mcpClient.setLoggingLevel(level) 请求来控制其接收的最低日志级别。低于该级别的消息将被过滤掉。
支持的日志级别(按严重性递增顺序):DEBUG (0)、INFO (1)、NOTICE (2)、WARNING (3)、ERROR (4)、CRITICAL (5)、ALERT (6)、EMERGENCY (7)

工具规范

模型上下文协议允许服务器公开工具,供语言模型调用。
Java SDK 支持使用处理函数实现工具规范。
工具使 AI 模型能够执行计算、访问外部 API、查询数据库以及操作文件:
// 同步工具规范
var schema = """
            {
              "type" : "object",
              "id" : "urn:jsonschema:Operation",
              "properties" : {
                "operation" : {
                  "type" : "string"
                },
                "a" : {
                  "type" : "number"
                },
                "b" : {
                  "type" : "number"
                }
              }
            }
            """;
var syncToolSpecification = new McpServerFeatures.SyncToolSpecification(
    new Tool("calculator", "基础计算器", schema),
    (exchange, arguments) -> {
        // 工具实现
        return new CallToolResult(result, false);
    }
);
工具规范包含一个工具定义,其中包含 namedescription 和参数模式,随后是一个调用处理器,用于实现工具的逻辑。
该函数的第一个参数是 McpAsyncServerExchange,用于与客户端交互;第二个参数是一个工具参数的映射。

资源规范

资源规范及其处理函数的定义。
资源通过暴露以下数据为 AI 模型提供上下文:文件内容、数据库记录、API 响应、系统信息、应用程序状态。
资源规范示例:
// 同步资源规范
var syncResourceSpecification = new McpServerFeatures.SyncResourceSpecification(
    new Resource("custom://resource", "name", "description", "mime-type", null),
    (exchange, request) -> {
        // 资源读取实现
        return new ReadResourceResult(contents);
    }
);
资源规范由资源定义和资源读取处理器组成。
资源定义包括 namedescriptionMIME type
处理资源读取请求的函数的第一个参数是一个 McpAsyncServerExchange,服务器可以通过它与已连接的客户端交互。
第二个参数是一个 McpSchema.ReadResourceRequest

提示规范

作为提示功能的一部分,MCP 提供了一种标准化的方式,让服务器向客户端公开提示模板。
提示规范是一种用于 AI 模型交互的结构化模板,可实现一致的消息格式化、参数替换、上下文注入、响应格式化以及指令模板化。
// 同步提示规范
var syncPromptSpecification = new McpServerFeatures.SyncPromptSpecification(
    new Prompt("greeting", "描述", List.of(
        new PromptArgument("name", "描述", true)
    )),
    (exchange, request) -> {
        // 提示实现
        return new GetPromptResult(description, messages);
    }
);
提示定义包括 name(提示的标识符)、description(提示的用途)以及参数列表(用于模板的参数)。 处理函数负责处理请求并返回格式化后的模板。 第一个参数是 McpAsyncServerExchange,用于与客户端交互;第二个参数是一个 GetPromptRequest 实例。

补全规范

作为补全功能的一部分,MCP 提供了一种标准化方式,让服务器能够为提示和资源 URI 的参数提供自动补全建议。
// 同步补全规范
var syncCompletionSpecification = new McpServerFeatures.SyncCompletionSpecification(
			new McpSchema.PromptReference("code_review"), (exchange, request) -> {

        // 补全实现 ...

        return new McpSchema.CompleteResult(
            new CompleteResult.CompleteCompletion(
              List.of("python", "pytorch", "pyside"),
              10, // 总数
              false // 是否还有更多
            ));
      }
);

// 创建具有补全能力的同步服务器
var mcpServer = McpServer.sync(mcpServerTransportProvider)
  .capabilities(ServerCapabilities.builder()
    .completions() // 启用补全支持
      // ...
    .build())
  // ...
  .completions(new McpServerFeatures.SyncCompletionSpecification( // 注册补全规范
      new McpSchema.PromptReference("code_review"), syncCompletionSpecification))
  .build();

McpSchema.CompletionReference 定义了完成规范的类型(PromptRefernceResourceRefernce)和标识符(例如 handler)。 handler 函数处理请求并返回完成响应。 第一个参数是 McpAsyncServerExchange,用于与客户端交互;第二个参数是一个 CompleteRequest 实例。 查看使用完成了解如何在客户端使用完成功能。

在服务器端使用采样

要使用采样功能,请连接到支持采样的客户端。 无需特殊的服务器配置,但在发起请求前请确认客户端支持采样。 了解客户端采样支持 连接到兼容的客户端后,服务器即可请求语言模型生成:
// 创建服务器
McpSyncServer server = McpServer.sync(transportProvider)
    .serverInfo("my-server", "1.0.0")
    .build();

// 定义一个使用采样的工具
var calculatorTool = new McpServerFeatures.SyncToolSpecification(
    new Tool("ai-calculator", "使用 AI 执行计算", schema),
    (exchange, arguments) -> {
        // 检查客户端是否支持采样
        if (exchange.getClientCapabilities().sampling() == null) {
            return new CallToolResult("客户端不支持 AI 功能", false);
        }

        // 创建采样请求
        McpSchema.CreateMessageRequest request = McpSchema.CreateMessageRequest.builder()
            .messages(List.of(new McpSchema.SamplingMessage(McpSchema.Role.USER,
                new McpSchema.TextContent("计算:" + arguments.get("expression"))))
            .modelPreferences(McpSchema.ModelPreferences.builder()
                .hints(List.of(
                    McpSchema.ModelHint.of("claude-3-sonnet"),
                    McpSchema.ModelHint.of("claude")
                ))
                .intelligencePriority(0.8)  // 优先智能
                .speedPriority(0.5)         // 速度重要性适中
                .build())
            .systemPrompt("你是一个有用的计算器助手。仅提供数值答案。")
            .maxTokens(100)
            .build();

        // 向客户端请求采样
        McpSchema.CreateMessageResult result = exchange.createMessage(request);

        // 处理结果
        String answer = result.content().text();
        return new CallToolResult(answer, false);
    }
);

// 将工具添加到服务器
server.addTool(calculatorTool);
CreateMessageRequest 对象允许你指定:Content——模型的输入文本或图像,Model Preferences——模型选择的提示与优先级,System Prompt——模型行为的指令,以及 Max Tokens——生成回复的最大长度。

日志支持

服务器提供结构化日志功能,可按不同严重级别向客户端发送日志消息。日志通知只能在现有客户端会话中发送,例如工具、资源和提示调用。 例如,我们可以在工具处理函数内发送日志消息。
在客户端,你可以注册日志消费者以接收来自服务器的日志消息,并设置最低日志级别来过滤消息。
var mcpClient = McpClient.sync(transport)
        .loggingConsumer(notification -> {
            System.out.println("收到日志消息: " + notification.data());
        })
        .build();

mcpClient.initialize();

mcpClient.setLoggingLevel(McpSchema.LoggingLevel.INFO);

// 调用会发送日志通知的工具
CallToolResult result = mcpClient.callTool(new McpSchema.CallToolRequest("logging-test", Map.of()));
服务器可以在工具/资源/提示处理函数中,通过 McpAsyncServerExchange/McpSyncServerExchange 对象发送日志消息:
var tool = new McpServerFeatures.AsyncToolSpecification(
    new McpSchema.Tool("logging-test", "测试日志通知", emptyJsonSchema),
    (exchange, request) -> {

      exchange.loggingNotification( // 使用 exchange 发送日志消息
          McpSchema.LoggingMessageNotification.builder()
            .level(McpSchema.LoggingLevel.DEBUG)
            .logger("test-logger")
            .data("调试消息")
            .build())
        .block();

      return Mono.just(new CallToolResult("日志测试已完成", false));
    });

var mcpServer = McpServer.async(mcpServerTransportProvider)
  .serverInfo("test-server", "1.0.0")
  .capabilities(
    ServerCapabilities.builder()
      .logging() // 启用日志支持
      .tools(true)
      .build())
  .tools(tool)
  .build();
客户端可以通过 mcpClient.setLoggingLevel(level) 请求来控制接收到的最低日志级别。低于该级别的消息将被过滤掉。 支持的日志级别(按严重程度递增):DEBUG (0)、INFO (1)、NOTICE (2)、WARNING (3)、ERROR (4)、CRITICAL (5)、ALERT (6)、EMERGENCY (7)

错误处理

SDK 通过 McpError 类提供全面的错误处理,涵盖协议兼容性、传输通信、JSON-RPC 消息、工具执行、资源管理、提示处理、超时和连接问题。这种统一的错误处理方式确保了同步和异步操作中的一致且可靠的错误管理。