Cameleer
Camel routes in Rust. The reliable action layer for AI agents.
Cameleer is Apache Camel's integration model, rebuilt in Rust: if you know Apache Camel, you already know Cameleer. The same endpoint URIs, Enterprise Integration Patterns, Simple expressions, YAML routes, headers and error handling. About 230 components, languages and data formats, ported one by one and verified against the real systems.
- Act reliably. An agent decides; a route does it. Serve routes as MCP tools with one
command (
cameleer run tools.camel.yaml --mcp), and every call is validated against a JSON schema, runs once, waits for a person when the stakes are high, cancels on timeout, rolls back and lands in a hash-chained audit log (the action layer for agents). - Keep your routes. Camel YAML and XML routes run unchanged; your team's Camel designs and habits come with you (migrating from Apache Camel).
- Run anywhere. One native binary that starts in 3 ms, runs in megabytes, is its own AWS Lambda runtime, and moves 1.7–8.7x the messages of Apache Camel on the same CPUs, in every scenario we measured (Apache Camel vs Cameleer).
Cameleering is running Apache Camel routes this way: the same patterns, URIs and YAML, driven by one native binary instead of the JVM, at the edge, in serverless functions and behind AI agents (what is cameleering?).
Website · Docs · Use cases · Quick start · Benchmarks · Agents · MCP tools · Serverless · Roadmap · FAQ
Cameleer was called rust-camel up to v0.1.0.
Based on Apache Camel (source), the integration framework by the Apache Software Foundation. Cameleer follows its names, options and semantics but contains no Camel source code. It is an independent project, not affiliated with or endorsed by the ASF. Apache, Apache Camel and Camel are trademarks of the Apache Software Foundation.
Rebuilt for speed, memory and scale
The same routes on Cameleer and on Apache Camel, on the JVM and compiled natively with Quarkus:
Startup (spawn → routes running) lower is better
Cameleer ▏ 3 ms
Camel JVM ████████████████████████████████████████ 1,106 ms
Camel native █ 30 ms
Memory, same route (peak) lower is better
Cameleer ▏ 8 MB
Camel JVM ████████████████████████████████████████ 399 MB
Camel native ███████████▏ 113 MB
REST API with JSON higher is better
Cameleer ████████████████████████████████████████ 80.3k req/s
Camel JVM ██████████████████▏ 37.9k req/s
Camel native ████████▏ 17.9k req/s
HTTP into PostgreSQL higher is better
Cameleer ████████████████████████████████████████ 11.0k req/s
Camel JVM █████████████████▏ 4.8k req/s
Camel native ████████████▏ 3.6k req/s
Kafka stream processing higher is better
Cameleer ████████████████████████████████████████ 6.0k records/s
Camel JVM ████▏ 0.7k records/s
Camel native ████▏ 0.7k records/s
Content-based router higher is better
Cameleer ████████████████████████████████████████ 1.14M msg/s
Camel JVM █████████████▏ 375.3k msg/s
Camel native ████▏ 119.5k msg/s
| Cameleer | Apache Camel (JVM) | Apache Camel (Quarkus native) | |
|---|---|---|---|
| Startup | 3 ms | 1.1 s | 30 ms |
| Memory under load | 8–68 MB | 213–440 MB | 112–198 MB |
| REST API with JSON | 80.3k req/s | 37.9k req/s | 17.9k req/s |
| HTTP into Kafka | 17.8k req/s | 10.1k req/s | 9.3k req/s |
| HTTP into PostgreSQL | 11.0k req/s | 4.8k req/s | 3.6k req/s |
| Kafka stream processing | 6.0k records/s | 698 records/s | 694 records/s |
| CSV batch, 1,000-row files | 998 files/s | 468 files/s | 163 files/s |
| Split and aggregate a JSON order | 70.9k orders/s | 26.7k orders/s | 9.3k orders/s |
| Content-based router | 1.14M msg/s | 376k msg/s | 120k msg/s |
In-memory request-reply (seda) |
719k msg/s | 118k msg/s | 73k msg/s |
Every scenario, the method and the raw data: Apache Camel vs Cameleer
and the full report, docs/BENCHMARKS.md. Run it yourself with
scripts/cloud-bench for about a dollar of cloud time.
How, without changing what Camel means:
-
Nothing but the Rust standard library. TLS, SSH, HTTP/2, gRPC, AMQP, MQTT, the Kafka protocol, the PostgreSQL, Redis, MongoDB and Cassandra wire protocols, XML and JSON are all written from scratch. There's no dependency tree, no build-time downloads and no supply-chain surprise.
-
No JVM, no garbage collector. The compiler guarantees memory safety, and routing never pauses for GC.
-
Engineered hot paths:
- a thread-caching allocator;
- exchange ids created only when read;
- copy-on-write JSON objects;
- a two-lock seda queue that spins before it parks;
- statistics on the CPU's time-stamp clock with per-thread counters.
The details are in benchmarks/analysis.md.
Same Camel. Same signature.
Here is a route that sends big orders from Kafka to SQS and taps every order into an audit topic, written for Apache Camel and for Cameleer:
.
.
.
.
.;
b.from
.route_id
.filter
.to
.end
.wire_tap;
Same URIs, same EIPs, same expression. Only the casing follows Rust. If you write Camel YAML, you don't change anything at all:
- route:
id: big-orders
from:
uri: kafka:orders
steps:
- wireTap: kafka:audit
- filter:
simple: "${header.amount} > 100"
steps:
- to: aws2-sqs:big-orders
$ cameleer run big-orders.camel.yaml # the Camel JBang workflow, as one native binary
What carries over from Camel:
- endpoint URIs and their options;
- EIP names and semantics: split, aggregate, multicast, circuit breaker, saga, idempotent consumer and the rest;
- the Simple, JSONPath, XPath and jq languages;
Camel*headers and exchange properties;onExceptionand the dead letter channel;- the YAML and XML DSLs, the REST DSL, Kamelets and route templates;
- health checks, metrics, tracing;
- Camel's
ai-toolandai-resourceendpoints and itscamel.server.mcp-*properties; - a Camel JBang-style CLI,
cameleer(run,init,export,get,trace), plusvalidate,testandtool.
Your team's Camel experience, designs and routes come with you.
The action layer for AI agents
The model decides what; a tested route decides how. Cameleer feeds events to models,
routes on their answers, and turns agent tool calls into reliable actions with validation,
idempotency, retries, sagas, human approval, rate limits, fallbacks and an audit log. Routes are
served as MCP tools to Claude Desktop, VS Code, Cursor and agent frameworks, called by models in
an agent step, or exposed as plain HTTP endpoints.
🔌 Serve routes as MCP tools. An ai-tool route (Apache Camel's endpoint and option names)
is a tool; one flag serves it:
- route:
id: lookup-order
from:
uri: ai-tool:lookup_order
parameters:
description: Look up an order by id
parameter.orderId: string
parameter.orderId.required: true
readOnlyHint: true
steps:
- setBody:
simple: '{"orderId": "${header.orderId}", "status": "shipped"}'
$ cameleer run tools.camel.yaml --mcp # Streamable HTTP on http://localhost:8080/mcp
$ cameleer run tools.camel.yaml --mcp-stdio # for clients that start the server themselves
- Every call goes through the same envelope: kill switch, authorization, JSON Schema 2020-12
argument checks, rate limit, circuit breaker, approval, idempotency, compensation, a timeout
that cancels the route, output checks and redaction, and a hash-chained audit record. Tool
definitions are pinned, and
cameleer tool disable|approve|denyacts on a running process. - Both MCP protocol eras on one endpoint (2026-07-28 and 2025-11-25/06-18/03-26), over
Streamable HTTP and stdio, with API-key, JWT and OAuth token checks. Approvals use the
protocol's own
input_requiredresults orelicitation/create. The official MCP conformance suite passes 39/39 (2025-11-25) and 26/26 (2025-06-18). - An MCP client and gateway: import other MCP servers' tools into the same envelope, with rug-pull protection, and serve them again.
- Measured: 41,620 MCP tool calls per second in sessions against 22,458 for Apache Camel's
camel-mcp-serveron the same machines, in 53 MB against 317 MB (p99 5.9 ms against 5.2 ms) (Apache Camel's MCP server vs Cameleer, MCP server guide).
An agent decides; something still has to do it:
- read from Kafka, call the model, write to Postgres;
- open the ticket, post to Slack;
- retry when the API times out, and never charge a card twice.
That's what Camel has done for enterprises for years. Cameleer does it for agents, as a library inside your agent or as a sidecar that starts in milliseconds.
🖐 Give agents hands. Every action becomes a route the agent can call over HTTP, a queue or directly, with retries, timeouts, idempotency and a dead letter channel. The agent says what; the route handles how, including the failures.
"Refund order 4411 and tell the customer" →
platform-http→ idempotent consumer → payments API with redelivery →slackoraws-ses, dead letter on failure.
Direct tool calls vs tool calls through Cameleer compares the two on a damaged-order refund across four systems, with the tested route.
⚡ Feed agents events, not polling loops. Turn Kafka, SQS, MQTT, webhooks, mailboxes and file drops into model calls. Filter and enrich first, so you pay for fewer tokens. Route on the answer.
New ticket on
kafka→ drop spam with a filter →aws-bedrock(Claude) classifies → urgent ones page on-call, the rest go to a queue.
📚 Ground agents in your data. Pull documents from S3, Google Drive, Gmail, SFTP or a database, split them, embed them with OpenAI, Bedrock or Vertex AI, and index them where you search. The same route keeps the index fresh.
New file in
aws2-s3→splitby paragraph →openai:embeddings→elasticsearch, with the source as metadata.
🛡 Keep models in check.
- a circuit breaker with fallback between Bedrock, Azure OpenAI and Vertex AI;
- a throttle to stay under rate limits;
- Bedrock guardrails on inputs and outputs;
- a wire tap of every prompt and answer to an audit log.
circuitBreaker→aws-bedrock(primary) → on failureazure-openai(fallback) →wireTaptokafka:llm-audit.
Every model component also takes maxRetries, fallbackModels, responseCache=exact and
coalesce, plus prompt caching (anthropic by default, aws-bedrock with promptCaching=true),
in the same process as the route, so there is no gateway hop
(model providers).
🔁 Run the agent loop in a route. The agent step runs a model and its tools until the model
answers or a turn, token or time limit is hit; tool calls go through the envelope above, a risky
call pauses the conversation for approval, and cameleer test replays recorded model responses so
an agent route is tested without a model (the agent step).
Models today: 23 providers, with tool calling in all of them: OpenAI and any OpenAI-compatible
server, including the Responses API, Ollama and provider= presets for 19 services (openai,
also llm), Anthropic (anthropic), Gemini (gemini), Azure OpenAI (azure-openai), AWS Bedrock
with Converse, streaming, guardrails and knowledge bases (aws-bedrock), and Google Vertex AI
(google-vertexai).
Rebuilt for serverless and the edge
Integrations sit idle, then get busy all at once: exactly the load serverless is priced for. A JVM fights that model: it takes most of a second to boot and hundreds of megabytes to idle.
- Scale to zero, wake up instantly. A 3 ms start fits inside a request's latency budget, and
cameleeris its own AWS Lambda runtime. - Pack tens of services onto one node. At 8 MB at startup and tens of MB under load, Cameleer fits on edge gateways and small devices that can't host a JVM.
- One executable, nothing to install. No JRE to patch and no
-Xmxto tune.cameleer exportturns YAML routes into a standalone Rust project. - Ship only what the routes use. Every build includes everything by default; with
build features a function keeps only its component families
(
--features cloud,jq), down to a 5.9 MB binary withcore.
| Run it as | Status |
|---|---|
| a library inside your Rust service or agent | ✅ |
a single binary running YAML or XML routes (cameleer run, with hot reload in dev mode) |
✅ |
| a container on Cloud Run, Fargate, Azure Container Apps, Knative or Kubernetes | ✅ |
a standalone project generated from your routes (cameleer export) |
✅ |
a native AWS Lambda function (built-in custom runtime, provided.al2023) |
✅ AWS Lambda |
an MCP server exposing routes as agent tools (cameleer run --mcp) |
✅ MCP server |
Real uses
| Trigger | Route | Outcome | |
|---|---|---|---|
| Payments | payment events on kafka |
idempotent consumer → enrich from sql → model risk score → choice |
duplicates dropped, risky payments held, the rest settled |
| Healthcare | HL7 v2 over mllp |
parse → transform → http to the EHR, with redelivery |
results delivered exactly once, failures to a dead letter queue |
| Support | aws2-sqs, mail or telegram |
filter → aws-bedrock classifies and drafts → choice |
urgent issues paged, routine ones answered with a draft |
| E-commerce | order webhooks on platform-http |
split line items → route per warehouse → aggregate |
one fulfilment message per warehouse, stock in aws2-ddb |
| IoT and the edge | sensor readings on paho-mqtt5 |
throttle → aggregate per device per minute |
rollups to aws2-timestream, raw data stays on site |
| AI ops | github events and alerts on platform-http |
model summary → dedupe → route by severity | one Slack thread per incident, not a hundred alerts |
| File exchange | partner files on sftp |
unmarshal CSV, XML or EDI → validate → split |
rows in PostgreSQL, rejects back to the partner |
Every component named here ships today; each row is a pattern you assemble from them. The use-case pages walk through the tested routes for AI agent tools, HL7 over MLLP, MQTT edge gateways, AWS Lambda and file/SFTP pipelines.
Not packaged yet? Build it on the engine
| You want | Build it from today's parts | Packaged version |
|---|---|---|
| vector search for RAG | embeddings → pgvector through sql, OpenSearch k-NN, or Qdrant and Pinecone through http |
🚧 vector components |
| token streaming to users | model streaming chunks → websocket or a server-sent-events endpoint |
✅ parts ship |
| per-tenant token budgets | model usage headers → counters in spring-redis → filter before the call |
✅ parts ship |
| human approval outside an agent tool | slack or mail link → platform-http callback → resume the parked action |
✅ parts ship (tools have approvals built in) |
Sketches for each, plus the planned improvements to agents, serverless, performance, operations and verification, are in docs/ROADMAP.md.
Quick start
With Docker: run a Camel YAML route
Save this as hello-api.camel.yaml (or take examples/hello-api.camel.yaml):
- rest:
path: /orders
get:
- path: /{id}
to: direct:getOrder
- route:
from:
uri: direct:getOrder
steps:
- setBody:
simple: '{"id": "${header.id}", "status": "shipped"}'
Run it and call it:
The image is a single native binary on distroless, for linux/amd64 and linux/arm64, on
Docker Hub and as ghcr.io/pmsudhi/cameleer. It runs
as non-root and works with --read-only. Any route written for Apache Camel's YAML DSL runs the
same way. Kubernetes, Docker Compose and Cloud Run setups are in the
deployment guide.
As a Rust crate: embed it in your program
[]
= "0.5"
= "0.5"
use *;
use RestDslExt;
To run YAML routes with every component from your own program, depend on cameleer-main and
call cameleer_main::new_main(), then add_route_file(...) and run()
(examples/embed_yaml.rs).
The cameleer CLI
From crates.io:
Or from source:
&&
Camel JBang habits carry over: cameleer run, cameleer ps, cameleer stop.
A smaller build
The image, cargo install and the default build include every component, so any route runs
without setup. For a function or an edge device, keep only the families your routes use:
A feature list replaces the default, so name every family you use. Each component page names its feature, and a route that needs a missing one fails at startup with the feature to add. The build features guide lists them all.
Documentation
Every component, language, data format and EIP has a page with tested examples: cameleer.ing/docs (source in docs/). Start with getting started, build features, the agent cookbook, the edge cookbook or the component index.
Connect your coding agent
Give Cursor, Claude, Windsurf, VS Code or any MCP-capable assistant Cameleer's real docs, so it
writes routes from the documentation instead of guessing. The docs MCP server is
https://gitmcp.io/pmsudhi/cameleer (it serves this repository's llms.txt, docs and README).
| tool | add this |
|---|---|
| Claude Code | claude mcp add --transport http cameleer-docs https://gitmcp.io/pmsudhi/cameleer |
Cursor (~/.cursor/mcp.json) |
{"mcpServers": {"cameleer-docs": {"url": "https://gitmcp.io/pmsudhi/cameleer"}}} |
Windsurf (~/.codeium/windsurf/mcp_config.json) |
{"mcpServers": {"cameleer-docs": {"serverUrl": "https://gitmcp.io/pmsudhi/cameleer"}}} |
VS Code (.vscode/mcp.json) |
{"servers": {"cameleer-docs": {"type": "http", "url": "https://gitmcp.io/pmsudhi/cameleer"}}} |
Claude Desktop (claude_desktop_config.json) |
{"mcpServers": {"cameleer-docs": {"command": "npx", "args": ["mcp-remote", "https://gitmcp.io/pmsudhi/cameleer"]}}} |
The docs are also indexed by Context7 (ask your assistant to "use context7" for Cameleer) and DeepWiki. Agents that read files directly can start from llms.txt or llms-full.txt.
Real use cases, ready to run
Every file below runs end to end in the test suite
(crates/cameleer-main/tests/examples.rs) against an
embedded Kafka broker and mock S3, Slack and OpenAI servers. Each file's header lists the
environment variables it needs and the exact docker run command.
| use case | route | what it does |
|---|---|---|
| Smallest REST API | hello-api.camel.yaml | GET /orders/{id} returns JSON: the Quick start above. |
| REST API | rest-api.camel.yaml | JSON REST endpoints with validation, a content-based router and error handling. Needs nothing else. |
| AI ticket triage | ai-ticket-triage.camel.yaml | Kafka in, an LLM classifies each ticket P1 or P3, urgent tickets go to their own topic. Works with OpenAI or any OpenAI-compatible server (Ollama, vLLM, Azure OpenAI). |
| Alerts to Slack | alerts-to-slack.camel.yaml | An HTTP webhook takes monitoring alerts, keeps the critical ones and posts them to Slack. |
| Files to S3 | files-to-s3.camel.yaml | Watches a folder and uploads each new CSV file to S3, then moves it to .done. |
| Rust REST service | rest_service.rs | The Rust DSL with two crates: REST endpoints, JSON, an echo service. |
| Embed YAML in Rust | embed_yaml.rs | Your own binary that runs Camel YAML routes with every component. |
The AI triage route, for example:
- route:
id: ticket-triage
from:
uri: "kafka:support-tickets?brokers={{env:KAFKA_BROKERS:localhost:9092}}&groupId=triage&autoOffsetReset=earliest"
steps:
- setProperty:
name: ticket
simple: "${body}"
- to: "openai:chat-completion?model={{env:OPENAI_MODEL:gpt-4o-mini}}&baseUrl={{env:OPENAI_BASE_URL:https://api.openai.com/v1}}&temperature=0&systemMessage=Classify the support ticket. Reply P1 for outages, data loss or security issues, otherwise P3. Reply with P1 or P3 only."
- setHeader:
name: priority
simple: "${body}"
- setBody:
simple: "${exchangeProperty.ticket}"
- choice:
when:
- simple: "${header.priority} contains 'P1'"
steps:
- to: "kafka:tickets-urgent?brokers={{env:KAFKA_BROKERS:localhost:9092}}"
otherwise:
steps:
- to: "kafka:tickets-routine?brokers={{env:KAFKA_BROKERS:localhost:9092}}"
On Linux (with Docker Desktop, use KAFKA_BROKERS=host.docker.internal:9092 instead of
--network host):
FAQ
Is it a drop-in replacement for Apache Camel? For routes, mostly: URIs, options, EIPs, headers and Simple follow Camel, and Camel YAML and XML routes run. Java code doesn't: processors, beans and custom components are written in Rust.
Does it have every Camel connector? No. It has about 230 components, languages and data formats, including all of Camel's AWS, Azure and Google Cloud components, but not the long tail of vendor connectors. docs/FEATURES.md lists them row by row, including known gaps.
Does it run my LLM or store vectors? No. It calls models and moves embeddings into the stores you already run. It isn't a model runtime or a vector database.
Does it have an MCP server?
Yes. ai-tool, ai-resource and ai-prompt routes are served over Streamable HTTP or stdio
with cameleer run --mcp or --mcp-stdio, using Apache Camel's camel.server.mcp-* property
names, and every call goes through the reliability envelope
(MCP server guide).
Do I need a JVM or Maven? No. You need Rust to build it, and nothing at run time.
Why do management statistics default differently from Camel?
Camel collects statistics only when camel-management is loaded. Cameleer always has management,
so by default it keeps route and context counters and makes per-step timing opt-in
(ManagementStatisticsLevel::Default, or camel.main.jmxManagementStatisticsLevel=Default).
How is it verified?
- 2,800+ hermetic tests against embedded servers;
- the official MCP conformance suite: 39/39 (2025-11-25) and 26/26 (2025-06-18);
- live suites against real PostgreSQL, Redis, RabbitMQ, ActiveMQ, Mosquitto, vsftpd, Postfix/Dovecot and nginx;
- official clients: librdkafka, pymongo, the DataStax driver, boto3, the Azure SDK, gcloud and grpcio;
- emulators: moto, Azurite, fake-gcs-server and FerretDB.
See docs/INTEROP.md.
Crates
| crate | contents |
|---|---|
cameleer-core |
CamelContext, Exchange/Message/Value, routes and the Rust DSL, EIPs, error handling, languages, data formats, core components |
cameleer-http |
HTTP/1.1 server and client, platform-http, http, REST DSL with OpenAPI, netty TCP/UDP |
cameleer-yaml |
YAML parser, Camel YAML DSL, XML DSL, route templates |
cameleer-protocols |
ftp, smtp/pop3/imap, websocket, mllp/hl7, syslog (with embedded test servers) |
cameleer-tls |
from-scratch TLS 1.3/1.2, X.509, SslContextParameters (used by all network components) |
cameleer-kafka-mqtt |
kafka, paho / paho-mqtt5 (with embedded test brokers) |
cameleer-amqp |
spring-rabbitmq / rabbitmq (AMQP 0-9-1), stomp, jms / activemq / amqp-stomp (with embedded test brokers) |
cameleer-amqp10 |
AMQP 1.0 client (SASL, TLS, CBS), amqp (JMS over AMQP 1.0), azure-servicebus, azure-eventhubs |
cameleer-sql |
embedded SQL engine, PostgreSQL client, sql / jdbc components, JDBC repositories |
cameleer-cloud |
AWS (incl. Bedrock), Azure (incl. OpenAI), Google Cloud (incl. Vertex AI), with verifying emulators |
cameleer-ssh |
SSH-2 + SFTP: sftp and ssh components |
cameleer-grpc |
HTTP/2 + HPACK, protobuf, grpc component and protobuf data format |
cameleer-datastores |
spring-redis, mongodb, elasticsearch/opensearch, cql (Cassandra), couchdb (with embedded test servers) |
cameleer-xml |
XML 1.0 parser + DOM, XPath 1.0, XSLT 1.0, XML Schema validation, xj, xmlsecurity-sign/-verify |
cameleer-ai |
ai-tool, ai-resource, ai-prompt, the tool registry and reliability envelope, the MCP server, client and gateway, the mcp component |
cameleer-saas |
openai/llm, anthropic, gemini, slack, telegram, github, twilio, jira, webhook, graphql, rss/atom (with embedded mock servers) |
cameleer-main |
Main runner (application.properties, route discovery) and the cameleer CLI; each family crate above is one of its cargo features |
cameleer-bench |
benchmark harness, sampling profiler and HTTP load generator |
Internals: ARCHITECTURE.md.
Build, test and check the numbers yourself
cargo build --release
cargo test --workspace # hermetic: every network component runs against embedded servers
scripts/bench.sh # Cameleer vs Apache Camel (Linux or Git Bash; .\scripts\bench.ps1 on Windows)
The live interop suites run against real servers and are opt-in:
sudo scripts/live-interop.sh all
CAMEL_LIVE_INTEROP=1 cargo test --workspace live_
Contributing, security and citing
Contributions are welcome: see CONTRIBUTING.md and the Code of Conduct. Report vulnerabilities privately as described in SECURITY.md. To cite Cameleer, use the "Cite this repository" button (CITATION.cff).
License and credits
Cameleer is licensed under the Apache License 2.0; see NOTICE.
It exists because of Apache Camel (github.com/apache/camel) and its community, whose design, documentation and Enterprise Integration Patterns catalogue it follows. Apache, Apache Camel and Camel are trademarks of the Apache Software Foundation; Cameleer is not affiliated with or endorsed by the ASF.