Skip to content

Exposing Existing Camel Routes

You already have Apache Camel routes running in your infrastructure. They call your HR API, query databases, send emails. Now you want AI agents to use them through Wanaku — without rewriting those routes or building a custom capability from scratch.

This guide shows you two ways to make that happen: the plugin approach (embed the capability in your existing Camel application) and the standalone approach (run the Camel Integration Capability as its own process). Both use a rules YAML file to tell Wanaku which routes to expose and how to map parameters.

What You Will Learn

  • How to expose an existing Camel route as an MCP tool using the CIC plugin
  • How to write a rules YAML file to map MCP parameters to Camel headers
  • When to use a plugin vs running a second standalone instance

What You Will Need

  • Wanaku running locally via wanaku start local (see demo 1.01)
  • Wanaku CLI installed (releases page)
  • Java 21+
  • Apache Maven 3.8+
  • Camel JBang installed (for the JBang example only) — instructions at camel.apache.org

You do not need to have completed any prior Camel demo, but familiarity with demo 3.02 (Camel Integration Capability) will help.

Architecture Overview

text
┌──────────────────────────────┐
│ Existing Camel Route         │
│ (CatFactsRoute.java)         │
│ from("direct:catFacts")      │
│   .toD("...count=${header..}")│
└──────────────────────────────┘

            │ CIC Plugin embedded OR standalone

┌──────────────────────────────┐
│ Camel Integration Capability │
│  - loads routes               │
│  - applies meow-rules.yaml    │
│  - registers MCP tools        │
│  - starts gRPC server         │
└──────────────────────────────┘
            │ gRPC

┌──────────────────────────────┐
│ Wanaku MCP Router            │
│  (route "cat-facts-route")   │
└──────────────────────────────┘
            │ MCP

┌──────────────────────────────┐
│ AI Agent                     │
│ calls: count=3               │
└──────────────────────────────┘

Understanding the Pieces

The Route

Your existing Camel route is unchanged. In this demo, CatFactsRoute.java fetches random cat facts from an external API:

java
from("direct:catFacts")
    .routeId("cat-facts-route")
    .log("Fetching ${header.COUNT} cat facts...")
    .toD("https://meowfacts.herokuapp.com/?count=${header.COUNT}")
    .convertBodyTo(String.class)

The route expects a COUNT header. The job of the rules file is to map the MCP count parameter to that header.

The Rules File

The rules file (meow-rules.yaml) is the bridge between MCP and Camel. It declares which routes to expose and how to map parameters:

yaml
mcp:
  tools:
    - cat-facts-route:
        route:
          id: "cat-facts-route"
        description: "Retrieve random facts about cats"
        properties:
          - name: count
            type: int
            description: Number of facts to retrieve
            required: true
            mapping:
              type: header
              name: COUNT

Plugin vs Standalone

ApproachHow It WorksUse When
CIC PluginDrop the plugin JAR into your existing Camel app's classpath. No code changes.You already run a Camel app and just want to add capability
StandaloneRun the CIC as a separate process with its own Main class.You want an isolated capability service, similar to demo 4.01

This demo covers both.

Step 1: Navigate to the Sample Routes

The samples are in sample-routes/ inside this directory:

text
4.02-exposing-existing-routes/
  sample-routes/
    camel-core-examples/
      cat-facts-example/          ← plugin approach + standalone (Java)
    camel-jbang-examples/
      cat-facts-jbang-example/    ← plugin approach (JBang YAML)

Step 2: Write the Rules File

Create a file named meow-rules.yaml (relative to the example's working directory):

yaml
mcp:
  tools:
    - cat-facts-route:
      route:
        id: "cat-facts-route"
      description: "Retrieve random facts about cats"
      properties:
        - name: count
          type: int
          description: Number of cat facts to retrieve
          required: true
          mapping:
            type: header
            name: COUNT

IMPORTANT

The route.id must match the routeId set in your Camel route definition exactly (case-sensitive).

Step 3: Run the Cat Facts Example (Plugin Approach — Core)

This approach runs your Camel application with the CIC plugin on the classpath. The auto-discovery mechanism (Java ServiceLoader) finds and starts the plugin automatically.

3a. Build the Application

shell
cd sample-routes/camel-core-examples/cat-facts-example

Build the fat JAR (the build-time profile is the default and bundles the plugin automatically):

shell
mvn clean package

This produces target/cat-facts-example-1.0-SNAPSHOT-jar-with-dependencies.jar.

3b. Run the Application

shell
REGISTRATION_URL=http://localhost:8080 \
REGISTRATION_ANNOUNCE_ADDRESS=localhost \
GRPC_PORT=9190 \
SERVICE_NAME=cat-facts-service \
ROUTES_RULES=file://$PWD/config/meow-rules.yaml \
java -jar target/cat-facts-example-1.0-SNAPSHOT-jar-with-dependencies.jar

You should see logs indicating the plugin loaded, the route was found, and the tool was registered.

3c. Verify Registration

In a separate terminal:

shell
wanaku capabilities list

You should see cat-facts-service listed.

shell
wanaku tools list

You should see cat-facts-route listed.

3d. Test the Tool

Connect an MCP client such as the MCP Inspector to the Wanaku router and invoke the tool. Use the router's MCP endpoint (e.g., http://localhost:8080/mcp/sse) and call cat-facts-route with count=2.

Alternatively, use the Wanaku CLI directly:

shell
wanaku mcp tool \
  --uri http://localhost:8080/mcp/sse \
  --name cat-facts-route \
  --param count=2

Expected output (cat facts in JSON):

text
[
  "Fact 1 about cats...",
  "Fact 2 about cats..."
]

Step 4: Run the Cat Facts Example (Plugin Approach — JBang)

If you prefer defining routes in YAML DSL instead of Java, use the JBang variant.

4a. Set Environment Variables

shell
export REGISTRATION_URL=http://localhost:8080
export REGISTRATION_ANNOUNCE_ADDRESS=localhost
export GRPC_PORT=9190
export SERVICE_NAME=cat-facts-jbang-service
export ROUTES_RULES=file://$PWD/config/meow-rules.yaml

NOTE

The JBang example currently ships without a meow-rules.yaml file. Copy the one from the core example into sample-routes/camel-jbang-examples/config/ or create one with the same content from Step 2.

4b. Run with Camel JBang

shell
camel run --dep ai.wanaku.sdk:capabilities-runtime-camel-plugin:0.2.0 \
  sample-routes/camel-jbang-examples/cat-facts-jbang-example/cat-facts-route.camel.yaml

The route is defined in cat-facts-route.camel.yaml:

yaml
- route:
    id: cat-facts-route
    from:
      uri: direct:catFacts
    steps:
      - log:
          message: "Fetching ${header.COUNT} cat facts..."
      - toD:
          uri: "https://meowfacts.herokuapp.com/?count=${header.COUNT}"
      - convertBodyTo:
          type: String
      - log:
          message: "Response: ${body}"

Step 5: Run as a Second Instance (Independent Registration)

This sample uses the same fat JAR for both the plugin approach and the standalone pattern. When you run it with a different SERVICE_NAME and GRPC_PORT, the embedded plugin registers a separate capability — a second, independent entry in the router, even though the underlying binary is identical. This is useful when you want route isolation without launching a host Camel application.

5a. Build the Fat JAR

shell
cd sample-routes/camel-core-examples/cat-facts-example
mvn clean package

5b. Run as Standalone

shell
REGISTRATION_URL=http://localhost:8080 \
REGISTRATION_ANNOUNCE_ADDRESS=localhost \
GRPC_PORT=9191 \
SERVICE_NAME=cat-facts-standalone \
ROUTES_RULES=file://$PWD/config/meow-rules.yaml \
java -jar target/cat-facts-example-1.0-SNAPSHOT-jar-with-dependencies.jar

Using port 9191 here avoids conflicts if you already have the plugin version running.

5c. Verify and Test

shell
wanaku capabilities list
wanaku tools list

You should see both cat-facts-service (plugin) and cat-facts-standalone (standalone) as separate capabilities, each exposing cat-facts-route.

TIP

This is the key difference from demo 4.01: you didn't write a single line of tool logic. The CIC handles parameter mapping, gRPC serving, and registration. You only wrote the rules YAML.

Route Exposure Rules

Parameter Mapping Modes

The rules file supports two mapping modes (see the full schema reference):

Automatic mapping (no properties defined): all MCP parameters are mapped to Camel headers with a Wanaku. prefix.

yaml
mcp:
  tools:
    - my-route-tool:
      route:
        id: "my-route"
        description: "Does something"

Explicit mapping (with properties): only defined parameters are mapped, with custom header names.

yaml
mcp:
  tools:
    - my-route-tool:
      route:
        id: "my-route-id"
        description: "Does something"
      properties:
        - name: param1
          type: string
          required: true
          mapping:
            type: header
            name: MY_HEADER

IMPORTANT

Never mix automatic and explicit mapping for the same tool. Either define properties with mappings, or omit properties entirely.

Resources

You can also expose Camel routes as resources (passive data sources). Resources don't execute the route body — they fetch data from the endpoint URI using a consumer template. The route must have autoStartup: false.

This feature is not part of this demo's flow, but the structure is the same as for tools:

yaml
mcp:
  resources:
    - cat-facts-template:
      route:
        id: "cat-facts-template-route"
        description: "Cat facts template data"

Choosing Between Plugin and Standalone

PluginStandalone
Existing Camel appEmbed — no code changesN/A — deploy as a new service
Independent deploymentNo — shares host app lifecycleYes — isolated process
Container supportVia host app's DockerfileOwn Dockerfile
CI/CD impactMinimal — redeploy host appDedicated pipeline
Use caseAdd capability to existing integrationDedicated capability service

Decision rule: if you already run Camel in production, use the plugin. If you want the capability isolated from your integration app, use standalone.

Troubleshooting

Plugin not loading

If the plugin is not discovered at startup, verify the JAR is on the classpath:

text
WARN No ContextServicePlugin found on classpath

The plugin requires camel-integration-capability-plugin as a dependency. With Maven, include it in your pom.xml:

xml
<dependency>
  <groupId>ai.wanaku</groupId>
  <artifactId>camel-integration-capability-plugin</artifactId>
  <version>0.2.0</version>
</dependency>

Route not found at startup

text
ERROR Route 'wrong-route-id' not found

Check that the route.id in meow-rules.yaml matches the routeId() call in your Java route or the id: field in your YAML route.

Plugin registration fails

text
ERROR Registration failed: connection refused

Confirm Wanaku is running on the port in REGISTRATION_URL:

shell
curl http://localhost:8080/health

If using Podman/Docker, set REGISTRATION_ANNOUNCE_ADDRESS to an address reachable from the container (e.g., host.docker.internal or your machine IP).

What's Next?

If you find a bug, please report it. To get in touch with the community, visit the Wanaku project.