跳转到主要内容
SEO Title

category

了解如何实现和配置模型上下文协议(MCP)服务器

转到Java MCP客户端了解如何构建MCP客户端或Java MCP概述,以了解Java中模型上下文协议(MCP)的一般概述。

 

概述


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

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


核心io.modelcontextprotocol.sdk:mcp模块提供STDIO和SSE服务器传输实现,无需外部web框架。
Spring特定的传输实现可作为可选依赖项io.modelcontextprotocol.sdk:mcp-Spring-webflux、io.modelcontext protocol.sdk:mcp-sprinng-webmvc提供给Spring Framework用户。
这个基于Spring AI MCP的快速入门演示将向您展示如何构建MCP服务器。
服务器支持同步和异步API,允许在不同的应用程序上下文中灵活集成。

  •  
// Create a server with custom configuration
McpSyncServer syncServer = McpServer.sync(transportProvider)
    .serverInfo("my-server", "1.0.0")
    .capabilities(ServerCapabilities.builder()
        .resources(false, true)  // Enable resource support
        .tools(true)             // Enable tool support
        .prompts(true)           // Enable prompt support
        .logging()               // Enable logging support
        .completions()           // Enable completions support
        .build())
    .build();

// Register tools, resources, and prompts
syncServer.addTool(syncToolSpecification);
syncServer.addResource(syncResourceSpecification);
syncServer.addPrompt(syncPromptSpecification);

// Close the server when done
syncServer.close();
// Create a server with custom configuration
McpSyncServer syncServer = McpServer.sync(transportProvider)
    .serverInfo("my-server", "1.0.0")
    .capabilities(ServerCapabilities.builder()
        .resources(false, true)  // Enable resource support
        .tools(true)             // Enable tool support
        .prompts(true)           // Enable prompt support
        .logging()               // Enable logging support
        .completions()           // Enable completions support
        .build())
    .build();

// Register tools, resources, and prompts
syncServer.addTool(syncToolSpecification);
syncServer.addResource(syncResourceSpecification);
syncServer.addPrompt(syncPromptSpecification);

// Close the server when done
syncServer.close();

 

服务器传输提供者


MCP SDK中的传输层负责处理客户端和服务器之间的通信。它提供了不同的实现来支持各种通信协议和模式。SDK包括几个内置的传输提供程序实现:

  •  
  •  
  •  

Creates a Servlet-based SSE server transport. It is included in the core mcp module.
The HttpServletSseServerTransport can be used with any Servlet container.
To use it with a Spring Web application, you can register it as a Servlet bean:

StdioServerTransportProvider transportProvider = new StdioServerTransportProvider(new ObjectMapper());
  •  
  •  

Creates WebFlux-based SSE server transport.
Requires the mcp-spring-webflux dependency.

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

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

Creates WebMvc-based SSE server transport.
Requires the mcp-spring-webmvc dependency.

 

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

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

Creates a Servlet-based SSE server transport. It is included in the core mcp module.
The HttpServletSseServerTransport can be used with any Servlet container.
To use it with a Spring Web application, you can register it as a Servlet bean:

@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);
    }
}

使用传统的Servlet API实现具有SSE传输规范的MCP HTTP,提供:

使用Servlet 6.0异步支持的异步消息处理
多客户端连接的会话管理
两种类型的端点:
服务器到客户端事件的SSE端点(/SSE)
客户端到服务器请求的消息端点(可配置)
错误处理和响应格式
优雅的关机支持



服务器功能


服务器可以配置各种功能:

var capabilities = ServerCapabilities.builder()
   .resources(false, true)  // Resource support with list changes notifications
   .tools(true)            // Tool support with list changes notifications
   .prompts(true)          // Prompt support with list changes notifications
   .logging()              // Enable logging support (enabled by default with logging level INFO)
   .build();

 

日志记录支持


服务器提供结构化日志记录功能,允许向具有不同严重级别的客户端发送日志消息:

// Send a log message to clients
server.loggingNotification(LoggingMessageNotification.builder()
   .level(LoggingLevel.INFO)
   .logger("custom-logger")
   .data("Custom log message")
   .build());


客户端可以通过mcpClient.setLoggingLevel(level)请求控制它们接收到的最低日志级别。低于设定级别的消息将被过滤掉。支持的日志记录级别(按严重程度递增的顺序):调试(0)、信息(1)、通知(2)、警告(3)、错误(4)、严重(5)、警报(6)、紧急(7)

 

工具规范


模型上下文协议允许服务器公开可由语言模型调用的工具。Java SDK允许使用其处理函数实现工具规范。工具使AI模型能够执行计算、访问外部API、查询数据库和操纵文件:

  •  
// Sync tool specification
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", "Basic calculator", schema),
    (exchange, arguments) -> {
        // Tool implementation
        return new CallToolResult(result, false);
    }
);
// Async tool specification
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", "Basic calculator", schema),
    (exchange, arguments) -> {
        // Tool implementation
        return Mono.just(new CallToolResult(result, false));
    }
);

Tool规范包括一个具有名称、描述和参数模式的Tool定义,后面是一个实现工具逻辑的调用处理程序。该函数的第一个参数是用于客户端交互的McpAsyncServerExchange,第二个参数是工具参数的映射。

 

资源规格

 


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

  •  
// Sync resource specification
var syncResourceSpecification = new McpServerFeatures.SyncResourceSpecification(
    new Resource("custom://resource", "name", "description", "mime-type", null),
    (exchange, request) -> {
        // Resource read implementation
        return new ReadResourceResult(contents);
    }
);
// Sync resource specification
var syncResourceSpecification = new McpServerFeatures.SyncResourceSpecification(
    new Resource("custom://resource", "name", "description", "mime-type", null),
    (exchange, request) -> {
        // Resource read implementation
        return new ReadResourceResult(contents);
    }
);

资源规范由资源定义和资源读取处理程序组成。资源定义,包括名称、描述和MIME类型。处理资源读取请求的函数的第一个参数是McpAsyncServerExchange,服务器可以在其上与连接的客户端进行交互。第二个参数是McpSchema。读取资源请求。

 

提示规范

 


作为Prompting功能的一部分,MCP为服务器向客户端公开提示模板提供了一种标准化的方法。Prompt Specification是一个用于AI模型交互的结构化模板,它支持一致的消息格式、参数替换、上下文注入、响应格式和指令模板。

  •  
// Sync prompt specification
var syncPromptSpecification = new McpServerFeatures.SyncPromptSpecification(
    new Prompt("greeting", "description", List.of(
        new PromptArgument("name", "description", true)
    )),
    (exchange, request) -> {
        // Prompt implementation
        return new GetPromptResult(description, messages);
    }
);
// Sync prompt specification
var syncPromptSpecification = new McpServerFeatures.SyncPromptSpecification(
    new Prompt("greeting", "description", List.of(
        new PromptArgument("name", "description", true)
    )),
    (exchange, request) -> {
        // Prompt implementation
        return new GetPromptResult(description, messages);
    }
);

提示定义包括名称(提示的标识符)、描述(提示的目的)和参数列表(模板的参数)。处理程序函数处理请求并返回格式化的模板。第一个参数是用于客户端交互的McpAsyncServerExchange,第二个参数是GetPromptRequest实例。

 

完工规范


作为完成功能的一部分,MCP为服务器提供了一种标准化的方式,为提示和资源URI提供参数自动完成建议。

  •  
// Sync completion specification
var syncCompletionSpecification = new McpServerFeatures.SyncCompletionSpecification(
			new McpSchema.PromptReference("code_review"), (exchange, request) -> {

        // completion implementation ...

        return new McpSchema.CompleteResult(
            new CompleteResult.CompleteCompletion(
              List.of("python", "pytorch", "pyside"),
              10, // total
              false // hasMore
            ));
      }
);

// Create a sync server with completion capabilities
var mcpServer = McpServer.sync(mcpServerTransportProvider)
  .capabilities(ServerCapabilities.builder()
    .completions() // enable completions support
      // ...
    .build())
  // ...
  .completions(new McpServerFeatures.SyncCompletionSpecification( // register completion specification
      new McpSchema.PromptReference("code_review"), syncCompletionSpecification))
  .build();


// Async prompt specification
var asyncCompletionSpecification = new McpServerFeatures.AsyncCompletionSpecification(
			new McpSchema.PromptReference("code_review"), (exchange, request) -> {

        // completion implementation ...

        return Mono.just(new McpSchema.CompleteResult(
            new CompleteResult.CompleteCompletion(
              List.of("python", "pytorch", "pyside"),
              10, // total
              false // hasMore
            )));
      }
);

// Create a async server with completion capabilities
var mcpServer = McpServer.async(mcpServerTransportProvider)
  .capabilities(ServerCapabilities.builder()
    .completions() // enable completions support
      // ...
    .build())
  // ...
  .completions(new McpServerFeatures.AsyncCompletionSpecification( // register completion specification
      new McpSchema.PromptReference("code_review"), asyncCompletionSpecification))
  .build();


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

 

使用服务器采样


要使用采样功能,请连接到支持采样的客户端。不需要特殊的服务器配置,但在发出请求之前,请验证客户端采样支持。了解客户端采样支持。
一旦连接到兼容的客户端,服务器就可以请求语言模型生成:

  •  
// Create a server
McpSyncServer server = McpServer.sync(transportProvider)
    .serverInfo("my-server", "1.0.0")
    .build();

// Define a tool that uses sampling
var calculatorTool = new McpServerFeatures.SyncToolSpecification(
    new Tool("ai-calculator", "Performs calculations using AI", schema),
    (exchange, arguments) -> {
        // Check if client supports sampling
        if (exchange.getClientCapabilities().sampling() == null) {
            return new CallToolResult("Client does not support AI capabilities", false);
        }

        // Create a sampling request
        McpSchema.CreateMessageRequest request = McpSchema.CreateMessageRequest.builder()
            .messages(List.of(new McpSchema.SamplingMessage(McpSchema.Role.USER,
                new McpSchema.TextContent("Calculate: " + arguments.get("expression")))
            .modelPreferences(McpSchema.ModelPreferences.builder()
                .hints(List.of(
                    McpSchema.ModelHint.of("claude-3-sonnet"),
                    McpSchema.ModelHint.of("claude")
                ))
                .intelligencePriority(0.8)  // Prioritize intelligence
                .speedPriority(0.5)         // Moderate speed importance
                .build())
            .systemPrompt("You are a helpful calculator assistant. Provide only the numerical answer.")
            .maxTokens(100)
            .build();

        // Request sampling from the client
        McpSchema.CreateMessageResult result = exchange.createMessage(request);

        // Process the result
        String answer = result.content().text();
        return new CallToolResult(answer, false);
    }
);

// Add the tool to the server
server.addTool(calculatorTool);
// Create a server
McpAsyncServer server = McpServer.async(transportProvider)
    .serverInfo("my-server", "1.0.0")
    .build();

// Define a tool that uses sampling
var calculatorTool = new McpServerFeatures.AsyncToolSpecification(
    new Tool("ai-calculator", "Performs calculations using AI", schema),
    (exchange, arguments) -> {
        // Check if client supports sampling
        if (exchange.getClientCapabilities().sampling() == null) {
            return Mono.just(new CallToolResult("Client does not support AI capabilities", false));
        }

        // Create a sampling request
        McpSchema.CreateMessageRequest request = McpSchema.CreateMessageRequest.builder()
            .content(new McpSchema.TextContent("Calculate: " + arguments.get("expression")))
            .modelPreferences(McpSchema.ModelPreferences.builder()
                .hints(List.of(
                    McpSchema.ModelHint.of("claude-3-sonnet"),
                    McpSchema.ModelHint.of("claude")
                ))
                .intelligencePriority(0.8)  // Prioritize intelligence
                .speedPriority(0.5)         // Moderate speed importance
                .build())
            .systemPrompt("You are a helpful calculator assistant. Provide only the numerical answer.")
            .maxTokens(100)
            .build();

        // Request sampling from the client
        return exchange.createMessage(request)
            .map(result -> {
                // Process the result
                String answer = result.content().text();
                return new CallToolResult(answer, false);
            });
    }
);

// Add the tool to the server
server.addTool(calculatorTool)
    .subscribe();

CreateMessageRequest对象允许您指定:Content-模型的输入文本或图像,model Preferences-模型选择的提示和优先级,System Prompt-模型行为的说明,Max Tokens-生成响应的最大长度。

 

日志记录支持


服务器提供结构化日志记录功能,允许向具有不同严重性级别的客户端发送日志消息。日志通知只能从现有客户端会话(如工具、资源和提示调用)中发送。
例如,我们可以从工具处理程序函数中发送日志消息。在客户端,您可以注册日志消费者以从服务器接收日志消息,并设置过滤消息的最低日志级别。

var mcpClient = McpClient.sync(transport)
       .loggingConsumer(notification -> {
           System.out.println("Received log message: " + notification.data());
       })
       .build();
mcpClient.initialize();
mcpClient.setLoggingLevel(McpSchema.LoggingLevel.INFO);
// Call the tool that sends logging notifications
CallToolResult result = mcpClient.callTool(new McpSchema.CallToolRequest("logging-test", Map.of()));

 

服务器可以使用工具/资源/提示处理程序函数中的McpAsyncServerExchange/McpSyncServerExchange对象发送日志消息:

var tool = new McpServerFeatures.AsyncToolSpecification(
   new McpSchema.Tool("logging-test", "Test logging notifications", emptyJsonSchema),
   (exchange, request) -> {
     exchange.loggingNotification( // Use the exchange to send log messages
         McpSchema.LoggingMessageNotification.builder()
           .level(McpSchema.LoggingLevel.DEBUG)
           .logger("test-logger")
           .data("Debug message")
           .build())
       .block();
     return Mono.just(new CallToolResult("Logging test completed", false));
   });
var mcpServer = McpServer.async(mcpServerTransportProvider)
 .serverInfo("test-server", "1.0.0")
 .capabilities(
   ServerCapabilities.builder()
     .logging() // Enable logging support
     .tools(true)
     .build())
 .tools(tool)
 .build();

客户端可以通过mcpClient.setLoggingLevel(level)请求控制它们接收到的最低日志级别。低于设定级别的消息将被过滤掉。支持的日志记录级别(按严重程度递增的顺序):调试(0)、信息(1)、通知(2)、警告(3)、错误(4)、严重(5)、警报(6)、紧急(7)

 

错误处理


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

文章链接

标签