The EventMesh A2A (Agent-to-Agent) Protocol is a specialized, high-performance protocol plugin designed to enable asynchronous communication, collaboration, and task coordination between autonomous agents.
With the release of v2.0, A2A adopts the MCP (Model Context Protocol) architecture, transforming EventMesh into a robust Agent Collaboration Bus. It bridges the gap between synchronous LLM-based tool calls (JSON-RPC 2.0) and asynchronous Event-Driven Architectures (EDA), enabling scalable, distributed, and decoupled agent systems.
- Standard Compliance: Fully supports standard methods defined by MCP (Model Context Protocol), such as
tools/call,resources/read. - Event-Driven: Maps synchronous RPC calls to asynchronous Request/Response Event Streams, leveraging EventMesh's high-concurrency processing capabilities.
- Transport Agnostic: All MCP messages are encapsulated within standard CloudEvents envelopes, running over any transport layer supported by EventMesh (HTTP, TCP, gRPC, Kafka).
A2A Protocol features a unique Dual-Mode architecture that simultaneously supports:
- JSON-RPC 2.0 (MCP Mode):
- Target: LLMs, Scripts (Python/JS), LangChain integration.
- Benefit: Extremely low barrier to entry. Clients send simple JSON objects; the adaptor automatically wraps them in CloudEvents.
- Native CloudEvents (Power Mode):
- Target: EventMesh native apps, Knative, Serverless functions.
- Benefit: Full control over event metadata. Allows pass-through of custom or binary data.
Mechanism: The EnhancedA2AProtocolAdaptor intelligently detects the payload format. If jsonrpc: "2.0" is present, it engages the MCP translation engine; otherwise, it treats the payload as a standard CloudEvent (delegating to the underlying CloudEvents adaptor).
- O(1) Broadcast: Publishers send messages once to a Topic, and EventMesh efficiently fans out to all subscribers.
- Decoupling: Solves the scalability issues of traditional P2P Webhook callbacks.
- Isolation: Provides backpressure isolation between publishers and subscribers.
- Batch Processing: Natively supports JSON-RPC Batch requests. EventMesh automatically splits them into parallel event streams.
- Intelligent Routing: Extracts routing hints (
_agentIdfor P2P,_topicfor Pub/Sub) from MCP parameters and injects them into CloudEvents attributes for zero-decoding routing.
- Sequencing: Preserves message order for streaming operations (
message/sendStream) using sequence IDs.
┌─────────────────────────────────────────────────────────────┐
│ EventMesh A2A Protocol v2.0 │
│ (MCP over CloudEvents Architecture) │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ MCP/JSON-RPC│ │ Native │ │ Protocol │ │
│ │ Handler │ │ Pub/Sub │ │ Delegator │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Enhanced A2A Protocol Adaptor │ │
│ │ (Intelligent Parsing & CloudEvent Mapping) │ │
│ └───────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ EventMesh Protocol Infrastructure │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ CloudEvents │ │ HTTP │ │ gRPC │ │
│ │ Protocol │ │ Protocol │ │ Protocol │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
protocol-a2a module runtime module examples module
┌─────────────────┐ ┌──────────────────┐ ┌──────────────┐
│ A2AMessageTransport(Iface) │ A2AGatewayServer │ │ A2AGatewayDemo│
│ A2AClient (SDK) │<──HTTP──>│ (main, Netty HTTP)│<──HTTP──>│ (client only) │
│ AgentCard/Topic │ │ InMemoryTransport │ └──────────────┘
└─────────────────┘ │ GatewayService │
│ TaskRegistry(TTL) │
└──────────────────┘
| Component | Module | Responsibility |
|---|---|---|
A2AGatewayServer |
runtime | Netty HTTP server entry point, pre-registers mock agents |
A2AGatewayHttpHandler |
runtime | HTTP request router, supports SSE streaming |
A2AGatewayService |
runtime | Core orchestration: task submission, response handling, SSE push |
TaskRegistry |
runtime | In-memory task state machine + TTL auto-cleanup (5 min) |
A2APublishSubscribeService |
runtime | AgentCard registration, discovery, heartbeat |
InMemoryA2AMessageTransport |
runtime | In-memory pub/sub (replaceable by EventMesh broker) |
A2AClient |
protocol-a2a | Java SDK with typed API |
To support the MCP Request/Response model within an event-driven architecture, A2A defines the following mapping rules:
| MCP Concept | CloudEvent Mapping | Description |
|---|---|---|
Request (tools/call) |
type: org.apache.eventmesh.a2a.tools.call.req mcptype: request |
Request event. |
Response (result) |
type: org.apache.eventmesh.a2a.common.response mcptype: response |
Response event. |
Correlation (id) |
extension: collaborationid / id |
Links Response to Request. |
| P2P Target | extension: targetagent |
Routing target Agent ID. |
| Pub/Sub Topic | subject: <topic_name> |
Broadcast Topic. |
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_weather",
"_agentId": "weather-service" // P2P Routing
},
"id": "req-123"
}{
"jsonrpc": "2.0",
"method": "market/update",
"params": {
"price": 50000,
"_topic": "market.btc" // Pub/Sub Routing
}
}// 1. Construct MCP Request JSON
String mcpRequest = "{" +
"\"jsonrpc\": \"2.0\"," +
"\"method\": \"tools/call\"," +
"\"params\": { \"name\": \"weather\", \"_agentId\": \"weather-agent\" }," +
"\"id\": \"req-001\"" +
"}";
// 2. Send via EventMesh SDK
eventMeshProducer.publish(new A2AProtocolTransportObject(mcpRequest));Subscribe to the topic org.apache.eventmesh.a2a.tools.call.req, process logic, and send back response with matching id.
The A2A Gateway provides a full REST API for external clients and non-Java agents:
# Sync task
curl -X POST 'http://localhost:10105/a2a/tasks?mode=sync' \
-H 'Content-Type: application/json' \
-d '{"targetAgent":"weather-agent","message":"Beijing"}'
# Async task
curl -X POST 'http://localhost:10105/a2a/tasks?mode=async' \
-H 'Content-Type: application/json' \
-d '{"targetAgent":"weather-agent","message":"Shanghai"}'
# Query status
curl http://localhost:10105/a2a/tasks/{taskId}
# SSE stream
curl -N http://localhost:10105/a2a/tasks/{taskId}/stream
# List agents
curl http://localhost:10105/a2a/agents| Method | Path | Description |
|---|---|---|
| POST | /a2a/tasks?mode=sync |
Submit task synchronously (wait for result) |
| POST | /a2a/tasks?mode=async |
Submit task asynchronously (return taskId) |
| GET | /a2a/tasks/{taskId} |
Get task status |
| DELETE | /a2a/tasks/{taskId} |
Cancel task |
| GET | /a2a/tasks/{taskId}/wait |
Long-poll wait for result |
| GET | /a2a/tasks/{taskId}/stream |
SSE stream of task status updates |
| GET | /a2a/agents |
List registered agents |
| POST | /a2a/heartbeat |
Agent heartbeat |
| GET | /a2a/cards/list |
List all AgentCards |
| POST | /a2a/cards/card/{org}/{unit}/{agent} |
Register AgentCard |
A2AClient client = A2AClient.builder()
.gatewayUrl("http://localhost:10105")
.namespace("global")
.agentName("my-agent")
.agentCard(card)
.heartbeatInterval(30_000)
.build();
client.start();
// Sync task (returns typed TaskResult)
TaskResult result = client.sendTaskSync("weather-agent", "Beijing", null);
// Async task (returns taskId)
String taskId = client.sendTaskAsync("weather-agent", "Shanghai", null);
// Query status
TaskResult status = client.getTaskStatus(taskId);
// Cancel
boolean cancelled = client.cancelTask(taskId);
// List agents (returns List<String>)
List<String> agents = client.listAgents();
client.shutdown();-
v2.0.0: Fully Embraced MCP (Model Context Protocol)
- Introduced
EnhancedA2AProtocolAdaptorsupporting JSON-RPC 2.0. - Implemented Async RPC over CloudEvents pattern.
- Added Native Pub/Sub support via
_topicparameter. - Added Streaming support via
_seqparameter.
- Introduced
-
v2.1.0: Gateway Runtime Architecture
- Added
A2AGatewayServer(Netty HTTP) standalone Gateway service. - Implemented
TaskRegistrytask state machine + TTL auto-cleanup (5 min). - Added SSE streaming response (
GET /a2a/tasks/{taskId}/stream). A2AClientSDK returns typed objects (TaskResult,List<String>).- Fixed
pendingTasksrace condition (put-before-publish). - AgentCard registration, discovery, heartbeat management.
- 73 test scenarios all passing.
- Added
Welcome to contribute code and documentation!
Apache License 2.0
- Project Homepage: https://eventmesh.apache.org
- Issues: https://github.com/apache/eventmesh/issues
- Mailing List: dev@eventmesh.apache.org