Skip to content

Message Protocol

Every interaction between an agent and its environment — tool calls, memory operations, skill execution, multi-agent delegation — travels over a single, typed, versioned wire format. This NDJSON protocol is the contract that decouples agents from backends: as long as both sides speak A2E messages, the implementations can evolve independently.

Wire Format

A2E uses NDJSON (newline-delimited JSON) as its wire format. Each line is a self-contained JSON object representing one message. Compact JSON encoding (no extra whitespace) is used for efficiency.

{"a2e":"1.0","id":"a1b2c3","type":"tool/call/req","ts":1716123456.789,...}\n
{"a2e":"1.0","id":"d4e5f6","type":"tool/call/resp","ts":1716123457.012,...}\n

A2EMessage Base

Every A2E message inherits from A2EMessage (Pydantic BaseModel):

FieldTypeDescription
typestrMessage type identifier (e.g. "tool/call/req")
idstrUUID hex, auto-generated per message
versionstrProtocol version, always "1.0"
tsfloatUnix epoch timestamp

Methods: to_dict() (serialize), new_id() (regenerate UUID).

Protocol Versioning

Protocol version is "1.0", described as a strict superset of SCP 1.0 (Skill Call Protocol). Unknown message types degrade gracefully — the base type map covers SCP-compatible handshake/ping/pong/shutdown/error, and any unrecognized type falls back to a generic A2EMessage.

Message Lifecycle

Correlation

RPC requests are correlated by req_id — the client generates a UUID, the server copies it into the response. The client maintains a dict of req_id -> queue.Queue, so multiple concurrent RPCs can be in flight. Events reference their parent request via req_id.

Event Streaming

A2EEvent (type: invoke/event) provides streaming mid-operation updates:

FieldTypeDescription
kindEventKindprogress, artifact, log, or status
req_idstrCorrelates to the originating request
datadictPayload (progress %, artifact content, log text, status message)
seqintMonotonic sequence number within the request

Events are delivered before the final response, enabling progressive UI updates.

Error Handling

A2EError is returned when a message cannot be processed:

FieldTypeDescription
req_idstrThe failed request's ID
codeA2EErrorCodeMachine-readable error code
messagestrHuman-readable error description
detaildictAdditional structured context
retryableboolWhether the client should retry
capability_namestrWhich capability namespace failed

See Error Codes for the full list.

Type Registry

Both client and server maintain a type_registry mapping type strings to Pydantic model classes. The base map (A2E_BASE_TYPE_MAP) covers core types:

Type StringModel Class
handshake/reqHandshakeRequest
handshake/respHandshakeResponse
invoke/eventA2EEvent
pingPing
pongPong
shutdownShutdown
errorA2EError

Plugins extend this at startup by registering their own TYPE_MAP entries (e.g. tool/call/req -> ToolCallRequest).

A2E Protocol v1.0 — Released under the MIT License.