Spring Boot starter providing auto-configuration for Model Context Protocol (MCP) client with Spring WebFlux, enabling reactive AI applications to connect to MCP servers via SSE and Streamable HTTP transports
Complete reference for all configuration properties available in the Spring AI MCP Client WebFlux Starter.
Configuration properties shared across all transport types.
Prefix: spring.ai.mcp.client
package org.springframework.ai.mcp.client.common.autoconfigure.properties;
/**
* Configuration properties for common MCP client settings.
* Bound from spring.ai.mcp.client.* properties.
* Immutable after Spring Boot property binding completes.
* Thread-safe for reads after initialization.
*/
@org.springframework.boot.context.properties.ConfigurationProperties("spring.ai.mcp.client")
public class McpClientCommonProperties {
/** Enable/disable the MCP client (default: true) */
private boolean enabled = true;
/** The name of the MCP client instance (default: "spring-ai-mcp-client") */
private String name = "spring-ai-mcp-client";
/** The version of the MCP client instance (default: "1.0.0") */
private String version = "1.0.0";
/** Flag to indicate if the MCP client has to be initialized (default: true) */
private boolean initialized = true;
/** The timeout duration for MCP client requests (default: 20 seconds) */
private java.time.Duration requestTimeout = java.time.Duration.ofSeconds(20);
/** The type of client to use (default: ClientType.SYNC) */
private ClientType type = ClientType.SYNC;
/** Enable/disable root change notifications (default: true) */
private boolean rootChangeNotification = true;
/** Tool callback configuration */
private Toolcallback toolcallback = new Toolcallback();
// Getters and setters...
public boolean isEnabled() { return enabled; }
public void setEnabled(boolean enabled) { this.enabled = enabled; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getVersion() { return version; }
public void setVersion(String version) { this.version = version; }
public boolean isInitialized() { return initialized; }
public void setInitialized(boolean initialized) { this.initialized = initialized; }
public java.time.Duration getRequestTimeout() { return requestTimeout; }
public void setRequestTimeout(java.time.Duration requestTimeout) { this.requestTimeout = requestTimeout; }
public ClientType getType() { return type; }
public void setType(ClientType type) { this.type = type; }
public boolean isRootChangeNotification() { return rootChangeNotification; }
public void setRootChangeNotification(boolean rootChangeNotification) { this.rootChangeNotification = rootChangeNotification; }
public Toolcallback getToolcallback() { return toolcallback; }
public void setToolcallback(Toolcallback toolcallback) { this.toolcallback = toolcallback; }
}package org.springframework.ai.mcp.client.common.autoconfigure.properties;
/**
* Client types supported by the MCP client.
* Determines which beans are created (sync or async).
* Enum is thread-safe and immutable.
*/
public enum ClientType {
/**
* Synchronous (McpSyncClient) client.
* Uses blocking I/O operations.
* Creates McpSyncClient beans and related sync beans.
*/
SYNC,
/**
* Asynchronous (McpAsyncClient) client.
* Uses reactive streams (Project Reactor) for non-blocking operations.
* Creates McpAsyncClient beans and related async beans.
*/
ASYNC
}package org.springframework.ai.mcp.client.common.autoconfigure.properties;
/**
* Callback configuration for tools.
* Nested configuration class within McpClientCommonProperties.
* Controls whether MCP tools are automatically converted to Spring AI ToolCallbacks.
*/
public static class Toolcallback {
/**
* Enable/disable tool callbacks (default: true).
* When true, creates ToolCallbackProvider beans for Spring AI integration.
* When false, MCP clients are still created but not integrated with Spring AI tools.
*/
private boolean enabled = true;
public boolean isEnabled() { return enabled; }
public void setEnabled(boolean enabled) { this.enabled = enabled; }
}spring.ai.mcp.client:
enabled: true # Enable MCP client
name: my-ai-application-client # Client name
version: 2.0.0 # Client version
initialized: true # Initialize on startup
request-timeout: 30s # 30 second timeout
type: SYNC # Use synchronous client
root-change-notification: true # Enable root change notifications
toolcallback:
enabled: true # Enable tool callbacksProperties format:
spring.ai.mcp.client.enabled=true
spring.ai.mcp.client.name=my-ai-application-client
spring.ai.mcp.client.version=2.0.0
spring.ai.mcp.client.initialized=true
spring.ai.mcp.client.request-timeout=30s
spring.ai.mcp.client.type=SYNC
spring.ai.mcp.client.root-change-notification=true
spring.ai.mcp.client.toolcallback.enabled=trueenabled (boolean, default: true)name (String, default: "spring-ai-mcp-client"){configured-name} - {connection-name} for each connectionversion (String, default: "1.0.0")initialized (boolean, default: true)client.initialize() manuallyrequest-timeout (Duration, default: 20s)20s, 5m, PT30S)TimeoutExceptiontype (ClientType, default: SYNC)SYNC or ASYNCroot-change-notification (boolean, default: true)toolcallback.enabled (boolean, default: true)Configuration properties for Server-Sent Events (SSE) based MCP client connections.
Prefix: spring.ai.mcp.client.sse
package org.springframework.ai.mcp.client.common.autoconfigure.properties;
/**
* Configuration properties for SSE client connections.
* Bound from spring.ai.mcp.client.sse.* properties.
* Thread-safe for reads after initialization.
*/
@org.springframework.boot.context.properties.ConfigurationProperties("spring.ai.mcp.client.sse")
public class McpSseClientProperties {
/**
* Map of named SSE connection configurations.
* Key: connection name (used to identify the transport)
* Value: SSE parameters for that connection
* Mutable during property binding, then effectively immutable.
*/
private final java.util.Map<String, SseParameters> connections = new java.util.HashMap<>();
public java.util.Map<String, SseParameters> getConnections() {
return connections;
}
}package org.springframework.ai.mcp.client.common.autoconfigure.properties;
/**
* Parameters for configuring an SSE connection to an MCP server.
* Immutable record type - thread-safe.
* Bound from spring.ai.mcp.client.sse.connections.{name}.* properties.
*
* @param url The base URL for SSE communication with the MCP server (required, must be valid HTTP/HTTPS URL)
* @param sseEndpoint The SSE endpoint path (optional, defaults to "/sse" if null)
*/
public record SseParameters(String url, String sseEndpoint) {}Simple configuration with default SSE endpoint (/sse):
spring.ai.mcp.client.sse:
connections:
server1:
url: http://localhost:8080
server2:
url: http://api.example.comCustom SSE endpoints:
spring.ai.mcp.client.sse:
connections:
mcp-hub:
url: http://localhost:3000
sse-endpoint: /mcp-hub/sse/cf9ec4527e3c4a2cbb149a85ea45ab01
custom-server:
url: http://api.example.com
sse-endpoint: /v1/mcp/events?token=abc123Properties format:
# Server 1 with default endpoint
spring.ai.mcp.client.sse.connections.server1.url=http://localhost:8080
# Server 2 with custom endpoint
spring.ai.mcp.client.sse.connections.mcp-hub.url=http://localhost:3000
spring.ai.mcp.client.sse.connections.mcp-hub.sse-endpoint=/mcp-hub/sse/cf9ec4527e3c4a2cbb149a85ea45ab01When you have a full URL like http://localhost:3000/mcp-hub/sse/token123, split it as:
url: http://localhost:3000 (protocol + host + port)sse-endpoint: /mcp-hub/sse/token123 (path including any query parameters)More examples:
| Full URL | url | sse-endpoint |
|---|---|---|
http://localhost:8080/sse | http://localhost:8080 | /sse (default, can omit) |
http://localhost:3000/api/v1/sse | http://localhost:3000 | /api/v1/sse |
http://api.example.com/mcp/events?key=xyz | http://api.example.com | /mcp/events?key=xyz |
Configuration properties for Streamable HTTP client connections to MCP servers.
Prefix: spring.ai.mcp.client.streamable-http
package org.springframework.ai.mcp.client.common.autoconfigure.properties;
/**
* Configuration properties for Streamable HTTP client connections.
* Bound from spring.ai.mcp.client.streamable-http.* properties.
* Thread-safe for reads after initialization.
*/
@org.springframework.boot.context.properties.ConfigurationProperties("spring.ai.mcp.client.streamable-http")
public class McpStreamableHttpClientProperties {
/**
* Map of named Streamable HTTP connection configurations.
* Key: connection name (used to identify the transport)
* Value: Connection parameters for that connection
* Mutable during property binding, then effectively immutable.
*/
private final java.util.Map<String, ConnectionParameters> connections = new java.util.HashMap<>();
public java.util.Map<String, ConnectionParameters> getConnections() {
return connections;
}
}package org.springframework.ai.mcp.client.common.autoconfigure.properties;
/**
* Parameters for configuring a Streamable HTTP connection to an MCP server.
* Immutable record type - thread-safe.
* Bound from spring.ai.mcp.client.streamable-http.connections.{name}.* properties.
*
* @param url The base URL for Streamable HTTP communication with the MCP server (required, must be valid HTTP/HTTPS URL)
* @param endpoint The endpoint path (optional, defaults to "/mcp" if null)
*/
public record ConnectionParameters(String url, String endpoint) {}Simple configuration with default endpoint (/mcp):
spring.ai.mcp.client.streamable-http:
connections:
server1:
url: http://localhost:8080
server2:
url: http://api.example.comCustom endpoints:
spring.ai.mcp.client.streamable-http:
connections:
primary:
url: http://localhost:9000
endpoint: /custom/mcp/endpoint
secondary:
url: http://api.example.com
endpoint: /v2/mcpProperties format:
# Server 1 with default endpoint
spring.ai.mcp.client.streamable-http.connections.server1.url=http://localhost:8080
# Server 2 with custom endpoint
spring.ai.mcp.client.streamable-http.connections.primary.url=http://localhost:9000
spring.ai.mcp.client.streamable-http.connections.primary.endpoint=/custom/mcp/endpointConfiguration properties for standard input/output (stdio) based MCP client connections.
Prefix: spring.ai.mcp.client.stdio
package org.springframework.ai.mcp.client.common.autoconfigure.properties;
/**
* Configuration properties for stdio client connections.
* Bound from spring.ai.mcp.client.stdio.* properties.
* Thread-safe for reads after initialization.
* Part of common MCP client autoconfiguration, not WebFlux-specific.
*/
@org.springframework.boot.context.properties.ConfigurationProperties("spring.ai.mcp.client.stdio")
public class McpStdioClientProperties {
/**
* External JSON file containing server configurations.
* Can be used instead of or in addition to inline connections.
* Spring Resource format (classpath:, file:, http:, etc.).
* Optional - if not provided, only inline connections are used.
*/
private org.springframework.core.io.Resource serversConfiguration;
/**
* Map of named stdio connection configurations.
* Key: connection name (used to identify the transport)
* Value: Stdio parameters for that connection
* Mutable during property binding, then effectively immutable.
* Can be combined with serversConfiguration file.
*/
private final java.util.Map<String, Parameters> connections = new java.util.HashMap<>();
public org.springframework.core.io.Resource getServersConfiguration() { return serversConfiguration; }
public void setServersConfiguration(org.springframework.core.io.Resource serversConfiguration) {
this.serversConfiguration = serversConfiguration;
}
public java.util.Map<String, Parameters> getConnections() { return connections; }
/**
* Converts all configured connections to ServerParameters map for the MCP SDK.
* Merges inline connections and serversConfiguration file.
* Thread-safe - called during bean creation only.
*
* @return Map of connection names to ServerParameters (never null, may be empty)
* @throws IOException if serversConfiguration file cannot be read
* @throws com.fasterxml.jackson.core.JsonProcessingException if JSON parsing fails
*/
public java.util.Map<String, io.modelcontextprotocol.spec.ServerParameters> toServerParameters();
}package org.springframework.ai.mcp.client.common.autoconfigure.properties;
/**
* Parameters for configuring a stdio connection to an MCP server.
* Immutable record type - thread-safe.
* Bound from spring.ai.mcp.client.stdio.connections.{name}.* properties.
*
* @param command The command to execute (e.g., "node", "python", "/usr/bin/mcp-server")
* @param args Command arguments as a list (optional, can be null or empty)
* @param env Environment variables for the process (optional, can be null or empty)
*/
public record Parameters(
String command,
java.util.List<String> args,
java.util.Map<String, String> env
) {
/**
* Converts this Parameters object to ServerParameters for the MCP SDK.
* Creates immutable ServerParameters instance.
*
* @return ServerParameters instance (never null)
*/
public io.modelcontextprotocol.spec.ServerParameters toServerParameters();
}Basic stdio configuration:
spring.ai.mcp.client.stdio:
connections:
local-node-server:
command: node
args:
- /path/to/mcp-server.js
python-server:
command: python
args:
- /path/to/mcp_server.py
- --verbose
env:
PYTHONPATH: /custom/path
DEBUG: "true"Using external JSON configuration file:
spring.ai.mcp.client.stdio:
servers-configuration: classpath:mcp-servers.jsonThe JSON file format:
{
"mcpServers": {
"server1": {
"command": "node",
"args": ["/path/to/server.js"]
},
"server2": {
"command": "python",
"args": ["/path/to/server.py"],
"env": {
"KEY": "value"
}
}
}
}Properties format:
spring.ai.mcp.client.stdio.connections.local-server.command=node
spring.ai.mcp.client.stdio.connections.local-server.args[0]=/path/to/mcp-server.js
spring.ai.mcp.client.stdio.connections.python-server.command=python
spring.ai.mcp.client.stdio.connections.python-server.args[0]=/path/to/server.py
spring.ai.mcp.client.stdio.connections.python-server.env.DEBUG=truepython vs python3, node vs node.exe)Configuration properties for the MCP client annotation scanner feature.
Prefix: spring.ai.mcp.client.annotation-scanner
package org.springframework.ai.mcp.client.common.autoconfigure.annotations;
/**
* Configuration properties for MCP client annotation scanner.
* Bound from spring.ai.mcp.client.annotation-scanner.* properties.
* Thread-safe for reads after initialization.
* Controls whether annotated handler methods are scanned and registered.
*/
@org.springframework.boot.context.properties.ConfigurationProperties("spring.ai.mcp.client.annotation-scanner")
public class McpClientAnnotationScannerProperties {
/**
* Enable/disable annotation-based MCP handler scanning (default: true).
* When enabled, scans for @McpLogging, @McpSampling, @McpProgress, etc.
* Scanning happens at startup during bean initialization.
* When disabled, no annotation scanning occurs and handler registry is not created.
*/
private boolean enabled = true;
public boolean isEnabled() { return enabled; }
public void setEnabled(boolean enabled) { this.enabled = enabled; }
}spring.ai.mcp.client:
annotation-scanner:
enabled: true # default, can be disabledTo disable annotation scanning:
spring.ai.mcp.client:
annotation-scanner:
enabled: false@McpLogging, @McpSampling, @McpElicitation, @McpProgress, @McpToolListChanged, @McpResourceListChanged, @McpPromptListChangedExample showing all property types together:
spring.ai.mcp.client:
# Common properties
enabled: true
name: my-mcp-client
version: 1.0.0
initialized: true
request-timeout: 25s
type: SYNC
root-change-notification: true
toolcallback:
enabled: true
annotation-scanner:
enabled: true
# Stdio connections (local processes)
stdio:
connections:
local-node-server:
command: node
args:
- ./mcp-servers/filesystem.js
local-python-server:
command: python
args:
- ./mcp-servers/database.py
env:
DATABASE_URL: jdbc:postgresql://localhost:5432/mydb
# SSE connections (remote servers)
sse:
connections:
weather-service:
url: http://localhost:8080
sse-endpoint: /weather/sse
data-service:
url: http://localhost:9000
# Streamable HTTP connections (remote servers)
streamable-http:
connections:
analysis-service:
url: http://localhost:7000
endpoint: /analyze/mcp
report-service:
url: http://localhost:6000All properties are automatically bound by Spring Boot's configuration property mechanism. You can use:
SPRING_AI_MCP_CLIENT_ENABLED=true)--spring.ai.mcp.client.enabled=true)-Dspring.ai.mcp.client.enabled=true)application-{profile}.yml for environment-specific configurationapplication-{profile}.yml)application.yml)@ConfigurationProperties classesThe starter performs these validations:
url is requiredurl is requiredcommand is required20s, 5m, PT30S)SYNC or ASYNCBindExceptionBindExceptionBindExceptionTo completely disable MCP client auto-configuration:
spring.ai.mcp.client:
enabled: falseOr exclude the auto-configuration classes:
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.SpringApplication;
@SpringBootApplication(exclude = {
org.springframework.ai.mcp.client.webflux.autoconfigure.SseWebFluxTransportAutoConfiguration.class,
org.springframework.ai.mcp.client.webflux.autoconfigure.StreamableHttpWebFluxTransportAutoConfiguration.class,
org.springframework.ai.mcp.client.common.autoconfigure.StdioTransportAutoConfiguration.class,
org.springframework.ai.mcp.client.common.autoconfigure.McpClientAutoConfiguration.class,
org.springframework.ai.mcp.client.common.autoconfigure.McpToolCallbackAutoConfiguration.class,
org.springframework.ai.mcp.client.common.autoconfigure.annotations.McpClientAnnotationScannerAutoConfiguration.class
})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}Disable specific features while keeping others:
spring.ai.mcp.client:
enabled: true
toolcallback:
enabled: false # Disable Spring AI integration
annotation-scanner:
enabled: false # Disable annotation scanningUse Spring profiles for environment-specific settings:
# application-dev.yml
spring.ai.mcp.client:
request-timeout: 60s # Longer timeout for debugging
sse:
connections:
test-server:
url: http://localhost:8080
# application-prod.yml
spring.ai.mcp.client:
request-timeout: 10s # Shorter timeout for production
sse:
connections:
prod-server:
url: https://api.production.com
sse-endpoint: /mcp/v1/sseLoad configuration from external sources:
spring.config.import: optional:file:./config/mcp-config.ymlOr use Spring Cloud Config:
spring.cloud.config:
uri: http://config-server:8888
name: mcp-clientenabled: false to explicitly disable features rather than removing configurationtessl i tessl/maven-org-springframework-ai--spring-ai-starter-mcp-client-webflux@1.1.0