Spring Framework integration for Model Context Protocol (MCP), providing Spring AI function calling capabilities and Spring-friendly abstractions for MCP clients and MCP servers
Access MCP client and server metadata including capabilities and initialization results through the McpConnectionInfo record.
import org.springframework.ai.mcp.McpConnectionInfo;
import io.modelcontextprotocol.spec.McpSchema;public record McpConnectionInfo(
McpSchema.ClientCapabilities clientCapabilities,
McpSchema.Implementation clientInfo,
McpSchema.InitializeResult initializeResult
) {
static Builder builder();
}Record containing MCP client and server metadata.
McpSchema.ClientCapabilities clientCapabilities()
McpSchema.Implementation clientInfo()
McpSchema.InitializeResult initializeResult()static Builder builder()
class Builder {
Builder clientCapabilities(McpSchema.ClientCapabilities clientCapabilities);
Builder clientInfo(McpSchema.Implementation clientInfo);
Builder initializeResult(McpSchema.InitializeResult initializeResult);
McpConnectionInfo build();
}McpConnectionInfo connectionInfo = McpConnectionInfo.builder()
.clientCapabilities(clientCapabilities)
.clientInfo(clientInfo)
.initializeResult(initializeResult)
.build();import org.springframework.ai.mcp.McpToolFilter;
McpToolFilter filter = (connectionInfo, tool) -> {
// Access client info
String clientName = connectionInfo.clientInfo().name();
String clientVersion = connectionInfo.clientInfo().version();
// Access client capabilities
var capabilities = connectionInfo.clientCapabilities();
// Access server initialization result
var initResult = connectionInfo.initializeResult();
var serverCapabilities = initResult.capabilities();
var serverInfo = initResult.serverInfo();
// Use in filtering logic
return /* ... */;
};import org.springframework.ai.mcp.McpToolNamePrefixGenerator;
McpToolNamePrefixGenerator prefixGen = (connectionInfo, tool) -> {
// Build prefix from connection info
String serverName = connectionInfo.clientInfo().name();
String serverVersion = connectionInfo.clientInfo().version();
return String.format("%s_v%s_%s", serverName, serverVersion, tool.name());
};// Access client implementation details
McpSchema.Implementation clientInfo = connectionInfo.clientInfo();
String name = clientInfo.name(); // Client/server name
String version = clientInfo.version(); // Version string
String title = clientInfo.title(); // Optional human-readable title// Check what the client supports
McpSchema.ClientCapabilities capabilities = connectionInfo.clientCapabilities();
// Check if specific capabilities are available
var roots = capabilities.roots(); // Root file system access
var sampling = capabilities.sampling(); // LLM sampling support
var experimental = capabilities.experimental(); // Experimental features// Access server initialization data
McpSchema.InitializeResult initResult = connectionInfo.initializeResult();
// Get server capabilities
var serverCapabilities = initResult.capabilities();
if (serverCapabilities != null) {
var tools = serverCapabilities.tools(); // Tool support
var resources = serverCapabilities.resources(); // Resource support
var prompts = serverCapabilities.prompts(); // Prompt support
var logging = serverCapabilities.logging(); // Logging support
}
// Get server information
var serverInfo = initResult.serverInfo();
if (serverInfo != null) {
String serverName = serverInfo.name();
String serverVersion = serverInfo.version();
}
// Get protocol version
String protocolVersion = initResult.protocolVersion();
// Get server instructions (optional guidance)
String instructions = initResult.instructions();import org.springframework.ai.mcp.*;
import io.modelcontextprotocol.spec.McpSchema;
// Advanced filter using full connection info
McpToolFilter advancedFilter = (connectionInfo, tool) -> {
// Check client name
String clientName = connectionInfo.clientInfo().name();
if (clientName.contains("untrusted")) {
return false; // Reject all tools from untrusted clients
}
// Check server capabilities
var initResult = connectionInfo.initializeResult();
var serverCapabilities = initResult.capabilities();
if (serverCapabilities == null || serverCapabilities.tools() == null) {
return false; // Server doesn't support tools properly
}
// Check protocol version compatibility
String protocolVersion = initResult.protocolVersion();
if (!protocolVersion.startsWith("2024-")) {
return false; // Only support 2024 protocol versions
}
// Check tool description
if (tool.description() == null || tool.description().isEmpty()) {
return false; // Reject tools without descriptions
}
return true;
};
// Detailed prefix generator
McpToolNamePrefixGenerator detailedPrefixGen = (connectionInfo, tool) -> {
StringBuilder prefix = new StringBuilder();
// Add client name component
String clientName = connectionInfo.clientInfo().name()
.replaceAll("[^a-zA-Z0-9]", "_")
.toLowerCase();
prefix.append(clientName);
// Add version component if significant
String version = connectionInfo.clientInfo().version();
if (version != null && version.matches("\\d+\\..*")) {
String majorVersion = version.split("\\.")[0];
prefix.append("_v").append(majorVersion);
}
// Add environment hint from server info
var serverInfo = connectionInfo.initializeResult().serverInfo();
if (serverInfo != null) {
String serverName = serverInfo.name();
if (serverName.contains("production")) {
prefix.append("_prod");
} else if (serverName.contains("staging")) {
prefix.append("_stage");
}
}
// Add tool name
prefix.append("_").append(tool.name());
return prefix.toString();
};
// Use with provider
SyncMcpToolCallbackProvider provider = SyncMcpToolCallbackProvider.builder()
.mcpClients(clients)
.toolFilter(advancedFilter)
.toolNamePrefixGenerator(detailedPrefixGen)
.build();McpToolFilter debugFilter = (connectionInfo, tool) -> {
System.out.println("=== Connection Info ===");
// Client info
var clientInfo = connectionInfo.clientInfo();
System.out.println("Client Name: " + clientInfo.name());
System.out.println("Client Version: " + clientInfo.version());
System.out.println("Client Title: " + clientInfo.title());
// Server info
var initResult = connectionInfo.initializeResult();
System.out.println("Protocol Version: " + initResult.protocolVersion());
var serverInfo = initResult.serverInfo();
if (serverInfo != null) {
System.out.println("Server Name: " + serverInfo.name());
System.out.println("Server Version: " + serverInfo.version());
}
// Capabilities
var capabilities = initResult.capabilities();
if (capabilities != null) {
System.out.println("Supports Tools: " + (capabilities.tools() != null));
System.out.println("Supports Resources: " + (capabilities.resources() != null));
System.out.println("Supports Prompts: " + (capabilities.prompts() != null));
}
System.out.println("=== Tool ===");
System.out.println("Tool Name: " + tool.name());
System.out.println("Tool Description: " + tool.description());
System.out.println("===================");
return true;
};