此版本仍在开发中,尚未被视为稳定版。如需最新的快照版本,请使用 Spring AI 1.1.3spring-doc.cadn.net.cn

MCP 客户端Starters

Spring AI MCP(模型上下文协议)客户端 Boot Starter 为 Spring Boot 应用程序中的 MCP 客户端功能提供自动配置。 它支持具有多种传输选项的同步和异步客户端实现。spring-doc.cadn.net.cn

MCP 客户端Starters提供:spring-doc.cadn.net.cn

Starters

标准 MCP 客户端

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>

标准Starters通过 STDIO(进程内)、SSEStreamable-HTTPStateless Streamable-HTTP 传输协议同时连接到一个或多个 MCP 服务器。 SSE 和 Streamable-Http 传输协议使用基于 JDK HttpClient 的传输实现。 每个到 MCP 服务器的连接都会创建一个新的 MCP 客户端实例。 您可以选择 SYNCASYNC MCP 客户端(注意:不能混用同步和异步客户端)。 对于生产部署,我们建议使用基于 WebFlux 的 SSE & StreamableHttp 连接配合 spring-ai-starter-mcp-client-webfluxspring-doc.cadn.net.cn

WebFlux 客户端

WebFlux starter 提供了与标准 starter 类似的功能,但使用了基于 WebFlux 的 Streamable-Http、无状态 Streamable-Http 和 SSE 传输实现。spring-doc.cadn.net.cn

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
</dependency>

配置属性

常用属性

公共属性以前缀 spring.ai.mcp.client 开头:spring-doc.cadn.net.cn

<property> </property> <description> </description> 默认值

enabledspring-doc.cadn.net.cn

启用/禁用 MCP 客户端spring-doc.cadn.net.cn

truespring-doc.cadn.net.cn

namespring-doc.cadn.net.cn

MCP 客户端实例名称spring-doc.cadn.net.cn

spring-ai-mcp-clientspring-doc.cadn.net.cn

versionspring-doc.cadn.net.cn

MCP 客户端实例的版本spring-doc.cadn.net.cn

1.0.0spring-doc.cadn.net.cn

initializedspring-doc.cadn.net.cn

是否在创建时初始化客户端spring-doc.cadn.net.cn

truespring-doc.cadn.net.cn

request-timeoutspring-doc.cadn.net.cn

MCP 客户端请求的超时持续时间spring-doc.cadn.net.cn

20sspring-doc.cadn.net.cn

typespring-doc.cadn.net.cn

客户端类型(同步或异步)。所有客户端必须同为同步或异步;不支持混合使用。spring-doc.cadn.net.cn

SYNCspring-doc.cadn.net.cn

root-change-notificationspring-doc.cadn.net.cn

为所有客户端启用/禁用根变更通知spring-doc.cadn.net.cn

truespring-doc.cadn.net.cn

toolcallback.enabledspring-doc.cadn.net.cn

启用/禁用 MCP 工具回调与 Spring AI 工具执行框架的集成spring-doc.cadn.net.cn

truespring-doc.cadn.net.cn

MCP 注解属性

MCP 客户端注解提供了一种使用 Java 注解实现 MCP 客户端处理程序的声明式方法。 客户端 mcp-annotations 属性以 spring.ai.mcp.client.annotation-scanner 为前缀:spring-doc.cadn.net.cn

<property> </property> <description> </description> 默认值

enabledspring-doc.cadn.net.cn

启用/禁用 MCP 客户端注解的自动扫描spring-doc.cadn.net.cn

truespring-doc.cadn.net.cn

标准输入输出传输属性

标准 I/O 传输的属性以前缀 spring.ai.mcp.client.stdio 开头:spring-doc.cadn.net.cn

<property> </property> <description> </description> 默认值

servers-configurationspring-doc.cadn.net.cn

包含 JSON 格式的 MCP 服务器配置的资源spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

connectionsspring-doc.cadn.net.cn

命名标准输入输出连接配置的映射spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

connections.[name].commandspring-doc.cadn.net.cn

执行 MCP 服务器的命令spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

connections.[name].argsspring-doc.cadn.net.cn

命令参数列表spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

connections.[name].envspring-doc.cadn.net.cn

服务器进程的环境变量映射spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

示例配置:spring-doc.cadn.net.cn

spring:
  ai:
    mcp:
      client:
        stdio:
          root-change-notification: true
          connections:
            server1:
              command: /path/to/server
              args:
                - --port=8080
                - --mode=production
              env:
                API_KEY: your-api-key
                DEBUG: "true"

或者,您可以使用外部 JSON 文件配置 stdio 连接,采用 Claude Desktop 格式spring-doc.cadn.net.cn

spring:
  ai:
    mcp:
      client:
        stdio:
          servers-configuration: classpath:mcp-servers.json

Claude Desktop 格式如下所示:spring-doc.cadn.net.cn

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/username/Desktop",
        "/Users/username/Downloads"
      ]
    }
  }
}

Windows STDIO 配置

在 Windows 上,像 npxnpmnode 这样的命令是以 批处理文件.cmd)的形式实现的,而不是原生可执行文件。Java 的 ProcessBuilder 无法直接执行批处理文件,需要 cmd.exe /c 包装器。

为什么 Windows 需要特殊处理

当 Java 的 ProcessBuilder(由 StdioClientTransport 内部使用)尝试在 Windows 上生成进程时,它只能执行:spring-doc.cadn.net.cn

npx.cmdnpm.cmd 甚至(来自微软商店的)python.cmd 这样的 Windows 批处理文件需要 cmd.exe 外壳来执行它们。spring-doc.cadn.net.cn

解决方案:cmd.exe 包装器

使用 cmd.exe /c 包装批处理文件命令:spring-doc.cadn.net.cn

Windows 配置:spring-doc.cadn.net.cn

{
  "mcpServers": {
    "filesystem": {
      "command": "cmd.exe",
      "args": [
        "/c",
        "npx",
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "C:\\Users\\username\\Desktop"
      ]
    }
  }
}

Linux/macOS 配置:spring-doc.cadn.net.cn

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/username/Desktop"
      ]
    }
  }
}

跨平台编程式配置

对于需要跨平台运行且无需单独配置文件的應用程式,请在您的 Spring Boot 应用中使用操作系统检测:spring-doc.cadn.net.cn

@Bean(destroyMethod = "close")
@ConditionalOnMissingBean(McpSyncClient.class)
public McpSyncClient mcpClient() {
    ServerParameters stdioParams;

    if (isWindows()) {
        // Windows: cmd.exe /c npx approach
        var winArgs = new ArrayList<>(Arrays.asList(
            "/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "target"));
        stdioParams = ServerParameters.builder("cmd.exe")
                .args(winArgs)
                .build();
    } else {
        // Linux/Mac: direct npx approach
        stdioParams = ServerParameters.builder("npx")
                .args("-y", "@modelcontextprotocol/server-filesystem", "target")
                .build();
    }

    return McpClient.sync(new StdioClientTransport(stdioParams, McpJsonDefaults.getMapper()))
            .requestTimeout(Duration.ofSeconds(10))
            .build()
            .initialize();
}

private static boolean isWindows() {
    return System.getProperty("os.name").toLowerCase().contains("win");
}
当使用编程式配置与 @Bean 时,请添加 @ConditionalOnMissingBean(McpSyncClient.class) 以避免与来自 JSON 文件的自动配置发生冲突。

路径注意事项

相对路径(推荐用于可移植性):spring-doc.cadn.net.cn

{
  "command": "cmd.exe",
  "args": ["/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "target"]
}

MCP 服务器根据应用程序的工作目录解析相对路径。spring-doc.cadn.net.cn

绝对路径(Windows 需要反斜杠或转义的正斜杠):spring-doc.cadn.net.cn

{
  "command": "cmd.exe",
  "args": ["/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "C:\\Users\\username\\project\\target"]
}

需要 cmd.exe 的常见 Windows 批处理文件

参考实现

请参阅 Spring AI 示例 - 文件系统,了解完整的跨平台 MCP 客户端实现,该实现可自动检测操作系统并相应地配置客户端。spring-doc.cadn.net.cn

Streamable-HTTP 传输属性

用于连接可流式 HTTP 和无状态可流式 HTTP MCP 服务器。spring-doc.cadn.net.cn

Streamable-HTTP 传输的属性以前缀 spring.ai.mcp.client.streamable-http 开头:spring-doc.cadn.net.cn

<property> </property> <description> </description> 默认值

connectionsspring-doc.cadn.net.cn

命名 Streamable-HTTP 连接配置的映射spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

connections.[name].urlspring-doc.cadn.net.cn

用于与 MCP 服务器进行 Streamable-Http 通信的基础 URL 端点spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

connections.[name].endpointspring-doc.cadn.net.cn

用于连接的可流式传输 HTTP 端点(作为 URL 后缀)spring-doc.cadn.net.cn

/mcpspring-doc.cadn.net.cn

示例配置:spring-doc.cadn.net.cn

spring:
  ai:
    mcp:
      client:
        streamable-http:
          connections:
            server1:
              url: http://localhost:8080
            server2:
              url: http://otherserver:8081
              endpoint: /custom-sse

SSE 传输属性

服务器发送事件 (SSE) 传输的属性以前缀 spring.ai.mcp.client.sse 开头:spring-doc.cadn.net.cn

<property> </property> <description> </description> 默认值

connectionsspring-doc.cadn.net.cn

命名 SSE 连接配置的映射spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

connections.[name].urlspring-doc.cadn.net.cn

用于与 MCP 服务器进行 SSE 通信的基础 URL 端点spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

connections.[name].sse-endpointspring-doc.cadn.net.cn

用于连接的 SSE 端点(作为 URL 后缀)spring-doc.cadn.net.cn

/ssespring-doc.cadn.net.cn

示例配置:spring-doc.cadn.net.cn

spring:
  ai:
    mcp:
      client:
        sse:
          connections:
            # Simple configuration using default /sse endpoint
            server1:
              url: http://localhost:8080
            # Custom SSE endpoint
            server2:
              url: http://otherserver:8081
              sse-endpoint: /custom-sse
            # Complex URL with path and token (like MCP Hub)
            mcp-hub:
              url: http://localhost:3000
              sse-endpoint: /mcp-hub/sse/cf9ec4527e3c4a2cbb149a85ea45ab01
            # SSE endpoint with query parameters
            api-server:
              url: https://api.example.com
              sse-endpoint: /v1/mcp/events?token=abc123&format=json

URL 拆分指南

当您拥有完整的 SSE URL 时,请将其拆分为基础 URL 和端点路径:spring-doc.cadn.net.cn

完整 URL 配置

http://localhost:3000/mcp-hub/sse/token123spring-doc.cadn.net.cn

url: localhost:3000
sse-endpoint: /mcp-hub/sse/token123spring-doc.cadn.net.cn

https://api.service.com/v2/events?key=secretspring-doc.cadn.net.cn

url: api.service.com
sse-endpoint: /v2/events?key=secretspring-doc.cadn.net.cn

http://localhost:8080/ssespring-doc.cadn.net.cn

url: localhost:8080
sse-endpoint: /sse(或省略以使用默认值)spring-doc.cadn.net.cn

排查 SSE 连接问题

404 未找到错误:spring-doc.cadn.net.cn

可流式 HTTP 传输属性

可流式 HTTP 传输的属性以 spring.ai.mcp.client.streamable-http 为前缀:spring-doc.cadn.net.cn

<property> </property> <description> </description> 默认值

connectionsspring-doc.cadn.net.cn

命名 Streamable Http 连接配置的映射spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

connections.[name].urlspring-doc.cadn.net.cn

用于与 MCP 服务器进行 Streamable-Http 通信的基础 URL 端点spring-doc.cadn.net.cn

-spring-doc.cadn.net.cn

connections.[name].endpointspring-doc.cadn.net.cn

用于连接的可流式传输 HTTP 端点(作为 URL 后缀)spring-doc.cadn.net.cn

/mcpspring-doc.cadn.net.cn

示例配置:spring-doc.cadn.net.cn

spring:
  ai:
    mcp:
      client:
        streamable-http:
          connections:
            server1:
              url: http://localhost:8080
            server2:
              url: http://otherserver:8081
              endpoint: /custom-sse

功能

同步/异步客户端类型

该Starters支持两种类型的客户端:spring-doc.cadn.net.cn

  • 同步 - 默认客户端类型(spring.ai.mcp.client.type=SYNC),适用于带有阻塞操作的传统请求 - 响应模式spring-doc.cadn.net.cn

注意:SYNC 客户端仅会注册同步的 MCP 注解方法。异步方法将被忽略。spring-doc.cadn.net.cn

  • 异步 - 适用于具有非阻塞操作的响应式应用程序,使用 spring.ai.mcp.client.type=ASYNC 进行配置spring-doc.cadn.net.cn

注意:异步客户端仅会注册标记为异步的 MCP 注解方法。同步方法将被忽略。spring-doc.cadn.net.cn

客户端自定义

自动配置通过回调接口提供了广泛的客户端规范定制能力。这些定制器允许您配置 MCP 客户端行为的各个方面,从请求超时到事件处理和消息处理。spring-doc.cadn.net.cn

自定义类型

以下自定义选项可用:spring-doc.cadn.net.cn

客户端可以通过设置最低日志级别来控制日志的详细程度spring-doc.cadn.net.cn

客户端自定义示例

您可以根据应用程序的需求,为同步客户端实现McpCustomizer<McpClient.SyncSpec>,或为异步客户端实现McpCustomizer<McpClient.AsyncSpec>spring-doc.cadn.net.cn

@Component
public class CustomMcpSyncClientCustomizer implements McpCustomizer<McpClient.SyncSpec> {
    @Override
    public void customize(String serverConfigurationName, McpClient.SyncSpec spec) {

        // Customize the request timeout configuration
        spec.requestTimeout(Duration.ofSeconds(30));

        // Sets the root URIs that this client can access.
        spec.roots(roots);

        // Sets a custom sampling handler for processing message creation requests.
        spec.sampling((CreateMessageRequest messageRequest) -> {
            // Handle sampling
            CreateMessageResult result = ...
            return result;
        });

        // Sets a custom elicitation handler for processing elicitation requests.
        spec.elicitation((ElicitRequest request) -> {
          // handle elicitation
          return new ElicitResult(ElicitResult.Action.ACCEPT, Map.of("message", request.message()));
        });

        // Adds a consumer to be notified when progress notifications are received.
        spec.progressConsumer((ProgressNotification progress) -> {
         // Handle progress notifications
        });

        // Adds a consumer to be notified when the available tools change, such as tools
        // being added or removed.
        spec.toolsChangeConsumer((List<McpSchema.Tool> tools) -> {
            // Handle tools change
        });

        // Adds a consumer to be notified when the available resources change, such as resources
        // being added or removed.
        spec.resourcesChangeConsumer((List<McpSchema.Resource> resources) -> {
            // Handle resources change
        });

        // Adds a consumer to be notified when the available prompts change, such as prompts
        // being added or removed.
        spec.promptsChangeConsumer((List<McpSchema.Prompt> prompts) -> {
            // Handle prompts change
        });

        // Adds a consumer to be notified when logging messages are received from the server.
        spec.loggingConsumer((McpSchema.LoggingMessageNotification log) -> {
            // Handle log messages
        });
    }
}
@Component
public class CustomMcpAsyncClientCustomizer implements McpCustomizer<McpClient.AsyncSpec> {
    @Override
    public void customize(String serverConfigurationName, McpClient.AsyncSpec spec) {
        // Customize the async client configuration
        spec.requestTimeout(Duration.ofSeconds(30));
    }
}

serverConfigurationName 参数是应用自定义器并创建 MCP 客户端的服务器配置名称。spring-doc.cadn.net.cn

MCP 客户端自动配置会自动检测并应用应用程序上下文中的任何自定义器。spring-doc.cadn.net.cn

传输支持

自动配置支持多种传输类型:spring-doc.cadn.net.cn

  • 标准输入/输出(Stdio)(由 spring-ai-starter-mcp-clientspring-ai-starter-mcp-client-webflux 激活)spring-doc.cadn.net.cn

  • (HttpClient) HTTP/SSE 和 Streamable-HTTP(由 spring-ai-starter-mcp-client 激活)spring-doc.cadn.net.cn

  • (WebFlux) HTTP/SSE 和 Streamable-HTTP(由 spring-ai-starter-mcp-client-webflux 激活)spring-doc.cadn.net.cn

工具过滤

MCP Client Boot Starter 支持通过 McpToolFilter 接口对发现的工具进行过滤。这允许您根据自定义标准(例如 MCP 连接信息或工具属性)选择性地包含或排除工具。spring-doc.cadn.net.cn

要实现工具过滤,请创建一个实现 McpToolFilter 接口的 bean:spring-doc.cadn.net.cn

@Component
public class CustomMcpToolFilter implements McpToolFilter {

    @Override
    public boolean test(McpConnectionInfo connectionInfo, McpSchema.Tool tool) {
        // Filter logic based on connection information and tool properties
        // Return true to include the tool, false to exclude it

        // Example: Exclude tools from a specific client
        if (connectionInfo.clientInfo().name().equals("restricted-client")) {
            return false;
        }

        // Example: Only include tools with specific names
        if (tool.name().startsWith("allowed_")) {
            return true;
        }

        // Example: Filter based on tool description or other properties
        if (tool.description() != null &&
            tool.description().contains("experimental")) {
            return false;
        }

        return true; // Include all other tools by default
    }
}

McpConnectionInfo 记录提供对以下内容的访问:spring-doc.cadn.net.cn

该过滤器会自动检测并应用于同步和异步的 MCP 工具回调提供者。 如果未提供自定义过滤器,默认将包含所有发现的工具。spring-doc.cadn.net.cn

注意:应用上下文中应仅定义一个 McpToolFilter Bean。 如果需要多个过滤器,请将它们合并为一个组合过滤器实现。spring-doc.cadn.net.cn

工具名称前缀生成

MCP Client Boot Starter 通过 McpToolNamePrefixGenerator 接口支持自定义工具名称前缀的生成。此功能通过为工具名称添加唯一前缀,帮助在集成来自多个 MCP 服务器的工具时避免命名冲突。spring-doc.cadn.net.cn

默认情况下,如果没有提供自定义的 McpToolNamePrefixGenerator Bean,Starters将使用 DefaultMcpToolNamePrefixGenerator,以确保所有 MCP 客户端连接中的工具名称唯一。默认生成器:spring-doc.cadn.net.cn

  • 跟踪所有现有连接和工具名称以确保唯一性spring-doc.cadn.net.cn

  • 通过用下划线替换非字母数字字符来格式化工具名称(例如,my-tool 变为 my_toolspring-doc.cadn.net.cn

  • 当在不同连接中检测到重复的工具名称时,添加计数器前缀(例如:alt_1_toolNamealt_2_toolNamespring-doc.cadn.net.cn

  • 线程安全并保持幂等性——相同的(客户端、服务器、工具)组合始终获得相同的唯一名称。spring-doc.cadn.net.cn

  • 确保最终名称不超过 64 个字符(如有必要,从开头截断)spring-doc.cadn.net.cn

例如: * 工具 search 的首次出现 → search * 来自不同连接的工具 search 的第二次出现 → alt_1_search * 包含特殊字符的工具 my-special-toolmy_special_toolspring-doc.cadn.net.cn

您可以通过提供自己的实现来自定义此行为:spring-doc.cadn.net.cn

@Component
public class CustomToolNamePrefixGenerator implements McpToolNamePrefixGenerator {

    @Override
    public String prefixedToolName(McpConnectionInfo connectionInfo, Tool tool) {
        // Custom logic to generate prefixed tool names

        // Example: Use server name and version as prefix
        String serverName = connectionInfo.initializeResult().serverInfo().name();
        String serverVersion = connectionInfo.initializeResult().serverInfo().version();
        return serverName + "_v" + serverVersion.replace(".", "_") + "_" + tool.name();
    }
}

McpConnectionInfo 记录提供了有关 MCP 连接的全面信息:spring-doc.cadn.net.cn

内置前缀生成器

该框架提供了多种内置的前缀生成器:spring-doc.cadn.net.cn

  • DefaultMcpToolNamePrefixGenerator - 通过跟踪重复项并在需要时添加计数器前缀来确保工具名称的唯一性(如果未提供自定义 Bean,则默认使用)spring-doc.cadn.net.cn

  • McpToolNamePrefixGenerator.noPrefix() - 返回不带任何前缀的工具名称(如果多个服务器提供同名工具,可能会导致冲突)spring-doc.cadn.net.cn

要完全禁用前缀并使用原始工具名称(如果使用的是多个 MCP 服务器,则不推荐这样做),请将无前缀生成器注册为 Bean:spring-doc.cadn.net.cn

@Configuration
public class McpConfiguration {

    @Bean
    public McpToolNamePrefixGenerator mcpToolNamePrefixGenerator() {
        return McpToolNamePrefixGenerator.noPrefix();
    }
}

前缀生成器通过 Spring 的 ObjectProvider 机制自动检测并应用于同步和异步 MCP 工具回调提供者。 如果未提供自定义生成器 Bean,将自动使用 DefaultMcpToolNamePrefixGeneratorspring-doc.cadn.net.cn

当对多个 MCP 服务器使用 McpToolNamePrefixGenerator.noPrefix() 时,重复的工具名称将导致 IllegalStateException。默认的 DefaultMcpToolNamePrefixGenerator 通过自动为重复的工具名称添加唯一前缀来防止这种情况。

工具上下文到 MCP 元数据转换器

MCP Client Boot Starter 支持通过 ToolContextToMcpMetaConverter 接口,将 Spring AI 的 ToolContext 自定义转换为 MCP 工具调用元数据。 此功能允许您将额外的上下文信息(例如用户 ID、机密Tokens)作为元数据,与 LLM 生成的调用参数一同传递。spring-doc.cadn.net.cn

例如,您可以将 MCP progressToken 传递给工具上下文中的 MCP 进度流程,以跟踪长时间运行操作的进度:spring-doc.cadn.net.cn

ChatModel chatModel = ...

String response = ChatClient.create(chatModel)
        .prompt("Tell me more about the customer with ID 42")
        .toolContext(Map.of("progressToken", "my-progress-token"))
        .call()
        .content();

默认情况下,如果未提供自定义转换器 bean,Starters将使用 ToolContextToMcpMetaConverter.defaultConverter(),其作用是:spring-doc.cadn.net.cn

您可以通过提供自己的实现来自定义此行为:spring-doc.cadn.net.cn

@Component
public class CustomToolContextToMcpMetaConverter implements ToolContextToMcpMetaConverter {

    @Override
    public Map<String, Object> convert(ToolContext toolContext) {
        if (toolContext == null || toolContext.getContext() == null) {
            return Map.of();
        }

        // Custom logic to convert tool context to MCP metadata
        Map<String, Object> metadata = new HashMap<>();

        // Example: Add custom prefix to all keys
        for (Map.Entry<String, Object> entry : toolContext.getContext().entrySet()) {
            if (entry.getValue() != null) {
                metadata.put("app_" + entry.getKey(), entry.getValue());
            }
        }

        // Example: Add additional metadata
        metadata.put("timestamp", System.currentTimeMillis());
        metadata.put("source", "spring-ai");

        return metadata;
    }
}

内置转换器

该框架提供了内置的转换器:spring-doc.cadn.net.cn

  • ToolContextToMcpMetaConverter.defaultConverter() - 过滤掉 MCP 交换密钥和空值(如果未提供自定义 Bean,则默认使用)spring-doc.cadn.net.cn

  • ToolContextToMcpMetaConverter.noOp() - 返回一个空映射,实际上禁用了上下文到元数据的转换spring-doc.cadn.net.cn

要完全禁用上下文到元数据的转换:spring-doc.cadn.net.cn

@Configuration
public class McpConfiguration {

    @Bean
    public ToolContextToMcpMetaConverter toolContextToMcpMetaConverter() {
        return ToolContextToMcpMetaConverter.noOp();
    }
}

转换器通过 Spring 的 ObjectProvider 机制自动检测并应用于同步和异步 MCP 工具回调。 如果未提供自定义转换器 Bean,将自动使用默认转换器。spring-doc.cadn.net.cn

禁用 MCP ToolCallback 自动配置

MCP ToolCallback 自动配置默认启用,但可以通过 spring.ai.mcp.client.toolcallback.enabled=false 属性禁用。spring-doc.cadn.net.cn

当禁用时,不会从可用的 MCP 工具创建任何 ToolCallbackProvider Bean。spring-doc.cadn.net.cn

MCP 客户端注解

MCP 客户端Starters会自动检测并注册用于处理各种 MCP 客户端操作的注解方法:spring-doc.cadn.net.cn

示例用法:spring-doc.cadn.net.cn

@Component
public class McpClientHandlers {

    @McpLogging(clients = "server1")
    public void handleLoggingMessage(LoggingMessageNotification notification) {
        System.out.println("Received log: " + notification.level() +
                          " - " + notification.data());
    }

    @McpSampling(clients = "server1")
    public CreateMessageResult handleSamplingRequest(CreateMessageRequest request) {
        // Process the request and generate a response
        String response = generateLLMResponse(request);

        return CreateMessageResult.builder()
            .role(Role.ASSISTANT)
            .content(new TextContent(response))
            .model("gpt-4")
            .build();
    }

    @McpProgress(clients = "server1")
    public void handleProgressNotification(ProgressNotification notification) {
        double percentage = notification.progress() * 100;
        System.out.println(String.format("Progress: %.2f%% - %s",
            percentage, notification.message()));
    }

    @McpToolListChanged(clients = "server1")
    public void handleToolListChanged(List<McpSchema.Tool> updatedTools) {
        System.out.println("Tool list updated: " + updatedTools.size() + " tools available");
        // Update local tool registry
        toolRegistry.updateTools(updatedTools);
    }
}

这些注解支持同步和异步实现,并且可以使用 clients 参数为特定客户端进行配置:spring-doc.cadn.net.cn

@McpLogging(clients = "server1")
public void handleServer1Logs(LoggingMessageNotification notification) {
    // Handle logs from specific server
    logToFile("server1.log", notification);
}

@McpSampling(clients = "server1")
public Mono<CreateMessageResult> handleAsyncSampling(CreateMessageRequest request) {
    return Mono.fromCallable(() -> {
        String response = generateLLMResponse(request);
        return CreateMessageResult.builder()
            .role(Role.ASSISTANT)
            .content(new TextContent(response))
            .model("gpt-4")
            .build();
    }).subscribeOn(Schedulers.boundedElastic());
}

有关所有可用注解及其使用模式的详细信息,请参阅 MCP 客户端注解 文档。spring-doc.cadn.net.cn

使用示例

将适当的Starters依赖项添加到您的项目中,并在 application.propertiesapplication.yml 中配置客户端:spring-doc.cadn.net.cn

spring:
  ai:
    mcp:
      client:
        enabled: true
        name: my-mcp-client
        version: 1.0.0
        request-timeout: 30s
        type: SYNC  # or ASYNC for reactive applications
        sse:
          connections:
            server1:
              url: http://localhost:8080
            server2:
              url: http://otherserver:8081
        streamable-http:
          connections:
            server3:
              url: http://localhost:8083
              endpoint: /mcp
        stdio:
          root-change-notification: false
          connections:
            server1:
              command: /path/to/server
              args:
                - --port=8080
                - --mode=production
              env:
                API_KEY: your-api-key
                DEBUG: "true"

MCP 客户端 Bean 将自动配置并可用于注入:spring-doc.cadn.net.cn

@Autowired
private List<McpSyncClient> mcpSyncClients;  // For sync client

// OR

@Autowired
private List<McpAsyncClient> mcpAsyncClients;  // For async client

当工具回调启用时(默认行为),所有已注册的 MCP 客户端的 MCP 工具将作为 ToolCallbackProvider 实例提供:spring-doc.cadn.net.cn

@Autowired
private SyncMcpToolCallbackProvider toolCallbackProvider;
ToolCallback[] toolCallbacks = toolCallbackProvider.getToolCallbacks();

示例应用