Zilla: A Multi-Protocol Gateway That Puts Kafka, MQTT, HTTP and MCP Behind One Config File
🦎 A lightweight, multi-protocol gateway for event-driven applications and AI agents. Expose and govern Kafka, MQTT, APIs, and MCP through one high-performance engine with shared routing, security, schema, and observability.
At a glance
- What is it?
- Aklivity's Zilla is a stateless Java gateway that exposes Kafka and MQTT over HTTP, SSE, gRPC, WebSocket and MCP, and federates MCP servers and APIs behind one endpoint. The pitch is real; the licence file is not, and that is the first thing to check.
- Who is it for?
- Adopt Zilla if you already run Kafka or MQTT and need browser, device or agent clients to reach it without hand-written bridges, and if you are willing to read the licence file before anything ships. Do not adopt it if you need a stable 1.x line with no 2.x migration, or if your team cannot operate a JVM gateway.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The protocol gap Zilla is built to close
Browsers do not speak Kafka. The README says this outright, and it is the shortest accurate summary of the problem. An IoT fleet may publish over MQTT while the system of record consumes Kafka. An AI agent may need capabilities spread across MCP servers, HTTP APIs and event streams, each with its own endpoint, credential, schema and telemetry model. The usual answer is a pile of custom bridges: one service translating REST to Kafka, another wrapping each MCP provider, a third handling token exchange, and instrumentation bolted on afterwards in four different formats. Zilla's claim is that these become declarative routes in a single zilla.yaml, sharing one routing, identity, authorization, schema and telemetry layer. The intended user is a platform or integration engineer who already has Kafka or MQTT running and now has to open it to clients that cannot speak those protocols natively. It is not aimed at someone who just needs a plain HTTP reverse proxy; the protocol translation is the whole point.
What the streaming engine actually does
The architecture section lists four concrete mechanisms. Code-generated flyweights give typed access over encoded buffers, which avoids deserializing a message into objects just to read a header. Each connection stays assigned to one worker for its lifetime, so there is no cross-thread handoff per message. Bindings exchange back-pressured stream frames through shared memory rather than copying payloads between stages. Cache-enabled Kafka routes can fetch once and serve many downstream consumers, which matters when several SSE or WebSocket clients subscribe to the same topic. The README describes the engine as designed to minimize allocation, copying and cross-thread coordination, and notes that Zilla is stateless with shared state externalized when needed. It also states that Zilla is designed for scalability with minimal latency and throughput overhead when proxying protocols, but no numbers are given in the material available here, so treat that as a design goal rather than a measured result. One structural consequence of the worker-affinity rule is worth naming: scaling is by adding gateway instances, not by tuning a thread pool inside one.
MCP federation and the toolkit__capability namespace
The MCP side is the newer half and the more interesting one. Zilla connects an agent-facing MCP endpoint to existing MCP servers, HTTP APIs, OpenAPI-described services and Kafka. Capabilities are namespaced as <toolkit>__<capability>, with the README's examples being github__create_pr, payments__refund and kafka__produce_message. The toolkit prefix selects the route and prevents two providers from colliding on a tool name. Zilla aggregates configured providers into one catalog, authenticates the agent once at the gateway, filters the capability listing by authorization, and can forward or exchange credentials for upstream services. For large catalogs there is an eager versus cold tool split, so an agent loads only what it needs, plus relay of MCP elicitation and schema guardrails over JSON, Avro and Protobuf. The design decision worth flagging is where state lives: MCP listing and authorization state can be externalized, and Zilla Plus adds shared Redis or Hazelcast stores. That implies the Community edition's multi-replica story is thinner than the single-replica one, and anyone planning horizontal scaling should read the Plus documentation before assuming parity.
Getting a route running with Docker Compose
The prerequisite is Docker Compose. The README's path is to clone the repository, change into zilla/examples, and bring up one of the bundled example directories. For REST over Kafka that is docker compose --project-directory http.kafka.crud up -d, after which a POST to http://localhost:7114/items with a JSON body containing name and price writes through to Kafka, and a GET on the same path reads back. Kafka UI is exposed at http://localhost:8080/ui/clusters/local/all-topics for inspecting the records. The MCP path is docker compose --project-directory mcp.proxy up -d, then pointing a Streamable HTTP MCP client at http://localhost:7114/mcp. MCP metrics are scraped from http://localhost:7190/metrics. Ports 7114 and 7190 are the two to remember. For a non-example deployment, the image is ghcr.io/aklivity/zilla:latest and the repository also documents a docker pull for it. Note that the README text supplied here is truncated mid-command in the Install section, so the full docker run invocation is not reproduced; check the docs site for the complete form rather than guessing at volume mounts.
Where Zilla is the wrong tool
Two limitations are visible in the material itself. First, the licence. The repository reports NOASSERTION, which means GitHub could not map the licence file to a known identifier. The README splits the product into Zilla Community, which includes the core Event Gateway and MCP Gateway, and Zilla Plus, which adds advanced OAuth grants, distributed stores, secure Kafka access, virtual clusters and commercial support. Which of those features are open source, and under what terms, is not stated in the supplied material. That is not a footnote; it determines whether you can ship the gateway at all. Second, the version story. The repository carries both a 2.4.0 release and a 1.3.2 release within days of each other, and the README says Zilla is evolving into a unified Event and AI Gateway with Zilla 2.0 extending the engine with native MCP. Running two release lines means two configuration references, and the README points at a 2.x configuration reference specifically. If you pin 1.x for stability, you are reading documentation for a different major version. Beyond that, Zilla is a JVM gateway: you inherit JVM operations, memory tuning and upgrade cadence, which is a real cost for a team that otherwise runs Go or Rust services.
Zilla against a hand-written bridge
The honest alternative is not another gateway. It is the code you would write anyway: a small service that consumes from Kafka and serves SSE or WebSocket to browsers, plus a separate wrapper per MCP provider. That approach is easier to reason about for one protocol pair and needs no new runtime. The difference in approach is where the work sits. A hand-written bridge encodes routing, auth, schema validation and metrics in application code, and you repeat that for every protocol pair. Zilla moves those into declarative routes in zilla.yaml, so the second and third protocol pair cost configuration rather than a new service. The trade is that you now depend on Zilla's binding set and its release cadence instead of your own code. If you have exactly one bridge and no plans for a second, the hand-written service is the smaller commitment. If you are staring at four clients and three protocols, the declarative route model is the argument for Zilla.
Maintenance, releases and the licence question
The repository is not archived and the last push is recent relative to the 2.4.0 release, so the project is actively developed. That activity is also the maintenance cost: three releases are listed within roughly three weeks, spanning two major lines, and the README explicitly frames a migration toward a unified Event and AI Gateway. Plan for configuration churn between 1.x and 2.x rather than treating an upgrade as a patch. On licensing, the only responsible statement is that NOASSERTION means the terms could not be identified automatically and must be read directly from the repository before adoption. Nothing in the supplied material states which licence governs the Community edition, and this is not legal advice. If your organisation has a licence review process, this repository is exactly the case that process exists for, and the Zilla Plus commercial tier adds a second question about which features you would need to buy.
Editorial conclusion
Adopt Zilla if you already run Kafka or MQTT and need browser, device or agent clients to reach it without hand-written bridges, and if you are willing to read the licence file before anything ships. Do not adopt it if you need a stable 1.x line with no 2.x migration, or if your team cannot operate a JVM gateway. Verify first: the actual licence terms behind the NOASSERTION label, which MCP features belong to Community versus Zilla Plus, and whether the release you pin matches the 1.x or 2.x configuration reference you are reading.
Community notes