diff --git a/mcp/common/src/main/java/org/springframework/ai/mcp/AsyncMcpToolCallbackProvider.java b/mcp/common/src/main/java/org/springframework/ai/mcp/AsyncMcpToolCallbackProvider.java
index 3525b9593e3..60233429ec9 100644
--- a/mcp/common/src/main/java/org/springframework/ai/mcp/AsyncMcpToolCallbackProvider.java
+++ b/mcp/common/src/main/java/org/springframework/ai/mcp/AsyncMcpToolCallbackProvider.java
@@ -18,7 +18,9 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import java.util.function.BiPredicate;
+import java.util.stream.Collectors;
import io.modelcontextprotocol.client.McpAsyncClient;
import io.modelcontextprotocol.spec.McpSchema.Tool;
@@ -122,6 +124,34 @@ public AsyncMcpToolCallbackProvider(McpAsyncClient... mcpClients) {
this(List.of(mcpClients));
}
+ /**
+ * Creates a new {@code AsyncMcpToolCallbackProvider} instance that includes only
+ * clients from the specified allowed servers.
+ *
+ * This constructor:
+ *
+ * - Filters the provided MCP clients to only those matching allowed server
+ * names
+ * - Retains all tools from the selected clients (no additional tool filtering)
+ * - Ensures no null parameters are passed
+ * - Maintains full asynchronous operation capability
+ *
+ * @param mcpClients complete list of available MCP async clients
+ * @param allowedServerNames set of server names to include (case-sensitive)
+ * @throws IllegalArgumentException if parameters are null or empty
+ * @since 1.1.0
+ */
+ public AsyncMcpToolCallbackProvider(List mcpClients, Set allowedServerNames) {
+ Assert.notNull(mcpClients, "MCP clients list must not be null");
+ Assert.notNull(allowedServerNames, "Allowed server names set must not be null");
+ Assert.notEmpty(allowedServerNames, "Allowed server names set must not be empty");
+
+ this.mcpClients = mcpClients.stream()
+ .filter(client -> allowedServerNames.contains(client.getServerInfo().name()))
+ .collect(Collectors.toList());
+ this.toolFilter = (client, tool) -> true;
+ }
+
/**
* Discovers and returns all available tools from the configured MCP servers.
*
diff --git a/mcp/common/src/main/java/org/springframework/ai/mcp/SyncMcpToolCallbackProvider.java b/mcp/common/src/main/java/org/springframework/ai/mcp/SyncMcpToolCallbackProvider.java
index 7d0aa4276a1..c46c45feba5 100644
--- a/mcp/common/src/main/java/org/springframework/ai/mcp/SyncMcpToolCallbackProvider.java
+++ b/mcp/common/src/main/java/org/springframework/ai/mcp/SyncMcpToolCallbackProvider.java
@@ -17,6 +17,7 @@
package org.springframework.ai.mcp;
import java.util.List;
+import java.util.Set;
import java.util.function.BiPredicate;
import io.modelcontextprotocol.client.McpSyncClient;
@@ -115,6 +116,33 @@ public SyncMcpToolCallbackProvider(McpSyncClient... mcpClients) {
this(List.of(mcpClients));
}
+ /**
+ * Creates a new {@code SyncMcpToolCallbackProvider} instance that includes only
+ * clients from the specified allowed servers.
+ *
+ * This constructor:
+ *
+ * - Filters the provided MCP clients to only those matching allowed server
+ * names
+ * - Retains all tools from the selected clients (no additional tool filtering)
+ * - Ensures no null parameters are passed
+ *
+ * @param mcpClients complete list of available MCP clients
+ * @param allowedServerNames set of server names to include (case-sensitive)
+ * @throws IllegalArgumentException if parameters are null or empty
+ * @since 1.1.0
+ */
+ public SyncMcpToolCallbackProvider(List mcpClients, Set allowedServerNames) {
+ Assert.notNull(mcpClients, "MCP clients list must not be null");
+ Assert.notNull(allowedServerNames, "Allowed server names set must not be null");
+ Assert.notEmpty(allowedServerNames, "Allowed server names set must not be empty");
+
+ this.mcpClients = mcpClients.stream()
+ .filter(client -> allowedServerNames.contains(client.getServerInfo().name()))
+ .toList();
+ this.toolFilter = (client, tool) -> true; // No additional filtering
+ }
+
/**
* Discovers and returns all available tools from all connected MCP servers.
*