How to Customize Embabel‑Agent for Your Specific Needs: A Complete Customization Guide

Embabel‑Agent is built on a modular, Spring‑Boot‑style architecture that lets you tailor execution modes, LLM providers, domain models, tool groups, and observability without heavy rewrites.

This guide walks you through every major customization point in the embabel/embabel-agent framework. Whether you're swapping LLMs, defining custom actions, or integrating with MCP servers, you'll find concrete examples drawn directly from the source code.


Configuration Properties: Control Runtime Behavior Without Code Changes

All embabel-agent settings externalize to application.yml or environment variables. This lets operations teams tune behavior without recompiling.

Key property examples:

  • Execution modes – Switch between planning strategies
  • Planning limits – embabel.agent.platform.ranking.max-attempts caps replanning attempts
  • LLM provider selection – Reference named Llm beans
  • Tool group toggles – Enable/disable MCP tool categories
  • Tracing options – Configure span export targets

Source: embabel-agent-api/README.md contains the complete property table with embabel.agent.platform.ranking.max-attempts documented at line 25.


# application.yml

embabel:
  agent:
    platform:
      ranking:
        max-attempts: 10   # increase replanning attempts

Agent Definition: Create Custom Actions, Goals, and Conditions

Java: Annotation‑Driven Agent Design

Use @Agent, @Action, @Goal, and @Condition annotations to declare agent behavior. The StarNewsFinder agent in the README demonstrates this pattern.

Source: README.md lines 25–34 show the StarNewsFinder implementation.

@Action
public WeatherReport getWeather(@Param("city") String city, Ai ai) {
    return ai.withLlm(OpenAiModels.GPT_4)
             .createObject("Give a concise weather forecast for %s".formatted(city),
                          WeatherReport.class);
}

Kotlin: DSL‑Based Agent Construction

The Kotlin DSL provides a concise alternative using agent { … } blocks for declarative agent configuration.


Domain Model Customization: Strongly‑Typed LLM Interactions

Define POJOs or Kotlin data classes that LLMs instantiate directly or that expose @Tool methods for safe tool use. Jackson annotations drive automatic schema generation for structured outputs.

Source: README.md lines 36–44 define StarPerson, Horoscope, and Writeup with Jackson mappings.

public record WeatherReport(
    @JsonProperty("temperature") double temperature,
    @JsonProperty("conditions") String conditions,
    @JsonProperty("recommendation") String recommendation
) {}

LLM Selection: Plug in Any Spring AI ChatModel

Embabel‑Agent accepts any ChatModel that Spring AI supports: OpenAI, Anthropic, Ollama, OCI GenAI, or custom providers. Define a Spring bean of type Llm or use dedicated starters like embabel-agent-starter-ollama.

Source: README.md lines 55–60 demonstrate custom LLM bean creation.

@Configuration
class MyLlmConfig {
    @Bean
    fun myCustomLlm(): Llm = LlmOptions
        .withModel("my-company/custom-model")
        .withTemperature(0.7)
        .build()
}

Reference your custom LLM by bean name in actions:

ai.withLlm("myCustomLlm").createObject(prompt, Result.class);

Tool Groups: Enable Per‑Action MCP Capabilities

Control which Model Context Protocol (MCP) tools an action can invoke. Available groups include WEB, SEARCH, WIKIPEDIA, and others.

Source: README.md lines 56–63 show findNewsStories requesting the web tool group.

@Action(toolGroups = [ToolGroup.WEB, ToolGroup.SEARCH])
fun researchTopic(topic: String, ai: Ai): ResearchResult {
    val prompt = "Research the latest papers about $topic and summarise key findings."
    return ai.withDefaultLlm().createObject(prompt, ResearchResult::class.java)
}

Tool group assignment happens at the action level, giving granular control over agent capabilities.


Observability: Custom Tracing and Span Export

The observability module automatically instruments every action and LLM call. Add custom spans with @Tracked for fine‑grained performance visibility.

Source: README.md lines 62–70 document automatic span creation and @Tracked usage.

@Tracked("fetchCustomerData")
public Customer fetchCustomerData(String id) {
    // database or service call
    return customerRepository.findById(id);
}

Configure exporters in application.yml:

  • Zipkin – Distributed tracing infrastructure
  • Langfuse – LLM‑specific observability platform

MCP Server Integration: Expose Agents to External UIs

Run Embabel‑Agent as an MCP server to make your agents accessible from Claude Desktop, custom front‑ends, or other MCP clients.

Source: README.md lines 71–78 cover MCP client configuration and Docker startup.


# application.yml

spring:
  ai:
    mcp:
      client:
        enabled: true
        server:
          url: http://localhost:8080

Start with Docker:

docker run -p 8080:8080 \
  -e SPRING_PROFILES_ACTIVE=mcp-server \
  embabel/embabel-agent:latest

Spring Profiles: Switch Between Predefined Configurations

Profiles bundle related settings for common deployment scenarios. Available profiles include:

  • docker-desktop – Full web‑tool support for local development
  • severance – Reference configuration for the Severance demo
  • starwars – Star‑themed agent demonstration

Source: README.md lines 76–85 list all Spring profiles.

Activate a profile at runtime:

java -jar embabel-agent.jar --spring.profiles.active=docker-desktop

Or via environment variable:

export SPRING_PROFILES_ACTIVE=docker-desktop

Testing Customizations: Mock LLMs for Reliable Tests

The framework provides FakeOperationContext for unit testing without live LLM calls. Verify prompts and tool usage programmatically.

Source: README.md lines 11–15 reference StarNewsFinderTest as the example pattern.

@Test
void shouldRequestWeatherForCity() {
    FakeOperationContext context = new FakeOperationContext();
    WeatherAgent agent = new WeatherAgent(context);
    
    agent.getWeather("Bucharest", context.ai());
    
    assertThat(context.lastPrompt()).contains("Bucharest");
    assertThat(context.toolCalls()).isEmpty();
}

Key Source Files for Customization

File Purpose Location
README.md Quick‑start, configuration guide, all main examples Repository root
embabel-agent-api/README.md API surface, property tables, agent patterns embabel-agent-api/
embabel-agent-starter/pom.xml Maven dependency definitions embabel-agent-starter/
embabel-agent-observability/README.md Tracing setup, exporter configuration, @Tracked embabel-agent-observability/
embabel-agent-shell/README.md Interactive shell, custom prompt hooks embabel-agent-shell/
embabel-agent-skills/README.md Skill directory customization embabel-agent-skills/

Summary

  • Configuration properties in application.yml control runtime behavior without recompilation
  • Agent definitions use Java annotations or Kotlin DSL for declaring actions, goals, and conditions
  • Domain models as Jackson‑annotated classes enable structured LLM outputs
  • LLM selection works through Spring bean definition or dedicated starters
  • Tool groups restrict MCP capabilities per action via toolGroups parameter
  • Observability combines automatic spans with @Tracked custom instrumentation
  • MCP server mode exposes agents to external UIs and clients
  • Spring profiles bundle environment‑specific configurations

Frequently Asked Questions

How do I add a custom LLM provider to embabel-agent?

Define a Spring bean of type Llm using LlmOptions builder, then reference it by name in your actions. The custom bean integrates automatically with Spring AI's abstraction layer, supporting any ChatModel implementation.

Can I disable specific tools for certain actions?

Yes. Use the toolGroups parameter in @Action annotations to whitelist only required MCP capabilities. Omit the parameter to inherit default tools, or pass an empty array to restrict all external tool access.

What testing approach works best for customized agents?

Use FakeOperationContext to mock LLM interactions and assert on prompts, tool calls, and generated outputs. This pattern appears in StarNewsFinderTest and enables fast, deterministic unit tests without API rate limits or costs.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →