Spring Boot auto-configuration platform for Embabel Agent Framework, enabling annotation-driven profile activation and bootstrapping of agent configurations with MCP client support
Spring Boot auto-configuration for the Embabel Agent Framework. Enables automatic setup of agent platforms, tool groups, and Model Context Protocol (MCP) clients with annotation-driven profile activation.
Package: com.embabel.agent:embabel-agent-platform-autoconfigure:0.3.3
Language: Java (Spring Boot)
<dependency>
<groupId>com.embabel.agent</groupId>
<artifactId>embabel-agent-platform-autoconfigure</artifactId>
<version>0.3.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Add Spring AI model provider (required) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency># application.properties
spring.ai.openai.api-key=your-api-key
spring.ai.openai.chat.options.model=gpt-4import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import com.embabel.agent.autoconfigure.platform.AgentPlatformAutoConfiguration;
@SpringBootApplication
@ImportAutoConfiguration(AgentPlatformAutoConfiguration.class)
public class AgentApplication {
public static void main(String[] args) {
SpringApplication.run(AgentApplication.class, args);
}
}embabel.agent.logging.personality=starwarsRequired: Spring Boot Web, Spring AI Model Provider (OpenAI/Anthropic/Ollama/etc.), Java 17+
Automatically bootstraps:
@AutoConfiguration
@ImportAutoConfiguration({QuiteMcpClientAutoConfiguration.class})
@Import({CommonPlatformPropertiesLoader.class, ScanConfiguration.class,
AgentPlatformConfiguration.class, ToolGroupsConfiguration.class})
public class AgentPlatformAutoConfiguration {
// Automatically discovered by Spring Boot
}What gets scanned: com.embabel.agent.{api,core,experimental,prompt,spi,test,tools,web}
Provides synchronous/asynchronous MCP clients with error resilience preventing startup failures.
@AutoConfiguration
@ConditionalOnClass(McpSchema.class)
@ConditionalOnProperty(prefix = "spring.ai.mcp.client", name = "enabled",
havingValue = "true", matchIfMissing = true)
public class QuiteMcpClientAutoConfiguration extends McpClientAutoConfiguration {
@Bean
@ConditionalOnProperty(prefix = "spring.ai.mcp.client", name = "type",
havingValue = "SYNC", matchIfMissing = true)
List<McpSyncClient> mcpSyncClients(...);
@Bean
@ConditionalOnProperty(prefix = "spring.ai.mcp.client", name = "type",
havingValue = "ASYNC")
List<McpAsyncClient> mcpAsyncClients(...);
}Key feature: Failed MCP client initialization is logged but doesn't prevent application startup.
// Logging theme
@ConfigurationProperties(prefix = "embabel.agent.logging")
record LoggingPersonalityProperties(String personality) {}
// MCP client (from Spring AI)
class McpClientCommonProperties {
boolean enabled; // Default: true
String type; // SYNC or ASYNC, default: SYNC
String name; // Client name
String version; // Client version
Duration requestTimeout; // Request timeout
boolean initialized; // Auto-initialize, default: true
}Let Spring Boot auto-discover the configuration:
@SpringBootApplication
public class MyAgentApp {
public static void main(String[] args) {
SpringApplication.run(MyAgentApp.class, args);
}
}application.properties:
spring.ai.openai.api-key=sk-...
embabel.agent.logging.personality=starwarsspring.ai.mcp.client.enabled=true
spring.ai.mcp.client.type=SYNC
spring.ai.mcp.client.name=my-agent
spring.ai.mcp.client.version=1.0.0
spring.ai.mcp.client.request-timeout=10s
spring.ai.mcp.client.initialized=trueimport io.modelcontextprotocol.client.McpSyncClient;
import org.springframework.beans.factory.annotation.Autowired;
@Service
public class MyService {
@Autowired
private List<McpSyncClient> mcpClients;
public void useClient() {
if (!mcpClients.isEmpty()) {
McpSyncClient client = mcpClients.get(0);
// Use client...
}
}
}@SpringBootApplication(exclude = {AgentPlatformAutoConfiguration.class})
public class MyApp { }Or via properties:
spring.autoconfigure.exclude=\
com.embabel.agent.autoconfigure.platform.AgentPlatformAutoConfigurationspring.ai.mcp.client.enabled=falsespring.ai.mcp.client.type=ASYNCimport io.modelcontextprotocol.client.McpAsyncClient;
import reactor.core.publisher.Mono;
@Service
public class MyReactiveService {
@Autowired
private List<McpAsyncClient> mcpAsyncClients;
public Mono<Void> useClientAsync() {
if (!mcpAsyncClients.isEmpty()) {
McpAsyncClient client = mcpAsyncClients.get(0);
// Use reactive client...
}
return Mono.empty();
}
}# Choose one theme
embabel.agent.logging.personality=starwars
embabel.agent.logging.personality=severance
embabel.agent.logging.personality=colossus
embabel.agent.logging.personality=hitchhiker
embabel.agent.logging.personality=montypythonAccess in code:
@Value("${embabel.agent.logging.personality:}")
private String theme;# application.yml
spring:
profiles:
active: dev
---
spring:
config:
activate:
on-profile: dev
embabel:
agent:
logging:
personality: starwars
---
spring:
config:
activate:
on-profile: prod
embabel:
agent:
logging:
personality: ""Type: String
Default: "" (no theme)
Values: starwars, severance, colossus, hitchhiker, montypython
Purpose: Sets logging theme personality
Type: boolean
Default: true
Purpose: Enable/disable MCP client auto-configuration
Type: String
Default: SYNC
Values: SYNC, ASYNC
Purpose: Choose sync or async MCP clients
Bean: List<McpSyncClient> or List<McpAsyncClient>
Type: String Purpose: Client name for MCP protocol identification
Type: String Purpose: Client version for MCP protocol identification
Type: Duration
Format: 5s, 30s, 1m
Purpose: Timeout for MCP requests
Type: boolean
Default: true
Purpose: Auto-initialize clients on creation
Note: When false, must call client.initialize() manually
Core classes and their signatures:
// Main auto-configuration
@AutoConfiguration
public class AgentPlatformAutoConfiguration {
// Imports: QuiteMcpClientAutoConfiguration, ScanConfiguration,
// AgentPlatformConfiguration, ToolGroupsConfiguration
}
// Component scanning
@Configuration
@ComponentScan(basePackages = {"com.embabel.agent.*"})
@ConfigurationPropertiesScan(basePackages = {"com.embabel.agent.*"})
public class ScanConfiguration {
}
// MCP client auto-configuration
@AutoConfiguration
@ConditionalOnClass(McpSchema.class)
@ConditionalOnProperty(prefix = "spring.ai.mcp.client", name = "enabled",
havingValue = "true", matchIfMissing = true)
public class QuiteMcpClientAutoConfiguration extends McpClientAutoConfiguration {
List<McpSyncClient> mcpSyncClients(
McpSyncClientConfigurer configurer,
McpClientCommonProperties properties,
ObjectProvider<List<NamedClientMcpTransport>> transports,
ObjectProvider<ClientMcpSyncHandlersRegistry> handlers
);
List<McpAsyncClient> mcpAsyncClients(
McpAsyncClientConfigurer configurer,
McpClientCommonProperties properties,
ObjectProvider<List<NamedClientMcpTransport>> transports,
ObjectProvider<ClientMcpAsyncHandlersRegistry> handlers
);
}
// Auto-configuration filter
public class AgentPlatformAutoConfigurationFilter
implements AutoConfigurationImportFilter {
boolean[] match(String[] autoConfigurationClasses,
AutoConfigurationMetadata metadata);
// Excludes: org.springframework.ai.mcp.client.common.autoconfigure.McpClientAutoConfiguration
}
// Environment post-processor
public class EnvironmentPostProcessor
implements org.springframework.boot.env.EnvironmentPostProcessor,
org.springframework.core.Ordered {
String LOGGING_THEME_PROPERTY = "embabel.agent.logging.personality";
void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application);
int getOrder(); // Returns Ordered.HIGHEST_PRECEDENCE
}
// Configuration properties
@ConfigurationProperties(prefix = "embabel.agent.logging")
record LoggingPersonalityProperties(String personality) {}
class McpClientCommonProperties {
boolean enabled;
String type;
String name;
String version;
Duration requestTimeout;
boolean initialized;
}
// MCP client types
interface McpSyncClient {
void initialize();
}
interface McpAsyncClient {
Mono<Void> initialize();
}Old approach:
@SpringBootApplication
@EnableAgents(
loggingTheme = LoggingThemes.STAR_WARS,
mcpServers = {"filesystem"}
)
public class OldApp { }New approach:
@SpringBootApplication
@ImportAutoConfiguration(AgentPlatformAutoConfiguration.class)
public class NewApp { }embabel.agent.logging.personality=starwarsUse Spring AI MCP client properties instead.
META-INF/spring/.../AutoConfiguration.imports - AgentPlatformAutoConfigurationMETA-INF/spring.factories - EnvironmentPostProcessor, AutoConfigurationImportFilterInit Order: Filter → Transports → MCP Clients → Platform → Scanning
Packages: com.embabel.agent.{api,core,experimental,prompt,spi,test,tools,web}
Behavior: Failed MCP client initialization is logged but doesn't prevent application startup.
Logging:
ERROR c.e.a.a.p.QuiteMcpClientAutoConfiguration -
Failed to initialize MCP Sync Client: my-client - Application startup will continueResult:
List<McpSyncClient> beanTo troubleshoot:
Install with Tessl CLI
npx tessl i tessl/maven-com-embabel-agent--embabel-agent-platform-autoconfigure@0.3.0