MCP クライアント Boot スターター

Spring AI MCP (モデルコンテキストプロトコル) クライアント Boot スターターは、Spring Boot アプリケーションの MCP クライアント機能の自動構成を提供します。さまざまなトランスポートオプションを使用して、同期クライアント実装と非同期クライアント実装の両方をサポートします。

MCP クライアント Boot スターターは以下を提供します。

  • 複数のクライアントインスタンスの管理

  • 自動クライアント初期化 (有効な場合)

  • 複数の名前付きトランスポートのサポート (STDIO, Http/SSE and Streamable HTTP)

  • Spring AI のツール実行フレームワークとの統合

  • 選択的なツールの包含 / 除外のためのツールフィルタリング機能

  • 名前の競合を避けるためのカスタマイズ可能なツール名プレフィックス生成

  • アプリケーションコンテキストが閉じられたときにリソースを自動的にクリーンアップする適切なライフサイクル管理

  • カスタマイザーによるカスタマイズ可能なクライアント作成

スターター

標準 MCP クライアント

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

標準スターターは、STDIO (インプロセス)および SSEStreamable-HTTPStateless Streamable-HTTP トランスポートを介して、1 つ以上の MCP サーバーに同時に接続します。SSE および Streamable-Http トランスポートは、JDK HttpClient ベースのトランスポート実装を使用します。MCP サーバーへの接続ごとに、新しい MCP クライアントインスタンスが作成されます。MCP クライアントは SYNC または ASYNC のいずれかを選択できます(注: 同期クライアントと非同期クライアントを混在させることはできません)。本番環境のデプロイでは、WebFlux ベースの SSE および StreamableHttp 接続と spring-ai-starter-mcp-client-webflux を使用することをお勧めします。

WebFlux クライアント

WebFlux スターターは標準スターターと同様の機能を提供しますが、WebFlux ベースの Streamable-Http、Stateless Streamable-Http、および SSE トランスポート実装を使用します。

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

プロパティの構成

共通プロパティ

共通プロパティには spring.ai.mcp.client という接頭辞が付きます。

プロパティ 説明 デフォルト値

enabled

MCP クライアントを有効 / 無効にする

true

name

MCP クライアントインスタンスの名前

spring-ai-mcp-client

version

MCP クライアントインスタンスのバージョン

1.0.0

initialized

作成時にクライアントを初期化するかどうか

true

request-timeout

MCP クライアントリクエストのタイムアウト期間

20s

type

クライアント型(SYNC または ASYNC)。すべてのクライアントは同期または非同期のいずれかである必要があります。混在はサポートされていません

SYNC

root-change-notification

すべてのクライアントのルート変更通知を有効 / 無効にする

true

toolcallback.enabled

Spring AI のツール実行フレームワークとの MCP ツールコールバック統合を有効 / 無効にする

true

MCP アノテーションプロパティ

MCP クライアントアノテーションは、Java アノテーションを用いて MCP クライアントハンドラーを宣言的に実装する方法を提供します。クライアントの mcp-annotations プロパティには、spring.ai.mcp.client.annotation-scanner というプレフィックスが付きます。

プロパティ 説明 デフォルト値

enabled

MCP クライアントアノテーションの自動スキャンを有効 / 無効にする

true

Stdio トランスポートプロパティ

標準 I/O トランスポートのプロパティには spring.ai.mcp.client.stdio というプレフィックスが付きます。

プロパティ 説明 デフォルト値

servers-configuration

JSON 形式の MCP サーバー構成を含むリソース

-

connections

名前付き stdio 接続構成のマップ

-

connections.[name].command

MCP サーバーに対して実行するコマンド

-

connections.[name].args

コマンド引数のリスト

-

connections.[name].env

サーバープロセスの環境変数のマップ

-

構成例:

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"

あるいは、Claude デスクトップ形式 (英語) を使用して外部 JSON ファイルを使用して stdio 接続を構成することもできます。

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

Claude デスクトップ形式は次のようになります。

{
  "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 上でプロセスを生成しようとすると、次のものしか実行できません。

  • ネイティブ実行ファイル (.exe files)

  • cmd.exe で利用可能なシステムコマンド

npx.cmdnpm.cmd、さらには python.cmd (Microsoft Store から) などの Windows バッチファイルを実行するには、cmd.exe シェルが必要です。

ソリューション: cmd.exe ラッパー

バッチファイルコマンドを cmd.exe /c で囲みます:

Windows Configuration:

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

Linux/macOS Configuration:

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

Cross-Platform Programmatic Configuration

For applications that need to work across platforms without separate configuration files, use OS detection in your Spring Boot application:

@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, McpJsonMapper.createDefault()))
            .requestTimeout(Duration.ofSeconds(10))
            .build()
            .initialize();
}

private static boolean isWindows() {
    return System.getProperty("os.name").toLowerCase().contains("win");
}
When using programmatic configuration with @Bean, add @ConditionalOnMissingBean(McpSyncClient.class) to avoid conflicts with auto-configuration from JSON files.

Path Considerations

相対パス (recommended for portability):

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

The MCP server resolves relative paths based on the application’s working directory.

絶対パス (Windows requires backslashes or escaped forward slashes):

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

Common Windows Batch Files Requiring cmd.exe

  • npx.cmdnpm.cmd - Node パッケージマネージャー

  • python.cmd - Python (Microsoft Store installation)

  • pip.cmd - Python package manager

  • mvn.cmd - Maven wrapper

  • gradle.cmd - Gradle ラッパー

  • Custom .cmd or .bat scripts

Reference Implementation

See Spring AI Examples - ファイルシステム [GitHub] (英語) for a complete cross-platform MCP client implementation that automatically detects the OS and configures the client appropriately.

ストリーミング可能な HTTP トランスポートプロパティ

Streamable-HTTP および Stateless Streamable-HTTP MCP サーバーに接続するために使用されます。

Streamable-HTTP トランスポートのプロパティには、spring.ai.mcp.client.streamable-http という接頭辞が付きます。

プロパティ 説明 デフォルト値

connections

名前付き Streamable-HTTP 接続構成のマップ

-

connections.[name].url

MCP サーバーとの Streamable-Http 通信のベース URL エンドポイント

-

connections.[name].endpoint

接続に使用するストリーミング可能な http エンドポイント (URL サフィックスとして)

/mcp

構成例:

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 というプレフィックスが付きます。

プロパティ 説明 デフォルト値

connections

名前付き SSE 接続構成のマップ

-

connections.[name].url

MCP サーバーとの SSE 通信のベース URL エンドポイント

-

connections.[name].sse-endpoint

接続に使用する SSE エンドポイント(URL サフィックスとして)

/sse

構成例:

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 Splitting Guidelines

When you have a full SSE URL, split it into base URL and endpoint path:

完全 URL 構成

http://localhost:3000/mcp-hub/sse/token123

url: localhost:3000
sse-endpoint: /mcp-hub/sse/token123

https://api.service.com/v2/events?key=secret

url: api.service.com (英語)
sse-endpoint: /v2/events?key=secret

http://localhost:8080/sse

url: localhost:8080
sse-endpoint: /sse (or omit for default)

Troubleshooting SSE Connections

404 Not Found Errors:

  • Verify URL splitting: ensure the base url contains only the scheme, host, and port

  • Check the sse-endpoint starts with / and includes the full path and query parameters

  • Test the full URL directly in a browser or curl to confirm it’s accessible

Streamable Http Transport Properties

Properties for Streamable Http transport are prefixed with spring.ai.mcp.client.streamable-http:

Property Description Default Value

connections

名前付きストリーミング可能な HTTP 接続構成のマップ

-

connections.[name].url

MCP サーバーとの Streamable-Http 通信のベース URL エンドポイント

-

connections.[name].endpoint

接続に使用するストリーミング可能な http エンドポイント (URL サフィックスとして)

/mcp

構成例:

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

機能

同期 / 非同期クライアントの種類

スターターは 2 種類のクライアントをサポートします。

  • 同期 - デフォルトのクライアント型(spring.ai.mcp.client.type=SYNC)。ブロッキング操作を伴う従来のリクエストレスポンスパターンに適しています

NOTE : SYNC クライアントは、同期 MCP アノテーション付きメソッドのみを登録します。非同期メソッドは無視されます。

  • 非同期 - spring.ai.mcp.client.type=ASYNC を使用して構成された、ノンブロッキング操作を伴うリアクティブアプリケーションに適しています。

NOTE : ASYNC クライアントは、MCP アノテーションが付けられた非同期メソッドのみを登録します。同期メソッドは無視されます。

クライアントのカスタマイズ

自動構成は、コールバックインターフェースを通じて広範なクライアント仕様のカスタマイズ機能を提供します。これらのカスタマイザーを使用すると、リクエストのタイムアウトからイベント処理やメッセージ処理まで、MCP クライアントの動作のさまざまなアスペクトを構成できます。

カスタマイズの種類

次のカスタマイズオプションが利用可能です。

  • リクエスト構成 - カスタムリクエストタイムアウトを設定する

  • カスタムサンプリングハンドラー (英語) - サーバーがクライアント経由で LLM に LLM サンプリング (completions または generations) をリクエストするための標準化された方法。このフローにより、クライアントはモデルのアクセス、選択、権限を制御しながら、サーバーが AI 機能を活用できるようになります。サーバー API キーは必要ありません。

  • ファイルシステム(ルート)アクセス (英語) - クライアントがファイルシステム roots をサーバーに公開するための標準化された方法。ルートは、ファイルシステム内でサーバーが操作できる範囲の境界を定義し、サーバーがアクセスできるディレクトリとファイルを理解できるようにします。サーバーは、サポートしているクライアントからルートのリストをリクエストし、そのリストが変更されたときに通知を受け取ることができます。

  • Elicitation Handlers (英語) - サーバーが対話中にクライアントを通じてユーザーに追加情報をリクエストするための標準化された方法。

  • イベントハンドラー - 特定のサーバーイベントが発生したときに通知されるクライアントのハンドラー:

    • ツール変更通知 - 利用可能なサーバーツールのリストが変更されたとき

    • リソース変更通知 - 利用可能なサーバーリソースのリストが変更されたとき。

    • プロンプト変更通知 - 利用可能なサーバープロンプトのリストが変更されたとき。

    • ログハンドラー (英語) - サーバーが構造化されたログメッセージをクライアントに送信するための標準化された方法。

    • Progress Handlers (英語) - サーバーが構造化された進行状況メッセージをクライアントに送信するための標準化された方法。

Clients can control logging verbosity by setting minimum log levels

Client Customization Example

アプリケーションのニーズに応じて、同期クライアント用の McpSyncClientCustomizer または非同期クライアント用の McpAsyncClientCustomizer のいずれかを実装できます。

  • 同期化

  • 非同期

@Component
public class CustomMcpSyncClientCustomizer implements McpSyncClientCustomizer {
    @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 McpAsyncClientCustomizer {
    @Override
    public void customize(String serverConfigurationName, McpClient.AsyncSpec spec) {
        // Customize the async client configuration
        spec.requestTimeout(Duration.ofSeconds(30));
    }
}

serverConfigurationName パラメーターは、カスタマイザが適用され、MCP クライアントが作成されるサーバー構成の名前です。

MCP クライアントの自動構成は、アプリケーションコンテキストで見つかったカスタマイザーを自動的に検出して適用します。

輸送サポート

自動構成では、複数のトランスポート型がサポートされます。

  • 標準 I/O (スタジオ) (activated by the spring-ai-starter-mcp-client and spring-ai-starter-mcp-client-webflux)

  • (HttpClient) HTTP/SSE and Streamable-HTTP (spring-ai-starter-mcp-client によって活性化される)

  • (WebFlux) HTTP/SSE and Streamable-HTTP (spring-ai-starter-mcp-client-webflux によって活性化される)

Tool Filtering

The MCP Client Boot Starter supports filtering of discovered tools through the McpToolFilter interface. This allows you to selectively include or exclude tools based on custom criteria such as the MCP connection information or tool properties.

To implement tool filtering, create a bean that implements the McpToolFilter interface:

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

The McpConnectionInfo record provides access to:

  • clientCapabilities - The capabilities of the MCP client

  • clientInfo - Information about the MCP client (名前とバージョン)

  • initializeResult - The initialization result from the MCP server

The filter is automatically detected and applied to both synchronous and asynchronous MCP tool callback providers. If no custom filter is provided, all discovered tools are included by default.

メモ: Only one McpToolFilter bean should be defined in the application context. If multiple filters are needed, combine them into a single composite filter implementation.

Tool Name Prefix Generation

The MCP Client Boot Starter supports customizable tool name prefix generation through the McpToolNamePrefixGenerator interface. This feature helps avoid naming conflicts when integrating tools from multiple MCP servers by adding unique prefixes to tool names.

By default, if no custom McpToolNamePrefixGenerator bean is provided, the starter uses DefaultMcpToolNamePrefixGenerator which ensures unique tool names across all MCP client connections. The default generator:

  • Tracks all existing connections and tool names to ensure uniqueness

  • Formats tool names by replacing non-alphanumeric characters with underscores (e.g., my-tool becomes my_tool)

  • When duplicate tool names are detected across different connections, adds a counter prefix (e.g., alt_1_toolNamealt_2_toolName)

  • Is thread-safe and maintains idempotency - the same combination of (client, server, tool) always gets the same unique name

  • Ensures the final name doesn’t exceed 64 characters (truncating from the beginning if necessary)

次に例を示します: * First occurrence of tool search → search * Second occurrence of tool search from a different connection → alt_1_search * Tool with special characters my-special-tool → my_special_tool

You can customize this behavior by providing your own implementation:

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

The McpConnectionInfo record provides comprehensive information about the MCP connection:

  • clientCapabilities - The capabilities of the MCP client

  • clientInfo - Information about the MCP client (name, title, and version)

  • initializeResult - The initialization result from the MCP server, including server information

Built-in Prefix Generators

The framework provides several built-in prefix generators:

  • DefaultMcpToolNamePrefixGenerator - Ensures unique tool names by tracking duplicates and adding counter prefixes when needed (used by default if no custom bean is provided)

  • McpToolNamePrefixGenerator.noPrefix() - Returns tool names without any prefix (may cause conflicts if multiple servers provide tools with the same name)

To disable prefixing entirely and use raw tool names (not recommended if using multiple MCP servers), register the no-prefix generator as a bean:

@Configuration
public class McpConfiguration {

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

The prefix generator is automatically detected and applied to both synchronous and asynchronous MCP tool callback providers through Spring’s ObjectProvider mechanism. If no custom generator bean is provided, the DefaultMcpToolNamePrefixGenerator is used automatically.

When using McpToolNamePrefixGenerator.noPrefix() with multiple MCP servers, duplicate tool names will cause an IllegalStateException. The default DefaultMcpToolNamePrefixGenerator prevents this by automatically adding unique prefixes to duplicate tool names.

Tool Context to MCP Meta Converter

The MCP Client Boot Starter supports customizable conversion of Spring AI’s ToolContext to MCP tool-call metadata through the ToolContextToMcpMetaConverter interface. This feature allows you to pass additional contextual information (e.g. user id, secrets token) as metadata along with the LLM’s generated call arguments.

For example you can pass the MCP progressToken to your MCP Progress Flow (英語) in the tool context to track the progress of long-running operations:

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();

By default, if no custom converter bean is provided, the starter uses ToolContextToMcpMetaConverter.defaultConverter() which:

  • Filters out the MCP exchange key (McpToolUtils.TOOL_CONTEXT_MCP_EXCHANGE_KEY)

  • Filters out entries with null values

  • Passes through all other context entries as metadata

You can customize this behavior by providing your own implementation:

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

Built-in Converters

The framework provides built-in converters:

  • ToolContextToMcpMetaConverter.defaultConverter() - Filters out MCP exchange key and null values (used by default if no custom bean is provided)

  • ToolContextToMcpMetaConverter.noOp() - Returns an empty map, effectively disabling context-to-metadata conversion

To disable context-to-metadata conversion entirely:

@Configuration
public class McpConfiguration {

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

The converter is automatically detected and applied to both synchronous and asynchronous MCP tool callbacks through Spring’s ObjectProvider mechanism. If no custom converter bean is provided, the default converter is used automatically.

Disable the MCP ToolCallback Auto-Configuration

The MCP ToolCallback auto-configuration is enabled by default, but can be disabled with the spring.ai.mcp.client.toolcallback.enabled=false property.

When disabled, no ToolCallbackProvider bean is created from the available MCP tools.

MCP クライアントアノテーション

The MCP Client Boot Starter automatically detects and registers annotated methods for handling various MCP client operations:

  • @McpLogging - Handles logging message notifications from MCP servers

  • @McpSampling - Handles sampling requests from MCP servers for LLM completions

  • @McpElicitation - Handles elicitation requests to gather additional information from users

  • @McpProgress - Handles progress notifications for long-running operations

  • @McpToolListChanged - Handles notifications when the server’s tool list changes

  • @McpResourceListChanged - Handles notifications when the server’s resource list changes

  • @McpPromptListChanged - Handles notifications when the server’s prompt list changes

使用例:

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

The annotations support both synchronous and asynchronous implementations, and can be configured for specific clients using the clients parameter:

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

For detailed information about all available annotations and their usage patterns, see the MCP クライアントアノテーション documentation.

使用例

適切なスターター依存関係をプロジェクトに追加し、application.properties または application.yml でクライアントを構成します。

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 は自動的に構成され、注入に使用できるようになります。

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

// OR

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

ツールコールバックが有効になっている場合 (デフォルトの動作)、すべての MCP クライアントに登録された MCP ツールは ToolCallbackProvider インスタンスとして提供されます。

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

アプリケーション例