How Embabel‑Agent Integrates with External Tools and Platforms: A Complete Integration Guide
Embabel-agent integrates with external tools and platforms through three core layers: LLM provider abstractions via Spring‑AI, MCP (Model Context Protocol) clients and servers for tool interoperability, and A2A protocol support for agent federation, all wired together with Spring Boot auto‑configuration.
The Embabel Agent Platform is a Spring‑aware, JVM‑native framework designed to connect language models, external tools, and observability systems through a unified architecture. This article examines how embabel-agent achieves deep integration with LLM providers, MCP‑based tools, and monitoring platforms using concrete source code references and working configuration examples.
LLM Provider Integration via Spring‑AI
Embabel-agent does not implement LLM clients directly. Instead, it relies on Spring‑AI's ChatModel abstraction, auto‑configuring provider‑specific beans through dedicated starter modules.
Supported Provider Starters
| Provider | Starter Artifact | Configuration Class |
|---|---|---|
| OpenAI | embabel-agent-starter-openai |
[OpenAiAutoConfiguration.java](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-autoconfigure/models/embabel-agent-openai-autoconfigure/src/main/java/com/embabel/agent/autoconfigure/models/openai/OpenAiAutoConfiguration.java) |
| Anthropic | embabel-agent-starter-anthropic |
LLMAnthropicStreamingBuilderIT (test reference) |
| Ollama | emabel-agent-starter-ollama |
Production auto‑configuration shipped with starter |
| OCI Generative AI | embabel-agent-starter-oci |
Oracle Cloud Infrastructure integration |
| Gemini | embabel-agent-starter-gemini |
Google AI integration |
| MiniMax, Mistral‑AI | Dedicated starters | Provider‑specific model enums |
Each starter creates a ChatModel bean that the AgentPlatform injects into action execution contexts. Runtime model selection occurs through the Ai fluent API:
import com.embabel.agent.core.model.models.OpenAiModels;
import static com.embabel.agent.core.model.models.OpenAiModels.GPT_4;
// OpenAI provider
return ai.withLlm(GPT_4)
.createObject(prompt, Result.class);
// Anthropic provider
return ai.withLlm(LlmAnthropicModels.CLAUDE)
.createObject(prompt, Result.class);
The provider layer is completely interchangeable—no code changes are required beyond the withLlm() call.
MCP (Model Context Protocol) Tool Integration
MCP is the standardized protocol for exposing external capabilities to LLMs. Embabel-agent implements both client (consuming tools) and server (exposing tools) roles.
MCP Client: Consuming External Tools
The QuiteMcpClientAutoConfiguration creates resilient MCP clients that survive individual server failures. Unlike Spring‑AI's default implementation, this configuration tolerates startup errors and logs them without crashing the application.
Configure MCP clients in application.yml:
spring:
ai:
mcp:
client:
enabled: true
name: embabel
version: 1.0.0
type: SYNC # or ASYNC for non‑blocking operations
stdio:
connections:
brave-search:
command: docker
args: [run, -i, --rm, brave/search:latest]
wikipedia:
command: docker
args: [run, -i, --rm, wikipedia/mcp:latest]
postgres:
command: docker
args: [run, -i, --rm, postgres/mcp:latest]
The resilience design is critical: if the brave-search container fails to start, the platform continues with wikipedia and postgres available. This behavior is implemented through custom exception handling in QuiteMcpClientAutoConfiguration that wraps standard Spring‑AI MCP client creation with fallback logic.
Enabling MCP Servers via @EnableAgents
The @EnableAgents annotation declares which MCP servers activate for a given agent configuration:
import com.embabel.agent.config.annotation.EnableAgents;
@Configuration
@EnableAgents(mcpServers = { "brave-search", "wikipedia", "postgres" })
public class TravelAgentConfiguration {
// Additional beans...
}
During context initialization, the platform:
- Scans for
@EnableAgentsannotations - Creates
McpServerbeans for each named server - Registers them with the planning engine for goal‑selection
MCP Server: Exposing Tools to Other Agents
The AgentMcpServerAutoConfiguration module publishes an SSE endpoint at /sse that Claude Desktop, Copilot, or other MCP‑aware clients can consume.
Configuration properties control server behavior:
embabel:
agent:
mcp:
server:
enabled: true
execution-mode: SYNC # or ASYNC
transport: sse # Server‑Sent Events transport
When enabled, any @Action method with explicit tool descriptions becomes available through the MCP protocol to external consumers.
A2A Protocol: Agent‑to‑Agent Federation
Embabel-agent supports the A2A protocol for cross‑platform agent communication. Activating the a2a Spring profile starts an HTTP endpoint that accepts and responds to A2A messages:
# Start with A2A profile enabled
java -jar my-agent.jar --spring.profiles.active=a2a
The server binds to /a2a by default (e.g., http://localhost:8080/a2a), enabling:
- Remote task discovery: Other A2A agents query capability advertisements
- Secure delegation: Tasks execute with authenticated context propagation
- Status streaming: Long‑running operations report progress via SSE
This integration allows embabel-agent instances to participate in heterogeneous agent ecosystems without protocol translation.
Observability Integration: Micrometer and OpenTelemetry
The embabel-agent-observability module auto‑configures tracing and metrics through EmbabelSpanEventListener and EmbabelMetricsEventListener.
Automatic Span Generation
Every action execution, LLM call, and tool invocation becomes a child span:
Agent: TravelPlannerAgent
├─ Action: FindHotels
│ ├─ @Tracked: enrichCustomer (PROCESSING)
│ │ └─ Tool: brave-search (300ms)
│ ├─ ChatModel: gpt-4 (Spring AI) (1.2s)
│ └─ Tool: postgres/query-hotels (45ms)
└─ status: completed (traceId: abc123...)
Custom Tracking with @Tracked
The @Tracked annotation adds business‑context spans:
import com.embabel.agent.observability.annotation.Tracked;
import com.embabel.agent.observability.annotation.TrackType;
@Service
public class CustomerEnrichmentService {
@Tracked(
value = "enrichCustomer",
type = TrackType.PROCESSING,
description = "Enriches a Customer record with external data sources"
)
public Customer enrich(Customer input, Map<String, Object> externalData) {
// Implementation...
return enrichedCustomer;
}
}
Supported TrackType values include PROCESSING, VALIDATION, EXTERNAL_CALL, and AGGREGATION.
Exporter configuration follows standard Spring Boot properties:
management:
tracing:
sampling:
probability: 1.0
zipkin:
tracing:
endpoint: http://localhost:9411/api/v2/spans
metrics:
export:
otlp:
endpoint: http://localhost:4318/v1/metrics
Langfuse, Datadog, and custom OTel collectors are supported through Micrometer registries.
Platform Resilience: Auto‑Configuration Filtering
The AgentPlatformAutoConfigurationFilter prevents Spring‑AI's default MCP client auto‑configuration from activating when embabel-agent's resilient client is present. This avoids double‑bean registration and ensures the platform uses failure‑tolerant client implementations.
The filter implements AutoConfigurationImportFilter and excludes:
McpClientAutoConfiguration(Spring‑AI default)ToolCallbackAutoConfigurationwhere conflicting
Complete Integration Example
The following configuration demonstrates a production‑ready embabel-agent setup with multiple LLM providers, MCP tools, A2A federation, and observability:
package com.example.travel;
import com.embabel.agent.config.annotation.EnableAgents;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAgents(
mcpServers = { "brave-search", "postgres", "wikipedia" },
profiles = { "a2a" }
)
public class TravelAgentPlatformConfiguration {
}
# application.yml
spring:
ai:
mcp:
client:
enabled: true
name: travel-platform
version: 2.1.0
type: ASYNC
request-timeout: 30s
stdio:
connections:
brave-search:
command: docker
args: [run, -i, --rm, -e, BRAVE_API_KEY=${BRAVE_KEY}, brave/search:latest]
postgres:
command: docker
args: [run, -i, --rm, -e, DATABASE_URL=${DB_URL}, postgres/mcp:latest]
embabel:
agent:
mcp:
server:
enabled: true
execution-mode: ASYNC
management:
tracing:
enabled: true
sampling:
probability: 0.1
endpoints:
web:
exposure:
include: health, metrics, prometheus
// Action using tool groups
@Agent(description = "Intelligent travel planning assistant")
public class TravelPlanner {
@Action(
description = "Find and rank hotels based on user preferences",
toolGroups = { CoreToolGroups.WEB, CoreToolGroups.DATABASE }
)
public HotelRecommendations findHotels(
UserPreferences preferences,
TravelDates dates,
Ai ai) {
String prompt = buildHotelPrompt(preferences, dates);
return ai.withLlm(selectModelForComplexity(preferences))
.toolGroup(CoreToolGroups.WEB) // Requires brave-search
.toolGroup(CoreToolGroups.DATABASE) // Requires postgres
.createObject(prompt, HotelRecommendations.class);
}
private LlmModel selectModelForComplexity(UserPreferences prefs) {
return prefs.requiresReasoning()
? OpenAiModels.GPT_4
: OpenAiModels.GPT_4_MINI;
}
}
Key Source Files Reference
Summary
- LLM integration occurs through Spring‑AI
ChatModelbeans with provider‑specific starters for OpenAI, Anthropic, Ollama, and others - MCP client integration uses
QuiteMcpClientAutoConfigurationfor resilient, failure‑tolerant tool consumption - MCP server integration exposes agent capabilities via SSE endpoints configured in
AgentMcpServerAutoConfiguration - Tool activation is declarative through
@EnableAgentsand runtimetoolGroupsin action definitions - A2A federation enables cross‑platform agent communication with profile‑based activation
- Observability integrates Micrometer and OpenTelemetry through automatic span generation and
@Trackedannotations - Platform stability is guaranteed by
AgentPlatformAutoConfigurationFilterpreventing conflicting auto‑configurations
Frequently Asked Questions
How do I add a custom MCP server to embabel-agent?
Create a Docker container or native binary that implements the MCP JSON‑RPC protocol over stdio, then register it in application.yml under spring.ai.mcp.client.stdio.connections. The QuiteMcpClientAutoConfiguration will automatically create a client and inject it into the AgentPlatform. No Java code changes are required—only YAML configuration and container availability.
What happens if an MCP server fails to start?
The platform continues operating with reduced functionality. Unlike Spring‑AI's default implementation, embabel-agent's resilient client catches startup exceptions, logs them at WARN level, and excludes the failed server from the tool registry. Other configured MCP servers remain available. This behavior is implemented in QuiteMcpClientAutoConfiguration.
Can I use multiple LLM providers in the same application?
Yes. Add multiple provider starters to your classpath, then select the provider at call time using ai.withLlm(ModelEnum.SPECIFIC_MODEL). The Ai interface maintains separate client instances per provider, allowing mixed usage within the same agent or even the same action sequence when combined with conditional logic.
How do I integrate with Langfuse or a custom tracing backend?
Configure standard Spring Boot management properties for OTLP or Zipkin export. The EmbabelSpanEventListener emits all agent, action, and tool spans with consistent trace IDs. For Langfuse specifically, use the OpenTelemetry intake endpoint: https://cloud.langfuse.com/api/public/otel as your management.otlp.tracing.endpoint.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →