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
┌──────────────────────────────┐
│ 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:
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:
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: COUNTPlugin vs Standalone
| Approach | How It Works | Use When |
|---|---|---|
| CIC Plugin | Drop 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 |
| Standalone | Run 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:
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):
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: COUNTIMPORTANT
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
cd sample-routes/camel-core-examples/cat-facts-exampleBuild the fat JAR (the build-time profile is the default and bundles the plugin automatically):
mvn clean packageThis produces target/cat-facts-example-1.0-SNAPSHOT-jar-with-dependencies.jar.
3b. Run the Application
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.jarYou should see logs indicating the plugin loaded, the route was found, and the tool was registered.
3c. Verify Registration
In a separate terminal:
wanaku capabilities listYou should see cat-facts-service listed.
wanaku tools listYou 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:
wanaku mcp tool \
--uri http://localhost:8080/mcp/sse \
--name cat-facts-route \
--param count=2Expected output (cat facts in JSON):
[
"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
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.yamlNOTE
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
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.yamlThe route is defined in cat-facts-route.camel.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
cd sample-routes/camel-core-examples/cat-facts-example
mvn clean package5b. Run as Standalone
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.jarUsing port 9191 here avoids conflicts if you already have the plugin version running.
5c. Verify and Test
wanaku capabilities list
wanaku tools listYou 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.
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.
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_HEADERIMPORTANT
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:
mcp:
resources:
- cat-facts-template:
route:
id: "cat-facts-template-route"
description: "Cat facts template data"Choosing Between Plugin and Standalone
| Plugin | Standalone | |
|---|---|---|
| Existing Camel app | Embed — no code changes | N/A — deploy as a new service |
| Independent deployment | No — shares host app lifecycle | Yes — isolated process |
| Container support | Via host app's Dockerfile | Own Dockerfile |
| CI/CD impact | Minimal — redeploy host app | Dedicated pipeline |
| Use case | Add capability to existing integration | Dedicated 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:
WARN No ContextServicePlugin found on classpathThe plugin requires camel-integration-capability-plugin as a dependency. With Maven, include it in your pom.xml:
<dependency>
<groupId>ai.wanaku</groupId>
<artifactId>camel-integration-capability-plugin</artifactId>
<version>0.2.0</version>
</dependency>Route not found at startup
ERROR Route 'wrong-route-id' not foundCheck 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
ERROR Registration failed: connection refusedConfirm Wanaku is running on the port in REGISTRATION_URL:
curl http://localhost:8080/healthIf 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?
- Camel Assistant (demo 5.01) — build an AI assistant backed by Apache Camel documentation and Wanaku tools
- Camel Integration Capability (demo 3.02) — full cloud deployment of the CIC on OpenShift
If you find a bug, please report it. To get in touch with the community, visit the Wanaku project.