このバージョンはまだ開発中であり、まだ安定しているとは考えられていません。最新のスナップショットバージョンについては、Spring AI 1.1.2 を使用してください。 |
MCP クライアント Boot スターター
Spring AI MCP (モデルコンテキストプロトコル) クライアント Boot スターターは、Spring Boot アプリケーションの MCP クライアント機能の自動構成を提供します。さまざまなトランスポートオプションを使用して、同期クライアント実装と非同期クライアント実装の両方をサポートします。
MCP クライアント Boot スターターは以下を提供します。
複数のクライアントインスタンスの管理
自動クライアント初期化 (有効な場合)
複数の名前付きトランスポートのサポート (STDIO、Http/SSE、ストリーミング可能な HTTP)
Spring AI のツール実行フレームワークとの統合
選択的なツールの包含 / 除外のためのツールフィルタリング機能
名前の競合を避けるためのカスタマイズ可能なツール名プレフィックス生成
アプリケーションコンテキストが閉じられたときにリソースを自動的にクリーンアップする適切なライフサイクル管理
カスタマイザーによるカスタマイズ可能なクライアント作成
スターター
標準 MCP クライアント
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency> 標準スターターは、STDIO (インプロセス)および SSE、Streamable-HTTP、Stateless Streamable-HTTP トランスポートを介して、1 つ以上の MCP サーバーに同時に接続します。SSE および Streamable-Http トランスポートは、JDK HttpClient ベースのトランスポート実装を使用します。MCP サーバーへの接続ごとに、新しい MCP クライアントインスタンスが作成されます。MCP クライアントは SYNC または ASYNC のいずれかを選択できます(注: 同期クライアントと非同期クライアントを混在させることはできません)。本番環境のデプロイでは、WebFlux ベースの SSE および StreamableHttp 接続と spring-ai-starter-mcp-client-webflux を使用することをお勧めします。
プロパティの構成
共通プロパティ
共通プロパティには spring.ai.mcp.client という接頭辞が付きます。
| プロパティ | 説明 | デフォルト値 |
|---|---|---|
| MCP クライアントを有効 / 無効にする |
|
| MCP クライアントインスタンスの名前 |
|
| MCP クライアントインスタンスのバージョン |
|
| 作成時にクライアントを初期化するかどうか |
|
| MCP クライアントリクエストのタイムアウト期間 |
|
| クライアント型(SYNC または ASYNC)。すべてのクライアントは同期または非同期のいずれかである必要があります。混在はサポートされていません |
|
| すべてのクライアントのルート変更通知を有効 / 無効にする |
|
| Spring AI のツール実行フレームワークとの MCP ツールコールバック統合を有効 / 無効にする |
|
MCP アノテーションプロパティ
MCP クライアントアノテーションは、Java アノテーションを用いて MCP クライアントハンドラーを宣言的に実装する方法を提供します。クライアントの mcp-annotations プロパティには、spring.ai.mcp.client.annotation-scanner というプレフィックスが付きます。
| プロパティ | 説明 | デフォルト値 |
|---|---|---|
| MCP クライアントアノテーションの自動スキャンを有効 / 無効にする |
|
Stdio トランスポートプロパティ
標準 I/O トランスポートのプロパティには spring.ai.mcp.client.stdio というプレフィックスが付きます。
| プロパティ | 説明 | デフォルト値 |
|---|---|---|
| JSON 形式の MCP サーバー構成を含むリソース | - |
| 名前付き stdio 接続構成のマップ | - |
| MCP サーバーに対して実行するコマンド | - |
| コマンド引数のリスト | - |
| サーバープロセスの環境変数のマップ | - |
構成例:
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.jsonClaude デスクトップ形式は次のようになります。
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/username/Desktop",
"/Users/username/Downloads"
]
}
}
}Windows STDIO 構成
Windows では、npx、npm、node などのコマンドはネイティブ実行ファイルではなく、バッチファイル(.cmd)として実装されています。Java の ProcessBuilder はバッチファイルを直接実行することができず、cmd.exe /c ラッパーが必要です。 |
Windows に特別な処理が必要な理由
Java の ProcessBuilder (StdioClientTransport によって内部的に使用される) が Windows 上でプロセスを生成しようとすると、次のものしか実行できません。
ネイティブ実行ファイル (
.exeファイル)cmd.exeで利用可能なシステムコマンド
npx.cmd、npm.cmd、さらには python.cmd (Microsoft Store から) などの Windows バッチファイルを実行するには、cmd.exe シェルが必要です。
ソリューション: cmd.exe ラッパー
バッチファイルコマンドを cmd.exe /c で囲みます:
Windows 構成:
{
"mcpServers": {
"filesystem": {
"command": "cmd.exe",
"args": [
"/c",
"npx",
"-y",
"@modelcontextprotocol/server-filesystem",
"C:\\Users\\username\\Desktop"
]
}
}
}Linux/macOS 構成:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/username/Desktop"
]
}
}
}クロスプラットフォームのプログラムによる構成
個別の構成ファイルを使用せずにプラットフォーム間で動作する必要があるアプリケーションの場合は、Spring Boot アプリケーションで OS 検出を使用します。
@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");
}@Bean でプログラムによる構成を使用する場合は、JSON ファイルからの自動構成との競合を避けるために @ConditionalOnMissingBean(McpSyncClient.class) を追加します。 |
パスの考慮事項
相対パス(携帯性重視ならおすすめ):
{
"command": "cmd.exe",
"args": ["/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "target"]
}MCP サーバーは、アプリケーションの作業ディレクトリに基づいて相対パスを解決します。
絶対パス (Windows ではバックスラッシュまたはエスケープされたスラッシュが必要です):
{
"command": "cmd.exe",
"args": ["/c", "npx", "-y", "@modelcontextprotocol/server-filesystem", "C:\\Users\\username\\project\\target"]
}リファレンス実装
OS を自動的に検出し、クライアントを適切に構成する完全なクロスプラットフォーム MCP クライアント実装については、Spring AI の例 - ファイルシステム [GitHub] (英語) を参照してください。
ストリーミング可能な HTTP トランスポートプロパティ
Streamable-HTTP および Stateless Streamable-HTTP MCP サーバーに接続するために使用されます。
Streamable-HTTP トランスポートのプロパティには、spring.ai.mcp.client.streamable-http という接頭辞が付きます。
| プロパティ | 説明 | デフォルト値 |
|---|---|---|
| 名前付き Streamable-HTTP 接続構成のマップ | - |
| MCP サーバーとの Streamable-Http 通信のベース URL エンドポイント | - |
| 接続に使用するストリーミング可能な http エンドポイント (URL サフィックスとして) |
|
構成例:
spring:
ai:
mcp:
client:
streamable-http:
connections:
server1:
url: http://localhost:8080
server2:
url: http://otherserver:8081
endpoint: /custom-sseSSE トランスポートプロパティ
サーバー送信イベント (SSE) トランスポートのプロパティには、spring.ai.mcp.client.sse というプレフィックスが付きます。
| プロパティ | 説明 | デフォルト値 |
|---|---|---|
| 名前付き SSE 接続構成のマップ | - |
| MCP サーバーとの SSE 通信のベース URL エンドポイント | - |
| 接続に使用する SSE エンドポイント(URL サフィックスとして) |
|
構成例:
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=jsonURL 分割ガイドライン
完全な SSE URL がある場合は、それをベース URL とエンドポイントパスに分割します。
| 完全 URL | 構成 |
|---|---|
|
|
|
|
|
|
Streamable Http Transport Properties
Properties for Streamable Http transport are prefixed with spring.ai.mcp.client.streamable-http:
| Property | Description | Default Value |
|---|---|---|
| 名前付きストリーミング可能な HTTP 接続構成のマップ | - |
| MCP サーバーとの Streamable-Http 通信のベース URL エンドポイント | - |
| 接続に使用するストリーミング可能な http エンドポイント (URL サフィックスとして) |
|
構成例:
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をサーバーに公開するための標準化された方法。ルートは、ファイルシステム内でサーバーが操作できる範囲の境界を定義し、サーバーがアクセスできるディレクトリとファイルを理解できるようにします。サーバーは、サポートしているクライアントからルートのリストをリクエストし、そのリストが変更されたときに通知を受け取ることができます。誘導ハンドラー (英語) - サーバーが対話中にクライアントを通じてユーザーに追加情報をリクエストするための標準化された方法。
イベントハンドラー - 特定のサーバーイベントが発生したときに通知されるクライアントのハンドラー:
ツール変更通知 - 利用可能なサーバーツールのリストが変更されたとき
リソース変更通知 - 利用可能なサーバーリソースのリストが変更されたとき。
プロンプト変更通知 - 利用可能なサーバープロンプトのリストが変更されたとき。
ログハンドラー (英語) - サーバーが構造化されたログメッセージをクライアントに送信するための標準化された方法。
進行状況ハンドラー (英語) - サーバーが構造化された進行状況メッセージをクライアントに送信するための標準化された方法。
クライアントは最小ログレベルを設定することでログの詳細度を制御できる
クライアントのカスタマイズ例
アプリケーションのニーズに応じて、同期クライアント用の 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 (スタジオ) (
spring-ai-starter-mcp-clientとspring-ai-starter-mcp-client-webfluxによって活性化される)(HttpClient) HTTP/SSE と Streamable-HTTP (
spring-ai-starter-mcp-clientによって活性化される)(WebFlux) HTTP/SSE と Streamable-HTTP (
spring-ai-starter-mcp-client-webfluxによって活性化される)
ツールフィルタリング
MCP クライアント Boot スターターは、McpToolFilter インターフェースを介して検出されたツールのフィルタリングをサポートしています。これにより、MCP 接続情報やツールプロパティなどのカスタム条件に基づいて、ツールを選択的に含めたり除外したりできます。
ツールフィルタリングを実装するには、McpToolFilter インターフェースを実装する Bean を作成します。
@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 レコードは、次のものへのアクセスを提供します。
clientCapabilities- MCP クライアントの機能clientInfo- MCP クライアントに関する情報 (名前とバージョン)initializeResult- MCP サーバーからの初期化結果
フィルターは自動的に検出され、同期および非同期の MCP ツールコールバックプロバイダーに適用されます。カスタムフィルターが指定されていない場合は、検出されたすべてのツールがデフォルトで含まれます。
メモ: アプリケーションコンテキストでは、McpToolFilter または Bean を 1 つだけ定義してください。複数のフィルターが必要な場合は、1 つの複合フィルター実装に統合してください。
ツール名プレフィックスの生成
MCP クライアント Boot スターターは、McpToolNamePrefixGenerator インターフェースを介してカスタマイズ可能なツール名プレフィックス生成をサポートしています。この機能により、複数の MCP サーバーのツールを統合する際の名前の競合を回避できます。ツール名に固有のプレフィックスを追加することで、この問題を解決できます。
デフォルトでは、カスタム McpToolNamePrefixGenerator Bean が指定されていない場合、スターターは DefaultMcpToolNamePrefixGenerator を使用します。これにより、すべての MCP クライアント接続で一意のツール名が確保されます。デフォルトのジェネレーターは次のとおりです。
既存の接続とツール名をすべて追跡して一意性を確保します
英数字以外の文字をアンダースコアに置き換えてツール名をフォーマットします (たとえば、
my-toolはmy_toolになります)異なる接続間で重複したツール名が検出されると、カウンタープレフィックスが追加されます (例:
alt_1_toolName、alt_2_toolName)スレッドセーフであり、べき等性を維持します。クライアント、サーバー、ツールの同じ組み合わせは常に同じ一意の名前を取得します。
最終的な名前が 64 文字を超えないようにします (必要に応じて先頭から切り捨てる)
次に例を示します: * ツール search の最初の出現 → search * 異なる接続からのツール search の 2 番目の出現 → alt_1_search * 特殊文字を含むツール my-special-tool → my_special_tool
独自の実装を提供することで、この動作をカスタマイズできます。
@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 接続に関する包括的な情報を提供します。
clientCapabilities- MCP クライアントの機能clientInfo- MCP クライアントに関する情報 (名前、タイトル、バージョン)initializeResult- MCP サーバーからの初期化結果(サーバー情報を含む)
組み込みプレフィックスジェネレーター
フレームワークには、いくつかの組み込みプレフィックスジェネレーターが用意されています。
DefaultMcpToolNamePrefixGenerator- 重複を追跡し、必要に応じてカウンタープレフィックスを追加することで、ツール名の一意性を確保します。(カスタム Bean が提供されていない場合はデフォルトで使用される)McpToolNamePrefixGenerator.noPrefix()- プレフィックスなしでツール名を返します (複数のサーバーが同じ名前のツールを提供する場合、競合が発生する可能性があります)
プレフィックスを完全に無効にして生のツール名を使用するには (複数の MCP サーバーを使用している場合は推奨されません)、プレフィックスなしジェネレーターを Bean として登録します。
@Configuration
public class McpConfiguration {
@Bean
public McpToolNamePrefixGenerator mcpToolNamePrefixGenerator() {
return McpToolNamePrefixGenerator.noPrefix();
}
} プレフィックスジェネレーターは、Spring の ObjectProvider メカニズムを通じて自動的に検出され、同期および非同期の MCP ツールコールバックプロバイダに適用されます。カスタムジェネレーター Bean が提供されていない場合は、DefaultMcpToolNamePrefixGenerator が自動的に使用されます。
複数の MCP サーバーで McpToolNamePrefixGenerator.noPrefix() を使用する場合、ツール名が重複すると IllegalStateException が発生します。デフォルトの DefaultMcpToolNamePrefixGenerator では、重複するツール名に自動的に固有のプレフィックスを追加することで、この問題を防止します。 |
ツールコンテキストから MCP メタコンバーターへ
MCP クライアント Boot スターターは、ToolContextToMcpMetaConverter インターフェースを介して、Spring AI の ToolContext から MCP ツール呼び出しメタデータへのカスタマイズ可能な変換をサポートしています。この機能により、LLM によって生成された呼び出し引数に加えて、追加のコンテキスト情報(例: ユーザー ID、シークレットトークン)をメタデータとして渡すことができます。
たとえば、ツールコンテキストで MCP progressToken を MCP 進捗フロー (英語) に渡して、長時間実行される操作の進行状況を追跡できます。
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 が提供されていない場合、スターターは次の ToolContextToMcpMetaConverter.defaultConverter() を使用します。
MCP 交換キーを除外する (
McpToolUtils.TOOL_CONTEXT_MCP_EXCHANGE_KEY)NULL 値のエントリを除外します
他のすべてのコンテキストエントリをメタデータとして渡す
独自の実装を提供することで、この動作をカスタマイズできます。
@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;
}
}内蔵コンバーター
フレームワークには組み込みコンバーターが用意されています。
ToolContextToMcpMetaConverter.defaultConverter()- MCP 交換キーと null 値を除外します (カスタム Bean が提供されていない場合はデフォルトで使用される)ToolContextToMcpMetaConverter.noOp()- 空のマップを返し、コンテキストからメタデータへの変換を事実上無効にします。
コンテキストからメタデータへの変換を完全に無効にするには:
@Configuration
public class McpConfiguration {
@Bean
public ToolContextToMcpMetaConverter toolContextToMcpMetaConverter() {
return ToolContextToMcpMetaConverter.noOp();
}
} コンバーターは Spring の ObjectProvider メカニズムを通じて自動的に検出され、同期および非同期の MCP ツールコールバックに適用されます。カスタムコンバーター Bean が指定されていない場合は、デフォルトのコンバーターが自動的に使用されます。
MCP クライアントアノテーション
MCP クライアント Boot スターターは、さまざまな MCP クライアント操作を処理するためのアノテーション付きメソッドを自動的に検出し、登録します。
@McpLogging - MCP サーバーからのログメッセージ通知を処理します
@McpSampling - LLM 補完のための MCP サーバーからのサンプリングリクエストを処理します
@McpElicitation - ユーザーから追加情報を収集するための情報収集リクエストを処理します
@McpProgress - 長時間実行される操作の進行状況通知を処理します
@McpToolListChanged - サーバーのツールリストが変更されたときに通知を処理します
@McpResourceListChanged - サーバーのリソースリストが変更されたときに通知を処理します
@McpPromptListChanged - サーバーのプロンプトリストが変更されたときに通知を処理します
使用例:
@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 パラメーターを使用して特定のクライアント用に構成できます。
@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 クライアントアノテーションのドキュメントを参照してください。
使用例
適切なスターター依存関係をプロジェクトに追加し、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();アプリケーション例
Brave Web 検索チャットボット [GitHub] (英語) - モデルコンテキストプロトコルを使用して Web 検索サーバーと対話するチャットボット。
デフォルトの MCP クライアントスターター [GitHub] (英語) - デフォルトの
spring-ai-starter-mcp-clientMCP クライアント Boot スターターを使用する簡単な例。WebFlux MCP クライアントスターター [GitHub] (英語) -
spring-ai-starter-mcp-client-webfluxMCP クライアント Boot スターターの使用の簡単な例。