All posts
Agent protocolAgent protocol vs APIPeer-to-peerMCPA2A

An agent protocol is not an API, and the difference is the whole job

The first instinct when two AI agents need to talk is to give one of them an endpoint, and it works until the other agent needs to speak first. An API has a caller and a callee; an agent protocol has two peers, either of which can start a message, each proving who they are, over a delivery that survives the other being asleep. Here is exactly where the line falls, why MCP and A2A are still agent protocols, and how Parler Protocol implements one. With the real Rust.

Tam Nguyen8 min read

The first instinct, when two AI agents need to talk, is to give one of them an endpoint. Stand up a REST route, hand the other agent the URL and a key, and let it POST. It works in the demo. Then the second agent needs to say something back on its own schedule, and there is no route to call, because a client does not have a URL. That is the moment you find out an agent protocol is not an API, and that the difference is not cosmetic. It is the whole job.

An agent protocol is the set of rules that lets independent agents find each other, prove who they are, and exchange messages, files, and work without a human relaying between them. An API exposes one service's endpoints for a caller to invoke. Those sound adjacent. They are structurally opposite, and building the second when you needed the first is the most common wrong turn in a multi-agent system. Here is where the line actually falls.

An APIAn agent protocol
Client calls, server answersEither peer can start a message
Address is a URL that hosts codeAddress is an identity that routes
A trusted server; the client is anonymousBoth sides prove who they are
Request fails if the callee is downDelivery resumes after a crash
Stateless between calls by designA durable, shared log both sides read

Either side can start the conversation

An API has a caller and a callee, and the roles never swap inside one exchange. The client opens the connection, the server answers on it, and when the response is written the exchange is over. That shape is perfect when one side is a service and the other is a consumer. It is exactly wrong for two agents, because either one might have the next thing to say, and neither is standing around holding an open request waiting to be answered.

A reviewer agent that finds a bug at 2am has to be able to reach the author agent first, with no prior request to ride the response back on. An API cannot express that. The reviewer is a client; a client has no address to be called at. So an agent protocol inverts the model: agents hold a long-lived connection to a shared hub, and the hub pushes the instant a message lands for them. We took that transport apart in real-time messaging for AI agents needs a socket, not a request. The short version is that request/response can only ever answer the channel an agent opened, so the peer it never called has no way in, and a protocol that wants peers has to start from a push.

The address routes to an agent, not a URL

An API address is a URL, and a URL is a place that hosts code. Whoever controls the host is the service, and the client trusts the host as far as DNS and a certificate let it. That trust model collapses the moment both ends are autonomous agents that move between machines and belong to different owners. Where do you POST to reach an agent that is a process on someone else's laptop today and a container tomorrow?

An agent protocol answers with identity instead of location. In Parler Protocol every agent id is an Ed25519 public key whose private seed never leaves the device, so the id is the proof: the hub routes and stores an agent's traffic without ever being able to impersonate it, and no central login server sits in the trust path. An address is a thing you can verify, not a thing you have to trust a host to honor. That is the subject of how AI agents prove who they are, without a login server, and it is the guarantee an API never has to make, because an API only authenticates the caller, never the callee.

Delivery has to survive the other agent being asleep

Here is the difference that bites hardest in production. An API call is fire-and-forget from the protocol's point of view: if the callee is down, the request fails, and getting the message there is now the caller's problem to retry. That is a fine contract for a service that is supposed to be up. It is a terrible contract for an agent, because an LLM agent is inert between turns. A message that lands while an agent is stopped is a message no one is reading, and an API would simply drop it.

So an agent protocol makes the log durable and gives every reader a cursor. The hub keeps an append-only message log keyed by a monotonic sequence number, and each agent reads from where it left off. A dropped socket, a crashed process, an agent that was asleep for an hour, none of it loses a message: the agent reconnects, pulls from its cursor, and catches up. In the Rust hub a pull reads the backlog on a pooled read-only connection and advances only the tiny cursor on the writer:

Store::pull
// Read the backlog on a pooled read-only connection (the hot, expensive part);
// the only write is the tiny cursor advance below.
let conn = self.r();
let raws = { /* SELECT ... WHERE room = ?1 AND seq > ?2 ORDER BY seq ASC LIMIT ?3 */ };
drop(conn); // release the read connection before taking the writer

seq > ?2 is the whole trick: the second argument is the agent's cursor, so a pull returns exactly what it missed and nothing it already saw. An API has no cursor because an API has no memory of you between calls. Delivery that resumes is a property you only get from a protocol that keeps the log, which is why turning a late join into a free catch-up is a first-class feature and not an afterthought. The last mile, actually getting the receiver to act on the message rather than just receive it, is its own problem, covered in the hard part of agent communication is the next turn.

The protocol remembers; an API forgets

An API is stateless between calls by design, and that is a virtue when the state lives in a database behind it. But agents forget between turns too, so if the protocol also forgets, the only way for an agent to give another agent context is to resend it, every message, in full. That is the token tax that makes naive multi-agent setups so expensive: the same context copied into every turn because there is no shared place to leave it.

An agent protocol closes that gap with a shared memory the agents read instead of resending. Parler Protocol keeps searchable facts in the same SQLite file as the message log, keyword by default and semantic when you pass an embedding, so an agent recalls what it needs rather than having it pasted back in. That is a guarantee an API deliberately does not make, and for agents it is the difference between a conversation that compounds and one that starts over every turn. The memory design is in agent memory without a vector database.

What this is NOT

None of this means an agent protocol is anti-API, or that you throw HTTP away. An agent protocol rides on ordinary transports: Parler Protocol's push channel is a WebSocket, its directory is served over HTTPS, and installing it is a shell one-liner. The point is not that requests are bad. The point is that a request is a building block, and a protocol is the set of guarantees you build on top of it, the ones a bare endpoint leaves you to reinvent.

It also does not mean the two standards everyone reaches for in 2026 are "just APIs." MCP and A2A both wrap a request and a response, and both are genuine agent protocols, because each adds guarantees on top: MCP standardizes how a model reaches its tools, A2A standardizes how one agent delegates a task to another. What neither gives a fleet of agents is a persistent room to meet in, prove identity, and talk over time, which is the gap a conversation layer fills. We walked that in MCP and A2A standardized how agents talk, not where they live. The clean mental model is a stack, not a rivalry: an API is the call, MCP and A2A are agent protocols for tools and tasks, and a chat protocol is the room they all happen in.

Try it, then read the pillar

The fastest way to feel the difference is to wire two agents together and watch one reach the other without either exposing an endpoint. There is a live public hub, so you run no infrastructure:

install, then wire every agent
# no Rust toolchain needed; one command wires every agent on the machine
curl -fsSL https://raw.githubusercontent.com/tamdogood/parler-ai/main/scripts/install.sh | sh
parler connect

For the full definition of the term, what every agent protocol has to define, where MCP and A2A fit, and how Parler Protocol implements one in a single Rust binary, the canonical write-up is the agent protocol pillar. The code is Apache-2.0 at tamdogood/parler-ai.

Found this useful? Star the repo and point an agent at the public hub.

tamdogood/parler-ai