ZAP
The wire format is the data structure
ZAP is the Zero-copy Application Protocol — binary RPC between services, with a sixteen-byte header and a data segment laid out so a reader walks it where it landed. There is no parse step to skip, because there is nothing to parse. MCP, A2A and ACP all ride on it unchanged, so you keep the protocol your stack already speaks.
Why bother
JSON over HTTP is fine until a hundred agents are calling the same tools. Then the cost is the copies, and the fix is to stop making them.
One tool server, not one per agent
Running an MCP server beside every agent duplicates the process, the schema and the idle memory as many times as you have agents. Put the servers behind one endpoint and the agents share them.
The work you removed cannot be slow
Fewer processes to schedule and no text to turn into objects on either side of a call. That is where the time goes at scale, and the way to get it back is not to do it.
It carries the protocol you already use
MCP, A2A and ACP layer on ZAP without changing what your code says. ZAP is underneath them, not instead of them.
The message is already the object
Structs, lists, text and bytes are laid out on the wire in the shape a reader wants them, eight-byte aligned. Reading a field is a pointer and an offset into the buffer that arrived.
Nothing to collect afterwards
A reader that walks the buffer in place allocates nothing per message, so there is no garbage to collect and no pause to tune away later.
Existing MCP servers, wrapped
Point the daemon at the MCP servers you already run — over stdio, over HTTP, over a Unix socket — and it presents their tools as one federated schema. Agents connect once and see everything.
Keys arrive instead of being fetched
ZAP carries its own key distribution: a service subscribes once and receives the snapshot, then rotations and revocations as they happen. Nothing polls a JWKS endpoint, and a revoked key stops working when it is revoked rather than when a cache expires.
Three implementations, one wire
Go, Rust and TypeScript, held wire-compatible against a single schema file. The schema is the contract, and an incompatible change bumps its identifier rather than hoping nobody notices.
Four lines and it is running
One daemon in front of the servers you already have. Agents hold a single connection to it.
zapd presents the tools and resources of every backend as one schema, whether the backend speaks MCP or ZAP.
How it is put together
Many agents on one side, many tool servers on the other, one address in the middle.
┌─────────────────────────────────────────────────────────────────┐ │ Agent Swarm │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Agent 1 │ │ Agent 2 │ │ Agent 3 │ │ Agent N │ ... │ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ │ └────────────┴─────┬──────┴────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────┐ │ │ │ ZAP Gateway │ │ │ │ zap://localhost:9999│ │ │ │ │ │ │ │ • Schema Federation │ │ │ │ • Request Routing │ │ │ │ • Capability Control │ │ │ └───────────┬───────────┘ │ │ │ │ │ ┌──────────────────┼──────────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │MCP Srv │ │ZAP Srv │ │MCP Srv │ │ │ │ GitHub │ │ Native │ │ Slack │ ... │ │ └─────────┘ └─────────┘ └─────────┘ │ └─────────────────────────────────────────────────────────────────┘
Point one agent at it
Start the daemon, add the MCP servers you already run, change one address in your agent.
Nothing else about your setup has to move.
What ZAP saves depends on your workload, your payload size and your topology. The claim here is about mechanism, not about a number: a reader that walks the buffer in place does no parsing and no allocation, and shared backends run one process where per-agent sidecars run many. Measure it on your own traffic — we have not published a benchmark and will not quote one we cannot show you.