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

> Customize Embabel-Agent easily. Tailor execution modes LLM providers domain models tool groups and observability without major rewrites. A complete guide for your specific needs.

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

---

**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`](https://github.com/embabel/embabel-agent/blob/main/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`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-api/README.md) contains the complete property table with `embabel.agent.platform.ranking.max-attempts` documented at line 25.

```yaml

# 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`](https://github.com/embabel/embabel-agent/blob/main/README.md) lines 25–34 show the `StarNewsFinder` implementation.

```java
@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`](https://github.com/embabel/embabel-agent/blob/main/README.md) lines 36–44 define `StarPerson`, `Horoscope`, and `Writeup` with Jackson mappings.

```java
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`](https://github.com/embabel/embabel-agent/blob/main/README.md) lines 55–60 demonstrate custom LLM bean creation.

```kotlin
@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:

```java
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`](https://github.com/embabel/embabel-agent/blob/main/README.md) lines 56–63 show `findNewsStories` requesting the web tool group.

```kotlin
@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`](https://github.com/embabel/embabel-agent/blob/main/README.md) lines 62–70 document automatic span creation and `@Tracked` usage.

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

```

Configure exporters in [`application.yml`](https://github.com/embabel/embabel-agent/blob/main/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`](https://github.com/embabel/embabel-agent/blob/main/README.md) lines 71–78 cover MCP client configuration and Docker startup.

```yaml

# application.yml

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

```

Start with Docker:

```bash
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`](https://github.com/embabel/embabel-agent/blob/main/README.md) lines 76–85 list all Spring profiles.

Activate a profile at runtime:

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

```

Or via environment variable:

```bash
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`](https://github.com/embabel/embabel-agent/blob/main/README.md) lines 11–15 reference `StarNewsFinderTest` as the example pattern.

```java
@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`](https://github.com/embabel/embabel-agent/blob/main/README.md) | Quick‑start, configuration guide, all main examples | Repository root |
| [`embabel-agent-api/README.md`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-api/README.md) | API surface, property tables, agent patterns | `embabel-agent-api/` |
| [`embabel-agent-starter/pom.xml`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-starter/pom.xml) | Maven dependency definitions | `embabel-agent-starter/` |
| [`embabel-agent-observability/README.md`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-observability/README.md) | Tracing setup, exporter configuration, `@Tracked` | `embabel-agent-observability/` |
| [`embabel-agent-shell/README.md`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-shell/README.md) | Interactive shell, custom prompt hooks | `embabel-agent-shell/` |
| [`embabel-agent-skills/README.md`](https://github.com/embabel/embabel-agent/blob/main/embabel-agent-skills/README.md) | Skill directory customization | `embabel-agent-skills/` |

---

## Summary

- **Configuration properties** in [`application.yml`](https://github.com/embabel/embabel-agent/blob/main/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.