The MQTT Transport for A2A
This profile defines a broker-neutral A2A over MQTT topic model for discovery and messaging. It standardizes retained Agent Card discovery, request/reply mappings, request-scoped security metadata, and interoperable client behavior.
A2A base specification: This profile extends the A2A specification v1.0.0. All normative A2A data structures, method semantics, and error codes are as defined in that release unless explicitly overridden by this profile.
Profile Scope
- This profile specifies MQTT v5 topic conventions and message-property mappings for A2A v1.0.0 traffic.
- This profile defines interoperable behavior for requester clients and responder clients.
- Broker-internal implementation details remain implementation-specific unless explicitly stated.
Terminology
The key words MUST, SHOULD, and MAY are to be interpreted as described in RFC 2119.
Additional terms used in this profile:
requester: client agent that publishes A2A requestsresponder: client agent that consumes requests and publishes repliesdiscovery subscriber: client that subscribes to discovery topicspool: optional unit-scoped shared request endpoint consumed via MQTT shared subscriptions
Topic Model
Discovery Topic
Agent Cards MUST be published as retained messages at:
$a2a/v1/discovery/{org_id}/{unit_id}/{agent_id}Direct Interaction Topics
Interaction topics SHOULD use:
$a2a/v1/{method}/{org_id}/{unit_id}/{agent_id}Where {method} is typically request, reply, or event.
Optional Pool Request Topic
Shared pool dispatch uses:
$a2a/v1/request/{org_id}/{unit_id}/pool/{pool_id}Identifier Format
- Identifiers used in this profile (
org_id,unit_id,agent_id,pool_id, andgroup_id) MUST match:^[A-Za-z0-9_.-]+$
Client Session Requirements
- Clients implementing this profile MUST use MQTT v5.
- Requesters MUST subscribe to the intended reply topic before publishing requests that use that topic as MQTT
Response Topic. - Clients MUST set MQTT
Client IDin the format{org_id}/{unit_id}/{agent_id}. - Requesters SHOULD use a reply topic suffix with high collision resistance (
reply_suffix) so concurrent requesters do not overlap reply streams. - Clients SHOULD use reconnect behavior that preserves subscriptions/session state where broker policy allows.
- Connections carrying bearer tokens MUST use TLS.
Discovery Interoperability
- Agent Cards MAY be discovered via HTTP well-known endpoints defined by core A2A conventions.
- For MQTT-compliant agents, publishing retained Agent Cards to
$a2a/v1/discovery/{org_id}/{unit_id}/{agent_id}is RECOMMENDED. - A client MAY discover a card via HTTP and then choose MQTT by selecting an MQTT-capable entry from
supportedInterfaces.
Discovery Publisher Behavior
- Agents register by publishing retained Agent Cards to discovery topics and SHOULD use MQTT QoS 1.
- To unregister, agents SHOULD clear retained discovery state using the broker-supported retained-delete mechanism for the same topic.
- Agents updating cards SHOULD republish the full card payload for that topic.
Discovery Subscriber Behavior
- Discovery subscribers SHOULD subscribe using scoped filters such as:
$a2a/v1/discovery/{org_id}/{unit_id}/+
- Subscribers MUST process retained discovery messages as current registration state.
- Subscribers SHOULD treat subsequent retained updates on the same discovery topic as replacement state for that agent.
- Subscribers MAY combine HTTP-discovered cards and MQTT-discovered cards, but topic-scoped MQTT cards are authoritative for MQTT routing.
- Subscribers SHOULD process the MQTT User Property
a2a-statuson received Agent Card messages to determine agent liveness. See Presence and Liveness.
Presence and Liveness
Agent Cards are published as retained messages and persist on the broker after an agent disconnects. This section defines how agents signal operational status using MQTT User Properties on Agent Card publications, so that subscribers can distinguish a reachable agent from a stale card.
Liveness via Discovery Topic User Properties
Agents signal liveness by attaching MQTT v5 User Properties to their retained Agent Card publications on the discovery topic. Subscribers receive capability metadata and operational status in a single retained message.
- Agents SHOULD include MQTT User Property
a2a-statuswith valueonlinewhen publishing their retained Agent Card. - Agents SHOULD include MQTT User Property
a2a-status-sourcewith valueagenton Agent Card publications to distinguish agent-published status from broker-managed status.
Last Will and Testament (LWT) Configuration
- Agents SHOULD configure an MQTT Last Will and Testament (LWT) at connection time:
- Will Topic:
$a2a/v1/discovery/{org_id}/{unit_id}/{agent_id}(same as the agent's discovery topic) - Will Payload: the Agent Card JSON payload
- Will Retain:
true - Will QoS:
1 - Will User Properties:
a2a-status=offline,a2a-status-source=lwt
- Will Topic:
- On ungraceful disconnect (crash, network loss), the broker publishes the LWT, replacing the retained card with an offline-annotated version. Subscribers are notified automatically.
- On graceful disconnect, agents SHOULD republish their retained Agent Card with User Properties
a2a-status=offlineanda2a-status-source=agentbefore disconnecting, providing immediate notification without waiting for the broker's keep-alive timeout. - The LWT payload is fixed at CONNECT time. If an agent updates its card during a session, the LWT will carry the previous card version. The
a2a-status=offlinesignal remains valid; subscribers receive the updated card when the agent reconnects and republishes. - This profile relies on MQTT keep-alive for connection-level liveness detection. The broker declares a client dead after 1.5× the negotiated Keep Alive interval with no PINGREQ, which triggers the LWT. Application-level heartbeat mechanisms (for example, Message Expiry Interval on retained cards) are not specified in this version; they may be defined in a future revision if MQTT keep-alive proves insufficient.
Presence Subscriber Behavior
- Subscribers SHOULD process the MQTT User Property
a2a-statuson received Agent Card messages. A value ofonlineindicates the agent was reachable when the card was published;offlineindicates a disconnect was detected. - Subscribers MUST treat
a2a-statusas advisory and MUST NOT use it as a replacement for request/reply error handling and retry behavior. - Subscribers SHOULD interpret the absence of a retained Agent Card (no message on the discovery topic) as the agent being unregistered or unavailable.
- A subscriber that needs definitive liveness confirmation for a specific agent before committing to a costly operation MAY send a lightweight request (for example
GetTaskwith a non-existentTask.id) and use the reply timeout as a health signal.
Request/Reply Mapping (MQTT v5)
- Requesters SHOULD publish requests to
$a2a/v1/request/{org_id}/{unit_id}/{agent_id}using MQTT QoS 1. - Requesters MUST set MQTT 5
Response TopicandCorrelation Data. - Responders MUST publish replies to the provided
Response Topicand MUST echoCorrelation Data. Replies SHOULD be published using MQTT QoS 1. - Recommended reply topic pattern:
$a2a/v1/reply/{org_id}/{unit_id}/{agent_id}/{reply_suffix}. - MQTT
Correlation Datais transport-level request/reply correlation and MUST NOT be used as an A2A task identifier. - For new tasks, requesters MUST generate a
Task.idas a UUIDv4 value and include it in the request payload (Message.task_id).MQTT binding divergence: The core A2A specification states that
Task.idis generated by the server (responder). This binding intentionally reverses that: the requester generatesTask.idbefore sending the first request. This is necessary over MQTT because there is no synchronous response — the requester must be able to retry the initial publish (with a newCorrelation Data) without the risk of the responder creating a duplicate task. - Responders MUST use the requester-provided
Task.id(Message.task_id) to track task state and MUST echo it in all replies and stream items for that task. - Requesters MUST use the same
Task.idfor all subsequent task operations (for exampleGetTask,CancelTask, and subscriptions). - Requesters MAY include a
Task.context_idin the request payload (Message.context_id) to group related tasks into a conversational session. See Multi-Turn Conversation Patterns.
Informative: Why Both Correlation Data and Task.id
This section is informative (non-normative).
MQTT Correlation Data and A2A Task.id serve complementary but distinct roles:
| Identifier | Scope | Generated by | Lifetime |
|---|---|---|---|
Correlation Data | Single MQTT request/reply exchange | Requester (per publish) | One round-trip |
Task.id (Message.task_id) | Logical task / conversation session | Requester (UUIDv4, on task creation) | Entire task lifecycle |
Both are necessary because:
- Separate lifetimes.
Task.idis a stable UUIDv4 generated by the requester at task creation and reused for the entire task lifecycle.Correlation Datais ephemeral — a new value is generated for each individual MQTT publish, including retries. - Multiple in-flight requests per task. Over one task session a requester may send several concurrent requests (for example
SendMessagefollowed byGetTask). Each needs its ownCorrelation Dataso replies can be demultiplexed independently. - MQTT does not guarantee cross-topic ordering. Unlike HTTP pipelining, where intermediaries preserve message order within a connection, MQTT message delivery order is non-deterministic when messages traverse different topic suffixes.
Correlation Datalets requesters match replies regardless of arrival order. - Retry deduplication. Because
Task.idis requester-generated and present from the first request, responders can use it to deduplicate retried task-creating requests (where the first attempt was processed but the reply was lost).
Typical lifecycle:
- Requester generates a UUIDv4
Task.idand publishes the initialSendMessagerequest (SendMessageRequest) with bothMessage.task_id(in the payload) andCorrelation Data(MQTT property). - Responder accepts the task, persists state keyed by
Task.id, and replies (echoingCorrelation Data). - Requester uses the same
Task.idfor all subsequent task operations, generating freshCorrelation Datafor each new publish.
See also Multi-Turn Conversation Patterns for the third identifier tier —
Task.context_id.
Requester Behavior (Interop)
- Requesters MUST keep an in-flight map keyed by MQTT
Correlation Datafor active requests. Correlation Datavalues MUST be unique across concurrently in-flight requests from that requester on the same reply topic.- Requesters SHOULD publish requests with QoS 1.
- Requesters MUST include request-scoped auth properties (for example
a2a-authorization) when required by the target responder. - On reply, requesters MUST match
Correlation Data; replies with unknown or missing correlation MUST be treated as protocol errors and ignored. - For pooled requests, requesters MUST validate presence of
a2a-responder-agent-idon pooled responses; missing property MUST be treated as a protocol error. - For pooled requests that create or reference a task, requesters MUST persist (
Task.id,a2a-responder-agent-id). - Follow-up task operations (
GetTask,CancelTask, subsequent stream/task interactions) SHOULD be routed to direct responder topics once responder identity is known. - Requesters MUST implement the retry and timeout behavior defined in
Requester Retry and Timeout Profile.
Responder Behavior (Interop)
- Responders MUST subscribe to their direct request topic and MAY additionally subscribe to pool request topics when operating in shared dispatch mode.
- If a request omits
Response TopicorCorrelation Data, responders SHOULD reject it as invalid protocol input; if no reply path is available, responders MAY drop. - Responders MUST validate request payloads and return protocol/application errors on the provided reply path when possible.
- For new tasks, responders MUST accept the requester-provided
Task.id(a UUIDv4 value) and use it to track task state. Responders MUST reject requests with missing or malformedTask.idas invalid protocol input. - Responders MUST echo
Correlation Dataunchanged on all replies and stream items for a request. - Replies and stream items SHOULD be sent with QoS 1.
- Responders processing pooled requests MUST include User Property
a2a-responder-agent-idon responses. - Responders MUST NOT echo bearer tokens in payloads or MQTT properties.
Optional Task Handover
- A card-owning agent MAY delegate an in-progress task to a different agent instance. This allows a single published Agent Card to front multiple dynamically spawned or specialized agent instances without requiring each instance to register its own card.
- To signal handover, the responding agent MUST include MQTT User Property
a2a-responder-agent-idon the reply, with the value set to the delegated agent'sagent_id. This reuses the same property defined for shared pool dispatch. - When a requester receives a reply containing
a2a-responder-agent-id, it SHOULD direct all subsequent operations for thatTask.idto the indicated agent's direct request topic. This behavior is the same regardless of whether the property originates from pool dispatch or task handover. - The property MAY appear on any reply or stream message for a given task. Requesters MUST honor the most recently received
a2a-responder-agent-idfor a givenTask.id. - Handover does not alter the task's identity;
Task.idremains the same across the handover. - If the card-owning agent does not hand over, it is responsible for correctly routing incoming messages to its internal instances (for example by session or
Task.id). How an agent manages its internal instances is implementation-specific and out of scope.
Multi-Turn Conversation Patterns
This section defines how the A2A Task.context_id maps to the MQTT transport binding for conversational continuity across multiple tasks and interrupted-task flows.
A2A base specification alignment: This section maps the multi-turn conversation patterns defined in A2A specification v1.0.0 §3.4.3 to MQTT transport semantics.
Context Identifier Semantics
- A
Task.context_idlogically groups related tasks and messages into a single conversational session. - Requesters SHOULD generate a
Task.context_idas a UUIDv4 value and include it in the request payload (Message.context_id) when initiating a new conversation.MQTT binding note: Consistent with the requester-generated
Task.idmodel, requesters generateTask.context_idbefore sending. Requesters that do not includeTask.context_idare opting out of conversational continuity for that task. - If the request payload omits
Task.context_id, the responder MAY generate one and include it in the response task object. - Responders MUST preserve and echo the requester-provided
Task.context_idin all responses for tasks within that context. - If a responder receives a
Task.context_idwith no existing associated state, it MUST treat it as the start of a new conversational context. - Responders MUST reject requests where the incoming
Task.context_iddiffers from theTask.context_idalready associated with the sameTask.idin the responder's stored task state. The error MUST use JSON-RPC error code-32602(invalid params). - Requesters MAY include MQTT User Property
a2a-context-idwith theTask.context_idvalue on request publications for transport-level visibility. The JSON payloadMessage.context_idremains authoritative; if both are present, they MUST match. - All tasks sharing a
Task.context_idconstitute a single conversational session. Responders MAY maintain internal state or LLM context across interactions within the same context. - Responders MAY implement context expiration policies; such policies SHOULD be documented in the Agent Card or agent metadata.
Interaction Patterns
Multi-turn conversations combine three identifier tiers:
| Identifier | Scope | Generated by | Lifetime |
|---|---|---|---|
Task.context_id (Message.context_id) | Conversation | Requester (UUIDv4) | Multiple tasks |
Task.id (Message.task_id) | Task | Requester (UUIDv4) | Entire task lifecycle |
Correlation Data | Request/reply exchange | Requester (per publish) | One round-trip |
- New conversation. Requester generates a new
Task.context_id(UUIDv4) and a newTask.id(UUIDv4), publishesSendMessagewith freshCorrelation Data. - New turn in existing conversation. Requester generates a new
Task.idbut reuses the existingTask.context_id, publishes with freshCorrelation Data. Responders MAY leverage prior task history within the same context to inform processing. - Continue interrupted task. When a responder transitions a task to
input-requiredorauth-required, the requester publishes a newSendMessagewith the sameTask.idandTask.context_idand freshCorrelation Data. The responder resumes processing on the new correlation. See Streaming Reply Mapping for stream-final semantics of interrupted states. - Retry. Requester reuses the same
Task.idandTask.context_idwith newCorrelation Data, as defined in Requester Retry and Timeout Profile.
Requester Retry and Timeout Profile
- This section defines the baseline retry/timeout behavior for requester interoperability and is part of Core conformance.
- Requesters MUST implement these defaults (configurable by deployment policy):
reply_first_timeout_ms:15000stream_idle_timeout_ms:30000max_attempts:3total attempts (initial attempt plus up to two retries)retry_backoff_ms: exponential (1000,2000,4000) with jitter of+/-20%
- For a single logical operation retried multiple times, requesters MUST generate new MQTT
Correlation Datafor each publish attempt and MUST keep the sameTask.idin the payload. - Responders MUST use
Task.idto deduplicate retried requests. If a responder has already created state for a givenTask.id, it MUST return the existing task state rather than creating a duplicate. - Requesters MUST stop retrying after the first valid correlated reply is received (success or error).
- Requesters MUST treat these conditions as retry-eligible until
max_attemptsis reached:- publish not accepted by the MQTT client/broker path
- request timed out waiting for first correlated reply (
reply_first_timeout_ms)
- Once any correlated stream item is received, requesters MUST NOT retry the original request publish.
- If stream progress stalls longer than
stream_idle_timeout_msafter at least one stream item, requesters SHOULD recover using task follow-up (GetTask) with the knownTask.idinstead of republishing the original request. - For pooled requests:
- retries before responder selection MUST target the pool topic
- after responder identity is known (
a2a-responder-agent-id), follow-up operations and retries MUST target that responder's direct request topic
- Requesters MAY set MQTT Message Expiry Interval on request publications; if set, it SHOULD be greater than
reply_first_timeout_ms.
Optional Shared Subscription Dispatch
- This profile supports an optional unit-scoped shared dispatch mode so compatible responders (same contract/intent) can share request load while keeping standard A2A request/reply behavior.
- Canonical shared pool request topic:
$a2a/v1/request/{org_id}/{unit_id}/pool/{pool_id}
- Requesters MUST publish pooled tasks to the canonical non-shared pool request topic and MUST NOT publish directly to
$share/.... - Pool members MAY consume pooled requests via:
$share/{group_id}/$a2a/v1/request/{org_id}/{unit_id}/pool/{pool_id}
- All members of the same
{org_id}/{unit_id}/{pool_id}pool MUST use the samegroup_id. group_idSHOULD be deterministic and stable. Recommended base value:a2a.{org_id}.{unit_id}.{pool_id}
- If an implementation derives
group_idfrom external labels, it SHOULD replace characters outside[A-Za-z0-9._]with_before use. - Implementations MUST NOT use random per-instance values (for example UUIDs) as
group_id. - Implementations SHOULD enforce broker length limits for
group_id(recommended max64); if needed, truncate and append a short hash suffix. - A responder handling a pooled request MUST include MQTT User Property:
- key:
a2a-responder-agent-id - value: concrete responder
agent_id
- key:
- For pooled requests that create tasks, requesters SHOULD persist (
Task.id,a2a-responder-agent-id) and SHOULD route follow-up operations to the concrete responder direct request topic:$a2a/v1/request/{org_id}/{unit_id}/{agent_id}
- A designated agent in the unit MAY act as pool registrar and publish/update metadata describing
pool_id, membership, and the pool request topic. - How pool members coordinate membership, liveness, leader election, and failover is implementation-specific and out of scope for this profile.
- Shared dispatch is intentionally limited to
{org_id}/{unit_id}scope in this version because unit boundaries map to common tenancy/policy boundaries; cross-unit or org-global shared pools are not defined.
Streaming Reply Mapping (SendStreamingMessage)
- For streaming A2A operations, responders MUST publish each stream item as a discrete MQTT message to the request-provided
Response Topic. - Each stream message MUST echo the same MQTT 5
Correlation Dataas the originating request. - Stream payloads SHOULD use A2A stream update structures, including
TaskStatusUpdateEventandTaskArtifactUpdateEvent. - Stream updates SHOULD be published using MQTT QoS 1 so publishers can receive PUBACK reason codes (for example,
No matching subscribers). - For this MQTT binding, receipt of a
TaskStatusUpdateEvent.status.statevalue ofTASK_STATE_COMPLETED,TASK_STATE_FAILED,TASK_STATE_CANCELED, orTASK_STATE_REJECTEDMUST be treated as the end of that stream for the given correlation. - Requesters MUST treat that terminal status as stream completion for the correlated request.
- A
TaskStatusUpdateEventwithstatus.stateofinput-requiredorauth-requiredMUST also be treated as stream-final for the current correlation: the requester MUST clean up in-flight state for thatCorrelation Data. The task is not terminal — see Multi-Turn Conversation Patterns for continuation behavior. - If a requester does not receive terminal status within its stream timeout policy, it MAY issue follow-up task retrieval (
GetTask) usingTask.id. - This end-of-stream rule applies to reply-stream messages on the request/reply path, not to general-purpose
$a2a/v1/event/...publications.
Event Delivery
- Event messages published to
$a2a/v1/event/{org_id}/{unit_id}/{agent_id}MAY use MQTT QoS 0. - Event publications are outside request/reply correlation unless explicitly tied by application metadata.
QoS Guidance
- MQTT QoS 1 is the recommended default for discovery registration, request, and reply publications.
- Using QoS 1 allows publishers to receive MQTT v5 PUBACK responses that can carry broker reason codes, for example
No matching subscribers. - Brokers and clients MUST support QoS 1 on discovery, request, and reply paths for interoperability.
- Event publications MAY use QoS 0 when occasional loss is acceptable.
A2A User Property Naming
- MQTT User Properties defined by this binding MUST use the
a2a-prefix. - New binding-specific properties defined by implementations SHOULD also use the
a2a-prefix to avoid collisions.
Agent Card Requirements
- Card payloads SHOULD conform to the A2A Agent Card schema.
- Agent-provided transport metadata MAY be expressed via Agent extension fields.
- Extensions MUST NOT redefine core A2A semantics.
Security Metadata and Trust
- Agent Cards MAY include public key metadata (for example
jwksUri) via extension params. - Brokers MAY reject cards having an untrusted
jwksUri. - JWKS retrieval SHOULD use HTTPS with TLS certificate validation.
OAuth 2.0 and OIDC over MQTT User Properties
- OAuth 2.0/OIDC token acquisition is out-of-band for this binding and occurs between the requester and an authorization server.
- If the selected agent requires OAuth 2.0/OIDC, the requester MUST include an access token on each request message as an MQTT v5 User Property:
- key:
a2a-authorization - value:
Bearer <access_token>
- key:
- Broker connection authentication (for example username/password or mTLS) is independent of per-request OAuth authorization and MUST NOT be treated as a replacement for it.
- Responders MUST validate bearer token claims (including
exp,iss, andaud) and required scopes before processing the request. - Request messages carrying bearer tokens MUST be sent over TLS-secured MQTT transport.
- Implementations MUST NOT echo bearer tokens in reply/event payloads or MQTT properties.
- Requesters SHOULD refresh/replace expired tokens before retrying protected requests.
Optional Untrusted-Broker Security Profile
- This profile defines an optional end-to-end payload protection mode for environments where broker/topic ACLs are not sufficient to guarantee confidentiality.
- Profile identifier:
- MQTT User Property key:
a2a-security-profile - value:
ubsp-v1
- MQTT User Property key:
- When
a2a-security-profile=ubsp-v1is set on a request, requester and responder MUST use end-to-end encrypted payloads for all request, reply, and stream messages for that interaction. - Under
ubsp-v1, payloads MUST use JOSE JWE serialization:- MQTT
Content TypeMUST beapplication/jose+json(JSON serialization) orapplication/jose(compact serialization).
- MQTT
- Requesters MUST encrypt request payloads to the target responder public key resolved from trusted agent metadata (for example Agent Card extensions such as
jwksUri, or trusted OIDC/OAuth metadata links). - Responders MUST encrypt reply/stream payloads to the requester public key resolved from trusted metadata.
- Requesters using
ubsp-v1MUST provide discoverable public key metadata so responders can resolve a reply encryption key. - Under
ubsp-v1, request publications MUST include MQTT User Properties:- key:
a2a-security-profile, value:ubsp-v1 - key:
a2a-requester-agent-id, value: requesteragent_id - key:
a2a-recipient-agent-id, value: intended responderagent_id
- key:
- Under
ubsp-v1, response publications MUST include MQTT User Properties:- key:
a2a-security-profile, value:ubsp-v1 - key:
a2a-requester-agent-id, value: requesteragent_id - key:
a2a-responder-agent-id, value: responderagent_id
- key:
- Implementations MAY include
a2a-recipient-kidto indicate the JWKkidused for encryption. - Responders MUST verify that
a2a-recipient-agent-idmatches local responder identity before processing aubsp-v1request; mismatches MUST be rejected astransport_protocol_error. - Requesters and responders using
ubsp-v1SHOULD enforce replay protection for protected payloads (for examplejtiand short-livedexpclaims in protected content). - This profile reduces payload confidentiality/integrity dependency on broker ACL correctness, but does not replace transport TLS, authentication, or authorization requirements in this specification.
Optional MQTT Native Binary Artifact Mode
- Baseline interoperability remains JSON payloads, where binary
Part.rawcontent is represented using base64 in JSON serialization. - Implementations MAY support an optional native binary artifact mode for high-throughput scenarios.
- Mode selection for artifact encoding is controlled by request MQTT User Property
a2a-artifact-mode. - Requesters MAY set
a2a-artifact-modeto one of:json(default, JSON-compatible artifact payloads)binary(native MQTT binary artifact payloads)
- If
a2a-artifact-mode=binaryis requested and supported by the responder, the responder MAY publish artifact chunks as raw binary payloads on the reply stream topic. - If
a2a-artifact-modeis absent, unknown, or unsupported by the responder, implementations MUST usejsonmode. - Responders SHOULD indicate the chosen mode in reply messages using MQTT User Property:
- key:
a2a-artifact-mode - value:
jsonorbinary
- key:
- Each native binary artifact message MUST:
- echo the request
Correlation Data - set MQTT Payload Format Indicator to
0(unspecified bytes) - use MQTT Content Type when artifact media type is known
- include MQTT User Properties:
- key:
a2a-event-type, value:task-artifact-update - key:
a2a-task-id, value: task identifier - key:
a2a-artifact-id, value: artifact identifier - key:
a2a-chunk-seqno, value: chunk sequence number - key:
a2a-last-chunk, value:trueorfalse
- key:
- optionally include:
- key:
a2a-context-id, value:Task.context_idvalue
- key:
- echo the request
- MQTT User Property values are UTF-8 strings; non-string metadata MUST be string-encoded.
- Native binary artifact messages SHOULD use MQTT QoS 1.
a2a-last-chunk=trueindicates artifact chunk completion only; stream completion semantics still follow terminal task status (TASK_STATE_COMPLETED,TASK_STATE_FAILED,TASK_STATE_CANCELED).
Optional Broker-Managed Status via MQTT User Properties
As a complement to agent-published liveness (see Presence and Liveness), a broker MAY override or attach MQTT v5 User Properties on retained discovery messages when forwarding them to subscribers.
- Brokers implementing this feature SHOULD set or override the following User Properties based on the agent's MQTT client connection state:
- key:
a2a-status, value:onlinewhen the agent's client connection is active - key:
a2a-status, value:offlinewhen the agent's client connection is observed disconnected - key:
a2a-status-source, value:brokerto indicate the status originates from broker connection tracking (replacing any agent-publisheda2a-status-sourcevalue)
- key:
- Brokers SHOULD derive status from the agent's MQTT client connection state, keyed by Client ID (
{org_id}/{unit_id}/{agent_id}). - Subscribers MUST treat broker-managed status properties as advisory transport metadata and MUST NOT treat them as a replacement for request/reply error handling.
- When
a2a-status-source=brokeris present, subscribers SHOULD prefer it over agent-published status for connection-level reachability, as the broker has authoritative knowledge of TCP connection state.
Error Handling and Deduplication
- Requesters and responders MUST tolerate duplicate delivery behavior possible with MQTT QoS 1.
- Requesters SHOULD de-duplicate stream/reply items using available keys, such as
Correlation Data,a2a-task-id,a2a-artifact-id, anda2a-chunk-seqno. - Unknown
a2a-User Properties SHOULD be ignored unless marked mandatory by this profile. - Implementations MAY use MQTT Message Expiry Interval for stale-request control.
- If message expiry indicates the request is stale before processing, responders SHOULD drop it and MAY publish an expiration-related error when a valid reply path exists.
Mandatory Binding-Specific Error Mapping (JSON-RPC over MQTT)
- Error replies on MQTT request/reply paths MUST use JSON-RPC
errorobjects. - Error replies MUST echo the request MQTT
Correlation Data. - For generic JSON-RPC and A2A method/application errors (for example parse, invalid request, method not found, invalid params, authn/authz failures), implementations MUST follow the core A2A/JSON-RPC definitions.
- This MQTT binding defines the following mandatory transport-specific mapping:
| Condition | JSON-RPC error.code | error.data.a2a_error |
|---|---|---|
| Request expired before processing | -32003 | request_expired |
| Temporary responder unavailable/overloaded | -32004 | responder_unavailable |
| MQTT binding protocol metadata invalid | -32005 | transport_protocol_error |
- For
-32003to-32005, responders MUST includeerror.data.a2a_errorexactly as shown above. transport_protocol_errorcovers invalid or missing MQTT binding metadata required by this profile (for example malformed or missing request/reply binding properties).- Requesters MUST treat
-32003and-32004as retry-eligible at application policy level; transport-layer retries still followRequester Retry and Timeout Profile. - Requesters MUST treat
-32005as non-retryable unless request metadata is corrected.
Conformance Levels
Core Conformance
An implementation is Core conformant if it supports:
- Discovery retained topic model
- Request/reply topic model
- MQTT 5 reply correlation mapping (Response Topic + Correlation Data)
- Requester and responder interop behavior defined in this profile
- QoS interoperability support: MQTT QoS 1 on discovery, request, and reply paths
- Mandatory error-code mapping defined in this profile
- Multi-turn conversation patterns (
Task.context_idsemantics and interrupted-task continuation) - Presence and liveness (LWT configuration,
a2a-statusUser Property on Agent Card publications)
Extended Conformance
An implementation is Extended conformant if it additionally supports one or more of:
- Trusted JKU policy enforcement
- Broker-managed status via MQTT User Properties
- Extended observability over request/reply/event traffic
- Native binary artifact mode over MQTT
- Shared-subscription request dispatch
- Untrusted-broker security profile (
ubsp-v1)
Future Work
- HTTP JSON-RPC and A2A over MQTT interop
- SSE and WebSocket transport guidance for streaming and bidirectional flows
- Cross-broker conformance test suite and certification profile