Cameleer / MCP
The action layer for AI agents
The model decides what. A tested route decides how.
Agents are good at deciding and bad at doing things exactly once, within the rules, with a record of who allowed what. Cameleer sits between them and your systems: agents call it over MCP from Claude, IDE assistants and agent frameworks, each action runs as a tested route (an existing route becomes a tool by changing one line), and the server enforces what the model can't be trusted with. Arguments are checked, retries run once, risky actions wait for a person, slow calls are stopped and every call is audited, whatever the model does. Cameleer is both an MCP server and an MCP client, so the same rules also cover the other MCP servers your agents use.
Why agents need an action layer
The same refund across orders, payments, shipping and email, with the agent calling each API itself, or calling one Cameleer route.
Direct tool calls
4 tool calls, 5 model turns
- A retried call refunds the customer twice
- A failed step leaves half-done work for the model to undo
- The model chooses the refund amount
- The agent holds every API key
- Nothing records what happened, or who allowed it
Through Cameleer
1 tool call, 2 model turns
- Each request runs once; a repeat gets the first result
- A saga cancels the refund when a later step fails
- The amount comes from the order, not the prompt
- Keys stay in the route; the agent can only call the tool
- Every call lands in a hash-chained audit log, with the approver
Tested end to end: resolved (200), the same call again runs nothing (200 duplicate), bad arguments named (400), not delivered yet (409), over the limit waits for a person (202), carrier down and the refund rolled back (502). The route and the walkthrough.
What Cameleer guarantees, whatever the model does
Each row is enforced by the server on every call, not left to a prompt or to each tool's author, and each is backed by a test or by the field test with Claude.
| when the model... | without an action layer | with Cameleer | shown by |
|---|---|---|---|
| sends the same call twice | the action runs twice: two refunds, two emails | it runs once per conversation; the repeat gets the first result | field test: a resent ticket made one ticket |
| invents or mangles arguments | they reach your API | rejected by the tool's JSON Schema, every error named; nothing runs | hermetic tests |
| picks a risky action | it runs | it waits for the user's yes in the client, or for an operator | field test: cancellations and refunds approved and declined |
| ignores a business rule | it runs if the prompt didn't stop it | the route refuses and says why; the model passes the reason on | field test: a £900 refund refused, and not split to get under the limit |
| reads instructions planted in data | it may act on them | data comes back as data, and destructive tools still need a person's yes | field test: an injected "refund order 1020" reported, not acted on |
| waits on a slow system | the call times out but the work carries on | the timeout cancels the route before its next step | hermetic tests |
| is shown personal data | it sees everything the API returns | redacted before it leaves the server (card numbers, emails, secrets) | field test: no full card number, ever |
| is asked what it did | whatever the framework happened to log | a hash-chained record per call: caller, argument digest, decision, approver | a test detects an edited record |
Prove which server and tools an agent is talking to
Next release: run Cameleer in a confidential VM (Intel TDX, AMD SEV-SNP or a dstack CVM) and an MCP client can ask, in the handshake, for hardware evidence of the exact routes, configuration and tools the server runs, bound to the client's nonce and to the session's TLS connection. A model showing that evidence is not checking it; the client program checks the binding and the hardware signature. How it works, and what it does not prove yet.
More than an MCP server
MCP is how agents reach the action layer. Around it, Cameleer does the rest of the work an agent needs, in the same process.
1. Events in
Kafka, MQTT, webhooks, files, mailboxes, queues and databases trigger the agent, filtered and enriched first so you pay for fewer tokens.
2. The model
23 providers (OpenAI, Anthropic, Gemini, Bedrock, Azure OpenAI, Vertex AI, Ollama and OpenAI-compatible services) with retries, fallback models and caching, or any agent over MCP.
3. Route on the answer
Content-based routing on the model's answer, schema checks on its output, a re-ask on failure; the agent step runs a model and its tools in a loop inside a route.
4. Reliable actions
MCP or REST tools behind the guarantees above, plus rate limits, circuit breakers and compensation; a gateway puts the same rules on other MCP servers' tools.
An existing route becomes an MCP tool by changing one line
Keep the route's steps. Replace the line it starts from with an ai-tool URI that names the tool and its arguments, then run it with --mcp. The route still does the work with any of Cameleer's about 230 components; the server adds the checks on every call.
The one changed line
- route:
id: order-lookup
from:
- uri: direct:lookup-order
+ uri: "ai-tool:lookup_order?description=Look up an order by id¶meter.orderId=string¶meter.orderId.required=true&readOnlyHint=true"
steps:
- setBody:
simple: '{"orderId": "${header.orderId}", "status": "shipped"}'
The file is examples/agents/route-to-mcp-tool.camel.yaml; a test checks that it differs from the original route in that one line and serves the tool.
Then serve it with one command
# the CLI
cameleer run orders.camel.yaml --mcp # http://localhost:8080/mcp
cameleer run orders.camel.yaml --mcp-stdio # for Claude Desktop
# Docker
docker run --rm -p 8080:8080 -v "$PWD:/routes:ro" \
pmsudhi/cameleer run /routes/orders.camel.yaml --mcp
# the Rust crate (cameleer-main)
main.set_property("camel.server.mcp-enabled", "true");
b.from("ai-tool:lookup_order?description=Look up an order by id¶meter.orderId=string¶meter.orderId.required=true&readOnlyHint=true")
.set_body(simple(r#"{"orderId": "${header.orderId}"}"#));
And on every call
- Checked: JSON Schema 2020-12 on the arguments; unknown and
camel*arguments dropped. - Run once: a retried call in the same conversation returns the first result.
- Approved: destructive tools show the user a form, or wait for an operator.
- Bounded: rate limits, circuit breakers, and a timeout that cancels the route.
- Recorded: redaction of personal data, then a hash-chained audit record.
A route that other routes or a REST endpoint also call keeps its direct: start; add a three-line ai-tool route in front of it that does to: direct:lookup-order. Apache Camel's ai-tool, ai-resource and camel.server.mcp-* names work unchanged. Reference: Cameleer MCP guide, MCP server.
Or serve existing routes with no edits at all
--mcp-expose serves routes you already run as MCP tools without touching the route files. It is on the main branch now and ships in the next release.
One flag
cameleer run orders.camel.yaml --mcp-expose rest:* cameleer run orders.camel.yaml --mcp-expose direct:lookup-* cameleer run orders.camel.yaml --mcp-stdio --mcp-expose rest:*,route:billing-*
Patterns select REST DSL operations by path (rest:/orders*), routes by consumer URI (direct:lookup-*) or by id (route:billing-*). The property is camel.server.mcp-expose-routes.
What the model gets
- Typed tools from REST: path, query and header parameters with their types, descriptions, defaults and allowed values become the tool's JSON Schema;
bodyfor POST, PUT and PATCH. - Readable errors: a 4xx or 5xx reply comes back as a tool error the model can read; JSON replies are structured content.
- Safe by default: nothing is exposed without a pattern; GET and HEAD are read-only, every other exposed tool needs approval.
- The same envelope: schema checks, deduplication, timeout and audit on every call; per-route overrides take every
ai-tooloption.
Five tests in crates/cameleer-main/tests/mcp_expose.rs cover it, including the real binary over stdio. Routes added after start-up (dev reload) are not picked up yet. Reference: Expose existing routes without editing them.
Both an MCP server and an MCP client
Most products are one or the other. Cameleer is both, with the same checks on both sides, so it can serve your tools, use other servers' tools, and stand between your agents and every server they use.
As a server
- serves routes as tools, resources and prompts to Claude Desktop, VS Code, Cursor, Claude Code and agent frameworks;
- the 2026-07-28 and 2025-11-25 protocol eras on one endpoint, over Streamable HTTP and stdio;
- official conformance suite: 39/39 (2025-11-25) and 26/26 (2025-06-18).
As a client
- imports the tools of other MCP servers (HTTP or stdio, either era) with
camel.ai.mcp.NAME.*; - routes call them with the
mcp:component, and models use them from the agent step or a model component; - as a gateway, it serves them again next to your own, with its approvals, rate limits, audit and pinned definitions (gateway).
Use cases, with the requests people typed
Each page shows real requests from the field test against the shop example (a whole back office in one YAML file), the tool calls Claude made, the answer, and the tested route behind it.
Customer-service lookups
"Where is order 1007?" One read-only call, the facts, an answer. 32 of 32 runs.
Questions that take several steps
"Which out-of-stock products have open orders waiting on them?" Nine calls, chained by the model. 21 of 24.
Actions guarded by approvals
"Cancel order 1021." The user approves in the client before anything runs. 32 of 32.
Refunds with the rules in the route
"Refund $900 on order 1020." Over the limit: refused in code, explained by the model. 20 of 20.
A manager in the loop
Goodwill credit waits for a manager outside the chat; asking again gets the decision.
The tool asks the user
"Swap the jacket for a different size." The route asks which size, mid-call.
Safety
Prompt injection in a ticket, a redacted card number, a request to delete data. 28 of 28.
Prompts and resources
Policies as documents the model reads; prompts the user picks. 8 of 8 in sessions.
One gateway for several servers
Import another MCP server's read-only tools, add your rules, serve one endpoint.
Where to run it
Desktop, server, Docker and Kubernetes, Cloud Run, AWS Lambda, an edge gateway.
Where it runs, and why each matters
| environment | transport | why |
|---|---|---|
| Claude Desktop and other desktop clients | stdio | the client starts the server: nothing to host, data stays on the machine |
| a server or VM | Streamable HTTP | one endpoint for a team, with API keys, JWT or OAuth token checks |
| Docker, Compose, Kubernetes | either | the same image as every other route, health checks, several replicas |
| Cloud Run, Knative, Container Apps | Streamable HTTP | routes run about 3 ms after start, so scaling to zero costs clients little |
| AWS Lambda | a function URL | the binary is its own Lambda runtime; stateless 2026-07-28 requests fit it |
| an edge gateway | either | tools next to the machines, data on site, arm64 and amd64 images |
Commands for each, all run against an image built from the source: Where to run it.
How it compares
One tool answering a JSON document, on three identical cloud machines (4 dedicated vCPUs each, 64 client connections).
| Cameleer | Apache Camel camel-mcp-server (JVM) | MCP TypeScript SDK (Node.js) | |
|---|---|---|---|
tools/call in sessions | 41,620/s | 22,458/s | 1,536/s |
| p99 latency | 5.9 ms | 5.2 ms | 79 ms |
| peak memory | 53 MB | 317 MB | 214 MB |
stateless tools/call (2026-07-28) | 51,700/s in 26 MB | not offered | not offered |
| Cameleer | Apache Camel camel-mcp-server | an official MCP SDK | direct tool calls | |
|---|---|---|---|---|
| argument checks | JSON Schema 2020-12 | required arguments | the schema | yours to write |
| duplicate calls | run once per conversation | not built in | yours to write | yours to write |
| risky calls | approval form or operator | hints are advisory | yours to write | yours to write |
| slow calls | the timeout cancels the route | the route keeps running | yours to write | yours to write |
| audit | hash-chained record per call | events and metrics | yours to write | yours to write |
| other MCP servers | imported and served again | client options in some AI producers | a client library | n/a |
Every Cameleer call in the benchmark went through the whole envelope, which costs about 6 µs per call on those machines. Camel has the larger ecosystem and its own strengths: Apache Camel's MCP server vs Cameleer. A hand-wired agent against a route on a four-system refund: direct tool calls vs Cameleer. Raw data: benchmarks. MuleSoft, Boomi, Workato, WSO2, TIBCO, IBM and Azure Logic Apps as MCP platforms: enterprise MCP platforms compared.
Tested with real requests through Claude
40 requests a shop's staff would type ran through Claude and the official MCP Python client against the shop example. Each run was graded on the tool calls made, the database afterwards and a separate judge of the answer.
| model | runs | correct | tool calls per request | cost per request |
|---|---|---|---|---|
| Claude Opus 5.5, 2025-11-25 sessions | 160 | 157 | 3.3 | about $0.026 |
| Claude Opus 5.5, 2026-07-28 stateless | 40 | 39 | 3.3 | about $0.025 |
| Claude Haiku 5.5, 2025-11-25 sessions | 120 | 104 | 2.9 | about $0.0007 |
The four Opus misses were slips in the answer, not wrong actions. The first run passed 25 of 36 requests; every failure led to a fix in Cameleer or in the example: Ask Claude about your business.
Common questions
How do I turn an existing route into an MCP tool?
Change the line the route starts from to an ai-tool URI that names the tool and its arguments, for example uri: "ai-tool:lookup_order?description=Look up an order by id¶meter.orderId=string¶meter.orderId.required=true", and run it with cameleer run orders.camel.yaml --mcp (or --mcp-stdio for Claude Desktop, or the same command in the pmsudhi/cameleer Docker image). The route's steps stay as they are. In a Rust program, start the route with b.from("ai-tool:...") and set camel.server.mcp-enabled=true.
Can a client check what a Cameleer MCP server is running?
In the next release, yes, when Cameleer runs in a confidential VM: the client sends a nonce in server/discover or initialize and gets a hardware-signed report bound to that nonce, to the server's TLS key and to a manifest of its routes, configuration and tools. Cameleer does not verify the hardware signature itself; the client uses the platform's verifier. See trust.
Is Cameleer an MCP server or an MCP client?
Both. It serves routes as MCP tools, resources and prompts, and it imports the tools of other MCP servers for routes and models to use, or to serve again as a gateway with its own checks.
What is Cameleer's MCP server?
It serves Cameleer routes (ai-tool, ai-resource and ai-prompt endpoints, with Apache Camel's option names) to MCP clients such as Claude Desktop, VS Code, Cursor and agent frameworks, over Streamable HTTP or stdio, in the 2026-07-28 and 2025-11-25 protocol eras. Every call goes through an envelope: schema checks, deduplication, approvals, rate limits, circuit breakers, a timeout that cancels the route, redaction and a hash-chained audit record.
How fast is it compared with Apache Camel's MCP server?
On three identical cloud machines with 4 dedicated vCPUs each and 64 connections, Cameleer served 41,620 tool calls per second in MCP sessions in 53 MB of memory, against 22,458 calls per second in 317 MB for Apache Camel 4.23's camel-mcp-server on the JVM and 1,536 calls per second in 214 MB for a server on the official MCP TypeScript SDK. Camel's p99 latency was lower (5.2 ms against 5.9 ms).
Does it work with Claude?
Yes. In a field test, 40 requests a shop's staff would type ran through Claude and the official MCP client against Cameleer's shop example: Claude Opus 5.5 completed 157 of 160 runs correctly in 2025-11-25 sessions and 39 of 40 in the stateless 2026-07-28 era, with 2.9 turns and 3.3 tool calls per request on average.
Where can it run?
As a subprocess of a desktop client over stdio, as a server, in Docker, Docker Compose and Kubernetes, on Cloud Run, Knative and Azure Container Apps, on AWS Lambda through a function URL, and on an edge gateway next to the devices its tools control.
Can it sit in front of other MCP servers?
Yes. Cameleer imports the tools of other MCP servers over HTTP or stdio, lets you choose which to expose, puts the same envelope on them (rate limits, caching, approvals, audit, pinned definitions) and serves them through one endpoint. See the gateway use case.
Try the shop in Claude Desktop
The shop example is 19 tools, three policies and two prompts in one YAML file. Run it over HTTP, or let Claude Desktop start it (configuration in the example's README).
git clone https://github.com/pmsudhi/cameleer && cd cameleer/examples/agents/mcp-shop cameleer run shop.camel.yaml --properties application.properties # or, with nothing installed but Docker: docker run --rm -p 18190:18190 -v "$PWD:/routes:ro" pmsudhi/cameleer run /routes/shop.camel.yaml \ --properties /routes/application.properties --prop acme.dir=/routes --prop camel.server.host=0.0.0.0