CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-embabel-agent--embabel-agent-platform-autoconfigure

Spring Boot auto-configuration platform for Embabel Agent Framework, enabling annotation-driven profile activation and bootstrapping of agent configurations with MCP client support

Overview
Eval results
Files

mcp-client-setup.mddocs/guides/

MCP Client Setup Guide

Configure Model Context Protocol (MCP) clients for agent tool integration.

Basic MCP Client Setup

Enable MCP Clients

spring.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=true

Inject and Use Clients

import io.modelcontextprotocol.client.McpSyncClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class AgentService {

    @Autowired
    private List<McpSyncClient> mcpClients;

    public void executeTask() {
        if (mcpClients.isEmpty()) {
            // No clients available
            return;
        }

        McpSyncClient client = mcpClients.get(0);
        // Use MCP client for tool execution
        // See Spring AI MCP documentation for client API
    }
}

Synchronous vs Asynchronous Clients

Synchronous Clients (Default)

spring.ai.mcp.client.type=SYNC
@Autowired
private List<McpSyncClient> mcpSyncClients;

public void syncOperation() {
    McpSyncClient client = mcpSyncClients.get(0);
    client.initialize(); // Blocking
    // Blocking operations
}

Use when: Traditional blocking code, simpler error handling.

Asynchronous Clients

spring.ai.mcp.client.type=ASYNC
import io.modelcontextprotocol.client.McpAsyncClient;
import reactor.core.publisher.Mono;

@Autowired
private List<McpAsyncClient> mcpAsyncClients;

public Mono<Void> asyncOperation() {
    if (mcpAsyncClients.isEmpty()) {
        return Mono.empty();
    }

    McpAsyncClient client = mcpAsyncClients.get(0);
    return client.initialize()
        .then(/* Reactive operations */);
}

Use when: Reactive/WebFlux applications, non-blocking I/O.

Auto-Initialization

Enabled (Default)

spring.ai.mcp.client.initialized=true

Behavior:

  • Clients initialized during application startup
  • Failed initialization logged but doesn't block startup
  • Clients ready to use immediately after injection

Logging on failure:

ERROR c.e.a.a.p.QuiteMcpClientAutoConfiguration -
Failed to initialize MCP Sync Client: my-client - filesystem
- Application startup will continue

Disabled (Manual Initialization)

spring.ai.mcp.client.initialized=false
@Autowired
private List<McpSyncClient> clients;

@PostConstruct
public void initClients() {
    for (McpSyncClient client : clients) {
        try {
            client.initialize();
            logger.info("Client initialized successfully");
        } catch (Exception e) {
            logger.error("Failed to initialize client", e);
        }
    }
}

Use when:

  • Conditional client activation
  • Custom initialization logic
  • Delayed initialization

Client Customization

Custom Client Configurer

import org.springframework.ai.mcp.client.common.autoconfigure.configurer.McpSyncClientConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;

@Configuration
public class McpClientConfig {

    @Bean
    public McpSyncClientConfigurer customConfigurer() {
        return (transportName, spec) -> {
            // Customize per transport
            if ("filesystem".equals(transportName)) {
                return spec.requestTimeout(Duration.ofSeconds(30));
            }
            return spec;
        };
    }
}

Async Client Customization

import org.springframework.ai.mcp.client.common.autoconfigure.configurer.McpAsyncClientConfigurer;

@Bean
public McpAsyncClientConfigurer asyncConfigurer() {
    return (transportName, spec) -> spec
        .requestTimeout(Duration.ofSeconds(20))
        // Additional customizations
        ;
}

Transport Configuration

MCP clients require transports. See Spring AI documentation for transport-specific setup.

Common Transports

  • Stdio: Local process communication
  • SSE HTTP: Server-Sent Events over HTTP
  • SSE WebFlux: Reactive SSE
  • Streamable HTTP: Streaming HTTP

Example: Stdio Transport Configuration

See Spring AI MCP transport documentation for detailed transport configuration.

Error Handling

Resilient Initialization

Built-in behavior: Failed client initialization doesn't prevent application startup.

// Automatic error handling (pseudocode)
try {
    client.initialize();
    clients.add(client); // Success
} catch (Throwable t) {
    logger.error("Failed to initialize MCP Client: {} - Application continues",
                 clientName, t);
    // Client excluded, app continues
}

Check Client Availability

@Autowired
private List<McpSyncClient> mcpClients;

public void safeUse() {
    if (mcpClients.isEmpty()) {
        logger.warn("No MCP clients available");
        // Fallback behavior
        return;
    }

    // Use clients
}

Retry Failed Initialization

@Autowired
private List<McpSyncClient> clients;

public void retryInit() {
    for (McpSyncClient client : clients) {
        try {
            if (!client.isInitialized()) {
                client.initialize();
            }
        } catch (Exception e) {
            logger.error("Retry failed", e);
        }
    }
}

Configuration Examples

Development Configuration

spring:
  ai:
    mcp:
      client:
        enabled: true
        type: SYNC
        name: dev-agent
        version: 0.1.0
        request-timeout: 30s
        initialized: false  # Manual init for debugging

Production Configuration

spring:
  ai:
    mcp:
      client:
        enabled: true
        type: ASYNC
        name: prod-agent
        version: 1.0.0
        request-timeout: 5s
        initialized: true

Test Configuration

# Disable MCP clients in tests
spring.ai.mcp.client.enabled=false

Disabling MCP Clients

Complete Disable

spring.ai.mcp.client.enabled=false

Effect: No MCP client beans created.

Exclude Auto-Configuration

@SpringBootApplication(exclude = {
    QuiteMcpClientAutoConfiguration.class
})
public class MyApp { }

Or via properties:

spring.autoconfigure.exclude=\
  com.embabel.agent.autoconfigure.platform.QuiteMcpClientAutoConfiguration

Multiple Clients

MCP client beans are lists supporting multiple clients:

@Autowired
private List<McpSyncClient> mcpClients; // May contain multiple clients

public void useAll() {
    for (McpSyncClient client : mcpClients) {
        // Use each client
    }
}

public void useSpecific(String transportName) {
    for (McpSyncClient client : mcpClients) {
        if (client.getTransportName().equals(transportName)) {
            // Use specific client
        }
    }
}

Handler Registration

Sync Handler Registry

import org.springframework.ai.mcp.client.common.autoconfigure.handler.ClientMcpSyncHandlersRegistry;
import org.springframework.stereotype.Component;

@Component
public class MySyncHandlers implements ClientMcpSyncHandlersRegistry {

    @Override
    public void handleLogging(String transportName,
                             LoggingMessageNotification notification) {
        logger.info("[{}] {}", transportName, notification.getMessage());
    }

    @Override
    public void handleProgress(String transportName,
                              ProgressNotification notification) {
        logger.info("Progress: {}", notification.getProgress());
    }

    // Implement other handler methods...
}

Async Handler Registry

import org.springframework.ai.mcp.client.common.autoconfigure.handler.ClientMcpAsyncHandlersRegistry;
import reactor.core.publisher.Mono;

@Component
public class MyAsyncHandlers implements ClientMcpAsyncHandlersRegistry {

    @Override
    public Mono<Void> handleLogging(String transportName,
                                    LoggingMessageNotification notification) {
        return Mono.fromRunnable(() ->
            logger.info("[{}] {}", transportName, notification.getMessage())
        );
    }

    // Implement other handler methods returning Mono<?>...
}

Troubleshooting

No MCP Clients Available

Check:

  1. spring.ai.mcp.client.enabled=true
  2. McpSchema.class on classpath
  3. Transport configuration correct
  4. Check logs for initialization failures

Client Initialization Timeout

Solution: Increase timeout:

spring.ai.mcp.client.request-timeout=30s

Transport Not Found

Cause: Transport auto-configuration not loaded.

Solution: Ensure transport dependency is present and configured.

Install with Tessl CLI

npx tessl i tessl/maven-com-embabel-agent--embabel-agent-platform-autoconfigure@0.3.0

docs

index.md

SCORING.md

tile.json