> ## Documentation Index
> Fetch the complete documentation index at: https://mcp.transdocs.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Java MCP 服务器

> 学习如何实现和配置一个模型上下文协议（MCP）服务器

前往 [Java MCP 客户端](/sdk/java/mcp-client) 学习如何构建 MCP 客户端，或查看 [Java MCP 概览](/sdk/java/mcp-overview) 以了解 Java 中模型上下文协议（MCP）的总体介绍。

## 概览

MCP 服务器是模型上下文协议（MCP）架构中的基础组件，为客户端提供工具、资源和功能。它实现了协议的服务器端，负责：

* 公开客户端可发现并执行的工具
* 通过基于 URI 的访问模式管理资源
* 提供提示模板并处理提示请求
* 与客户端进行能力协商
* 实现服务器端协议操作
* 管理并发客户端连接
* 提供结构化日志和通知

<Tip>
  核心模块 `io.modelcontextprotocol.sdk:mcp` 提供了 STDIO 和 SSE 服务器传输实现，无需外部 Web 框架。

  Spring 专用的传输实现作为**可选**依赖项提供：`io.modelcontextprotocol.sdk:mcp-spring-webflux`、`io.modelcontextprotocol.sdk:mcp-spring-webmvc`，供 [Spring Framework](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-client-boot-starter-docs.html) 用户使用。
</Tip>

<Tip>
  这个基于 Spring AI MCP 的[快速入门示例](/quickstart/server)将向你展示如何构建一个 MCP 服务器。
</Tip>

服务器同时支持同步和异步 API，可在不同的应用上下文中灵活集成。

<Tabs>
  <Tab title="同步 API">
    ```java theme={null}
    // 使用自定义配置创建服务器
    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();
    ```
  </Tab>

  <Tab title="异步 API">
    ```java theme={null}
    // 使用自定义配置创建异步服务器
    McpAsyncServer asyncServer = McpServer.async(transportProvider)
        .serverInfo("my-server", "1.0.0")
        .capabilities(ServerCapabilities.builder()
            .resources(false, true)     // 启用资源支持
            .tools(true)                // 启用工具支持
            .prompts(true)              // 启用提示支持
            .logging()                  // 启用日志支持
            .completions()              // 启用补全支持
            .build())
        .build();

    // 注册工具、资源和提示
    asyncServer.addTool(asyncToolSpecification)
        .doOnSuccess(v -> logger.info("工具已注册"))
        .subscribe();

    asyncServer.addResource(asyncResourceSpecification)
        .doOnSuccess(v -> logger.info("资源已注册"))
        .subscribe();

    asyncServer.addPrompt(asyncPromptSpecification)
        .doOnSuccess(v -> logger.info("提示已注册"))
        .subscribe();

    // 完成后关闭服务器
    asyncServer.close()
        .doOnSuccess(v -> logger.info("服务器已关闭"))
        .subscribe();
    ```
  </Tab>
</Tabs>

## 服务器传输提供程序

MCP SDK 中的传输层负责处理客户端与服务器之间的通信。
它提供了多种实现，以支持不同的通信协议与模式。
SDK 内置了若干种传输提供程序实现：

<Tabs>
  <Tab title="STDIO">
    <>
      创建基于进程内通信的传输：

      ```java theme={null}
      StdioServerTransportProvider transportProvider = new StdioServerTransportProvider(new ObjectMapper());
      ```

      通过标准输入/输出流提供双向 JSON-RPC 消息处理，具备非阻塞消息处理、序列化/反序列化以及优雅关闭支持。

      关键特性：

      <ul>
        <li>通过 stdin/stdout 实现双向通信</li>
        <li>支持基于进程的集成</li>
        <li>简单设置与配置</li>
        <li>轻量级实现</li>
      </ul>
    </>
  </Tab>

  <Tab title="SSE (WebFlux)">
    <>
      <p>创建基于 WebFlux 的 SSE 服务器传输。<br />需要 <code>mcp-spring-webflux</code> 依赖。</p>

      ```java theme={null}
      @Configuration
      class McpConfig {
          @Bean
          WebFluxSseServerTransportProvider webFluxSseServerTransportProvider(ObjectMapper mapper) {
              return new WebFluxSseServerTransportProvider(mapper, "/mcp/message");
          }

          @Bean
          RouterFunction<?> mcpRouterFunction(WebFluxSseServerTransportProvider transportProvider) {
              return transportProvider.getRouterFunction();
          }
      }
      ```

      <p>实现了 MCP HTTP with SSE 传输规范，提供：</p>

      <ul>
        <li>使用 WebFlux 的响应式 HTTP 流</li>
        <li>通过 SSE 端点实现并发客户端连接</li>
        <li>消息路由与会话管理</li>
        <li>优雅关闭能力</li>
      </ul>
    </>
  </Tab>

  <Tab title="SSE (WebMvc)">
    <>
      <p>创建基于 WebMvc 的 SSE 服务器传输。<br />需要 <code>mcp-spring-webmvc</code> 依赖。</p>

      ```java theme={null}
      @Configuration
      @EnableWebMvc
      class McpConfig {
          @Bean
          WebMvcSseServerTransportProvider webMvcSseServerTransportProvider(ObjectMapper mapper) {
              return new WebMvcSseServerTransportProvider(mapper, "/mcp/message");
          }

          @Bean
          RouterFunction<ServerResponse> mcpRouterFunction(WebMvcSseServerTransportProvider transportProvider) {
              return transportProvider.getRouterFunction();
          }
      }
      ```

      <p>实现了 MCP HTTP with SSE 传输规范，提供：</p>

      <ul>
        <li>服务器端事件流</li>
        <li>与 Spring WebMVC 集成</li>
        <li>支持传统 Web 应用</li>
        <li>同步操作处理</li>
      </ul>
    </>
  </Tab>

  <Tab title="SSE (Servlet)">
    <>
      <p>
        创建一个基于 Servlet 的 SSE 服务器传输。它包含在核心 <code>mcp</code> 模块中。<br />
        <code>HttpServletSseServerTransport</code> 可与任何 Servlet 容器一起使用。<br />
        要在 Spring Web 应用中使用它，可以将其注册为一个 Servlet Bean：
      </p>

      ```java theme={null}
      @Configuration
      @EnableWebMvc
      public class McpServerConfig implements WebMvcConfigurer {

          @Bean
          public HttpServletSseServerTransportProvider servletSseServerTransportProvider() {
              return new HttpServletSseServerTransportProvider(new ObjectMapper(), "/mcp/message");
          }

          @Bean
          public ServletRegistrationBean customServletBean(HttpServletSseServerTransportProvider transportProvider) {
              return new ServletRegistrationBean(transportProvider);
          }
      }
      ```

      <p>
        使用传统的 Servlet API 实现 MCP HTTP with SSE 传输规范，提供：
      </p>

      <ul>
        <li>利用 Servlet 6.0 异步支持的异步消息处理</li>
        <li>多客户端连接的会话管理</li>

        <li>
          两种端点类型：

          <ul>
            <li>SSE 端点 (<code>/sse</code>)，用于服务器到客户端的事件推送</li>
            <li>消息端点（可配置），用于客户端到服务器的请求</li>
          </ul>
        </li>

        <li>错误处理与响应格式化</li>
        <li>优雅关闭支持</li>
      </ul>
    </>
  </Tab>
</Tabs>

## 服务器能力

服务器可以配置多种能力：

```java theme={null}
var capabilities = ServerCapabilities.builder()
    .resources(false, true)  // 资源支持，并启用列表变更通知
    .tools(true)            // 工具支持，并启用列表变更通知
    .prompts(true)          // Prompt 支持，并启用列表变更通知
    .logging()              // 启用日志支持（默认启用，日志级别为 INFO）
    .build();
```

### 日志支持

服务器提供结构化日志功能，允许以不同的严重级别向客户端发送日志消息：

```java theme={null}
// 向客户端发送日志消息
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)

### 工具规范

模型上下文协议允许服务器[公开工具](/specification/2024-11-05/server/tools/)，供语言模型调用。\
Java SDK 支持使用处理函数实现工具规范。\
工具使 AI 模型能够执行计算、访问外部 API、查询数据库以及操作文件：

<Tabs>
  <Tab title="Sync">
    ```java theme={null}
    // 同步工具规范
    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);
        }
    );
    ```
  </Tab>

  <Tab title="异步">
    ```java theme={null}
    // 异步工具规范
    var schema = """
                {
                  "type" : "object",
                  "id" : "urn:jsonschema:Operation",
                  "properties" : {
                    "operation" : {
                      "type" : "string"
                    },
                    "a" : {
                      "type" : "number"
                    },
                    "b" : {
                      "type" : "number"
                    }
                  }
                }
                """;
    var asyncToolSpecification = new McpServerFeatures.AsyncToolSpecification(
        new Tool("calculator", "基础计算器", schema),
        (exchange, arguments) -> {
            // 工具实现
            return Mono.just(new CallToolResult(result, false));
        }
    );
    ```
  </Tab>
</Tabs>

工具规范包含一个工具定义，其中包含 `name`、`description` 和参数模式，随后是一个调用处理器，用于实现工具的逻辑。\
该函数的第一个参数是 `McpAsyncServerExchange`，用于与客户端交互；第二个参数是一个工具参数的映射。

### 资源规范

资源规范及其处理函数的定义。\
资源通过暴露以下数据为 AI 模型提供上下文：文件内容、数据库记录、API 响应、系统信息、应用程序状态。\
资源规范示例：

<Tabs>
  <Tab title="同步">
    ```java theme={null}
    // 同步资源规范
    var syncResourceSpecification = new McpServerFeatures.SyncResourceSpecification(
        new Resource("custom://resource", "name", "description", "mime-type", null),
        (exchange, request) -> {
            // 资源读取实现
            return new ReadResourceResult(contents);
        }
    );
    ```
  </Tab>

  <Tab title="异步">
    ```java theme={null}
    // 异步资源规范
    var asyncResourceSpecification = new McpServerFeatures.AsyncResourceSpecification(
        new Resource("custom://resource", "name", "description", "mime-type", null),
        (exchange, request) -> {
            // 资源读取实现
            return Mono.just(new ReadResourceResult(contents));
        }
    );
    ```
  </Tab>
</Tabs>

资源规范由资源定义和资源读取处理器组成。\
资源定义包括 `name`、`description` 和 `MIME type`。\
处理资源读取请求的函数的第一个参数是一个 `McpAsyncServerExchange`，服务器可以通过它与已连接的客户端交互。\
第二个参数是一个 `McpSchema.ReadResourceRequest`。

### 提示规范

作为[提示功能](/specification/2024-11-05/server/prompts/)的一部分，MCP 提供了一种标准化的方式，让服务器向客户端公开提示模板。\
提示规范是一种用于 AI 模型交互的结构化模板，可实现一致的消息格式化、参数替换、上下文注入、响应格式化以及指令模板化。

<Tabs>
  <Tab title="Sync">
    ```java theme={null}
    // 同步提示规范
    var syncPromptSpecification = new McpServerFeatures.SyncPromptSpecification(
        new Prompt("greeting", "描述", List.of(
            new PromptArgument("name", "描述", true)
        )),
        (exchange, request) -> {
            // 提示实现
            return new GetPromptResult(description, messages);
        }
    );
    ```
  </Tab>

  <Tab title="异步">
    ```java theme={null}
    // 异步提示规范
    var asyncPromptSpecification = new McpServerFeatures.AsyncPromptSpecification(
        new Prompt("greeting", "描述", List.of(
            new PromptArgument("name", "描述", true)
        )),
        (exchange, request) -> {
            // 提示实现
            return Mono.just(new GetPromptResult(description, messages));
        }
    );
    ```
  </Tab>
</Tabs>

提示定义包括 name（提示的标识符）、description（提示的用途）以及参数列表（用于模板的参数）。
处理函数负责处理请求并返回格式化后的模板。
第一个参数是 `McpAsyncServerExchange`，用于与客户端交互；第二个参数是一个 `GetPromptRequest` 实例。

### 补全规范

作为[补全功能](/specification/2025-03-26/server/utilities/completion)的一部分，MCP 提供了一种标准化方式，让服务器能够为提示和资源 URI 的参数提供自动补全建议。

<Tabs>
  <Tab title="同步">
    ```java theme={null}
    // 同步补全规范
    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();

    ```
  </Tab>

  <Tab title="异步">
    ```java theme={null}
    // 异步补全规范
    var asyncCompletionSpecification = new McpServerFeatures.AsyncCompletionSpecification(
    			new McpSchema.PromptReference("code_review"), (exchange, request) -> {

            // 补全实现 ...

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

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

    ```
  </Tab>
</Tabs>

`McpSchema.CompletionReference` 定义了完成规范的类型（`PromptRefernce` 或 `ResourceRefernce`）和标识符（例如 handler）。
handler 函数处理请求并返回完成响应。
第一个参数是 `McpAsyncServerExchange`，用于与客户端交互；第二个参数是一个 `CompleteRequest` 实例。

查看[使用完成](/sdk/java/mcp-client#using-completion)了解如何在客户端使用完成功能。

### 在服务器端使用采样

要使用[采样功能](/specification/2024-11-05/client/sampling/)，请连接到支持采样的客户端。
无需特殊的服务器配置，但在发起请求前请确认客户端支持采样。
了解[客户端采样支持](./mcp-client#sampling-support)。

连接到兼容的客户端后，服务器即可请求语言模型生成：

<Tabs>
  <Tab title="同步 API">
    ```java theme={null}
    // 创建服务器
    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);
    ```
  </Tab>

  <Tab title="异步 API">
    ```java theme={null}
    // 创建服务器
    McpAsyncServer server = McpServer.async(transportProvider)
        .serverInfo("my-server", "1.0.0")
        .build();

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

            // 创建采样请求
            McpSchema.CreateMessageRequest request = McpSchema.CreateMessageRequest.builder()
                .content(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();

            // 向客户端请求采样
            return exchange.createMessage(request)
                .map(result -> {
                    // 处理结果
                    String answer = result.content().text();
                    return new CallToolResult(answer, false);
                });
        }
    );

    // 将工具添加到服务器
    server.addTool(calculatorTool)
        .subscribe();
    ```
  </Tab>
</Tabs>

`CreateMessageRequest` 对象允许你指定：`Content`——模型的输入文本或图像，`Model Preferences`——模型选择的提示与优先级，`System Prompt`——模型行为的指令，以及 `Max Tokens`——生成回复的最大长度。

### 日志支持

服务器提供结构化日志功能，可按不同严重级别向客户端发送日志消息。日志通知只能在现有客户端会话中发送，例如工具、资源和提示调用。

例如，我们可以在工具处理函数内发送日志消息。\
在客户端，你可以注册日志消费者以接收来自服务器的日志消息，并设置最低日志级别来过滤消息。

```java theme={null}
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` 对象发送日志消息：

```java theme={null}
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 消息、工具执行、资源管理、提示处理、超时和连接问题。这种统一的错误处理方式确保了同步和异步操作中的一致且可靠的错误管理。
