Cameleer

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.

196/200real requests handled right with Claude Opus 5.5field test, 40 requests, graded on the database afterwards
0wrong actions in those runs: none run twice, no rule broken, no risky call without a yesthe four misses were wording
41,620/sMCP tool calls in sessions, every one through the checksApache Camel's MCP server: 22,458/s
53 MBpeak memory in that runCamel: 317 MB, TypeScript SDK: 214 MB

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 layerwith Cameleershown by
sends the same call twicethe action runs twice: two refunds, two emailsit runs once per conversation; the repeat gets the first resultfield test: a resent ticket made one ticket
invents or mangles argumentsthey reach your APIrejected by the tool's JSON Schema, every error named; nothing runshermetic tests
picks a risky actionit runsit waits for the user's yes in the client, or for an operatorfield test: cancellations and refunds approved and declined
ignores a business ruleit runs if the prompt didn't stop itthe route refuses and says why; the model passes the reason onfield test: a £900 refund refused, and not split to get under the limit
reads instructions planted in datait may act on themdata comes back as data, and destructive tools still need a person's yesfield test: an injected "refund order 1020" reported, not acted on
waits on a slow systemthe call times out but the work carries onthe timeout cancels the route before its next stephermetic tests
is shown personal datait sees everything the API returnsredacted before it leaves the server (card numbers, emails, secrets)field test: no full card number, ever
is asked what it didwhatever the framework happened to loga hash-chained record per call: caller, argument digest, decision, approvera 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&parameter.orderId=string&parameter.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&parameter.orderId=string&parameter.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; body for 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-tool option.

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).

Where it runs, and why each matters

environmenttransportwhy
Claude Desktop and other desktop clientsstdiothe client starts the server: nothing to host, data stays on the machine
a server or VMStreamable HTTPone endpoint for a team, with API keys, JWT or OAuth token checks
Docker, Compose, Kuberneteseitherthe same image as every other route, health checks, several replicas
Cloud Run, Knative, Container AppsStreamable HTTProutes run about 3 ms after start, so scaling to zero costs clients little
AWS Lambdaa function URLthe binary is its own Lambda runtime; stateless 2026-07-28 requests fit it
an edge gatewayeithertools 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).

CameleerApache Camel camel-mcp-server (JVM)MCP TypeScript SDK (Node.js)
tools/call in sessions41,620/s22,458/s1,536/s
p99 latency5.9 ms5.2 ms79 ms
peak memory53 MB317 MB214 MB
stateless tools/call (2026-07-28)51,700/s in 26 MBnot offerednot offered
CameleerApache Camel camel-mcp-serveran official MCP SDKdirect tool calls
argument checksJSON Schema 2020-12required argumentsthe schemayours to write
duplicate callsrun once per conversationnot built inyours to writeyours to write
risky callsapproval form or operatorhints are advisoryyours to writeyours to write
slow callsthe timeout cancels the routethe route keeps runningyours to writeyours to write
audithash-chained record per callevents and metricsyours to writeyours to write
other MCP serversimported and served againclient options in some AI producersa client libraryn/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.

modelrunscorrecttool calls per requestcost per request
Claude Opus 5.5, 2025-11-25 sessions1601573.3about $0.026
Claude Opus 5.5, 2026-07-28 stateless40393.3about $0.025
Claude Haiku 5.5, 2025-11-25 sessions1201042.9about $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&parameter.orderId=string&parameter.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