# How Embabel Integrates with Model Context Protocol (MCP) in Spring Boot

> Learn how Embabel integrates with Model Context Protocol MCP in Spring Boot using auto-configuration. Discover resilient MCP clients and servers with @EnableAgents.

- Repository: [Embabel/embabel-agent](https://github.com/embabel/embabel-agent)
- Tags: how-to-guide
- Published: 2026-08-08

---

**Embabel integrates with the Model Context Protocol through Spring Boot auto-configuration classes that create resilient MCP clients and servers when you add the `@EnableAgents` annotation, automatically handling transport discovery, bean registration, and graceful failure recovery.**

The embabel/embabel-agent framework eliminates boilerplate when adopting the Model Context Protocol by providing annotation-driven configuration and fault-tolerant client management. Instead of manually configuring transports and connection handling, you declare which MCP services you need and receive fully configured `McpSyncClient` and `McpAsyncClient` beans ready for injection.

## Enabling MCP with the @EnableAgents Annotation

Integration starts with the `@EnableAgents` annotation, which activates the necessary Spring profiles and triggers auto-configuration based on the `mcpServers` array you provide.

When you add `@EnableAgents(mcpServers = {"filesystem", "github"})` to your Spring Boot application class, the framework activates profiles for each specified transport and prepares the context for client bean creation. This annotation is defined in [`embabel-agent-autoconfigure/embabel-agent-platform-autoconfigure/src/main/java/com/embabel/agent/config/annotation/EnableAgents.java`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-autoconfigure/embabel-agent-platform-autoconfigure/src/main/java/com/embabel/agent/config/annotation/EnableAgents.java).

```java
import com.embabel.agent.config.annotation.EnableAgents;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableAgents(
    loggingTheme = "starwars",
    mcpServers = {"filesystem", "github"}
)
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

```

The annotation processing reads the `mcpServers` array and activates corresponding Spring profiles, signaling the auto-configuration classes to create the appropriate client beans.

## Resilient MCP Client Auto-Configuration

Embabel replaces Spring-AI's default MCP client configuration with a resilient implementation that gracefully handles initialization failures.

The `AgentPlatformAutoConfigurationFilter` class in [`embabel-agent-autoconfigure/embabel-agent-platform-autoconfigure/src/main/java/com/embabel/agent/autoconfigure/platform/AgentPlatformAutoConfigurationFilter.java`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-autoconfigure/embabel-agent-platform-autoconfigure/src/main/java/com/embabel/agent/autoconfigure/platform/AgentPlatformAutoConfigurationFilter.java) explicitly excludes Spring-AI's default `McpClientAutoConfiguration`. This ensures Embabel's `QuiteMcpClientAutoConfiguration` takes precedence.

Located at [`embabel-agent-autoconfigure/embabel-agent-platform-autoconfigure/src/main/java/com/embabel/agent/autoconfigure/platform/QuiteMcpClientAutoConfiguration.java`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-autoconfigure/embabel-agent-platform-autoconfigure/src/main/java/com/embabel/agent/autoconfigure/platform/QuiteMcpClientAutoConfiguration.java), this configuration class:

1. Discovers available transports through `NamedClientMcpTransport` beans provided by Spring-AI
2. Creates **synchronous** (`McpSyncClient`) and **asynchronous** (`McpAsyncClient`) clients for each transport
3. Catches initialization failures, logs them, and allows the application to start while omitting only the failing client

```java
import io.modelcontextprotocol.client.McpSyncClient;
import org.springframework.stereotype.Service;

@Service
public class FileProcessingService {
    private final McpSyncClient mcpSyncClient;

    public FileProcessingService(McpSyncClient mcpSyncClient) {
        this.mcpSyncClient = mcpSyncClient;
    }

    public String listFiles(String directory) {
        return mcpSyncClient.execute("listFiles", directory);
    }
}

```

The asynchronous variant works similarly with `McpAsyncClient` for non-blocking operations:

```java
import io.modelcontextprotocol.client.McpAsyncClient;
import reactor.core.publisher.Mono;
import org.springframework.stereotype.Service;

@Service
public class GithubService {
    private final McpAsyncClient mcpAsyncClient;

    public GithubService(McpAsyncClient mcpAsyncClient) {
        this.mcpAsyncClient = mcpAsyncClient;
    }

    public Mono<String> fetchRepository(String repo) {
        return mcpAsyncClient.executeAsync("getRepo", repo);
    }
}

```

## Hosting MCP Servers

Embabel also supports exposing your application as an MCP server through `AgentMcpServerAutoConfiguration`. Located in [`embabel-agent-autoconfigure/embabel-agent-mcpserver-autoconfigure/src/main/java/com/embabel/agent/autoconfigure/mcpserver/AgentMcpServerAutoConfiguration.java`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-autoconfigure/embabel-agent-mcpserver-autoconfigure/src/main/java/com/embabel/agent/autoconfigure/mcpserver/AgentMcpServerAutoConfiguration.java), this configuration scans the `com.embabel.agent.mcpserver` package and registers synchronous and asynchronous MCP server implementations as Spring beans.

When the MCP server module is present on the classpath, the auto-configuration imports server implementations and exposes them as `McpServer` beans:

```java
import com.embabel.agent.mcpserver.McpServer;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class ServerStarter implements CommandLineRunner {
    private final McpServer mcpServer;

    public ServerStarter(McpServer mcpServer) {
        this.mcpServer = mcpServer;
    }

    @Override
    public void run(String... args) {
        mcpServer.start();
    }
}

```

## Customizing MCP Client Behavior

Developers can customize client configurations through the `McpClientCustomizer` interface. Any beans implementing this interface are automatically detected and applied by `QuiteMcpClientAutoConfiguration` during client creation, allowing you to set timeouts, client metadata, or add handlers for sampling and logging.

```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ai.mcp.customizer.McpClientCustomizer;

@Configuration
public class McpClientCustomization {
    @Bean
    public McpClientCustomizer myCustomizer() {
        return (name, builder) -> builder.requestTimeout(
            java.time.Duration.ofSeconds(30)
        );
    }
}

```

This customization applies to all MCP clients created by the auto-configuration, ensuring consistent behavior across different transports.

## Summary

- **Annotation-driven setup**: Add `@EnableAgents(mcpServers = {...})` to activate MCP integration and trigger auto-configuration.
- **Resilient defaults**: `QuiteMcpClientAutoConfiguration` creates both synchronous and asynchronous clients while gracefully handling initialization failures.
- **Spring-AI replacement**: `AgentPlatformAutoConfigurationFilter` excludes default Spring-AI MCP configuration to ensure Embabel's resilient implementation takes precedence.
- **Server capability**: `AgentMcpServerAutoConfiguration` enables hosting MCP servers when the optional server module is included.
- **Extensible customization**: Implement `McpClientCustomizer` beans to modify client settings such as timeouts and request handling.

## Frequently Asked Questions

### How do I enable MCP clients in an Embabel application?

Add the `@EnableAgents` annotation to your Spring Boot main class and specify the desired MCP servers in the `mcpServers` array. For example, `@EnableAgents(mcpServers = {"filesystem", "github"})` activates the file system and GitHub MCP clients. The auto-configuration in `QuiteMcpClientAutoConfiguration` then creates the appropriate `McpSyncClient` and `McpAsyncClient` beans for each transport.

### What happens if an MCP client fails to initialize?

Embabel's `QuiteMcpClientAutoConfiguration` catches initialization exceptions during client creation, logs the error, and allows the application to continue starting up. Only the specific failing client is omitted from the context, while other MCP clients and the rest of your application start normally. This resilience ensures that temporary network issues or misconfigured transports do not prevent application deployment.

### Can I customize MCP client timeouts and configurations?

Yes. Implement the `McpClientCustomizer` interface as a Spring bean to modify client builders before they create clients. The customizer receives the client name and builder, allowing you to set request timeouts, client information, and protocol handlers. `QuiteMcpClientAutoConfiguration` automatically applies all customizer beans to every MCP client it creates.

### Does Embabel support both MCP clients and servers?

Yes. The framework provides auto-configuration for both consuming MCP services and hosting them. Client functionality comes through `QuiteMcpClientAutoConfiguration` in the platform module, while server functionality is available via `AgentMcpServerAutoConfiguration` when you include the `embabel-agent-mcpserver-autoconfigure` module. Both configurations activate automatically based on classpath contents and the `@EnableAgents` annotation.