---
adr_number: 47
title: "A2A Standard Adoption"
status_history:
  - ["2026-03-11", "Draft", "Jeffrey Phillips Freeman"]
  - ["2026-03-11", "Proposed", "Jeffrey Phillips Freeman"]
  - ["2026-03-11", "Accepted", "Jeffrey Phillips Freeman"]
tier: 4
authors: ["Jeffrey Phillips Freeman"]
superseded_by:
related_adrs:
  - number: 1
    title: "Layered Architecture"
    relationship: "A2A remains the Presentation-Application boundary; adopting the external standard provides the wire format while preserving the layer role"
  - number: 23
    title: "Server Mode"
    relationship: "Server mode transport uses A2A JSON-RPC over HTTP; shared Domain/Application layers are unaffected"
  - number: 26
    title: "Agent-to-Agent Protocol (A2A)"
    relationship: "Supersedes the bespoke envelope and REST transport originally defined in ADR-026; the A2A boundary role and operation groups remain, now implemented via the external standard"
  - number: 22
    title: "LangChain/LangGraph Integration"
    relationship: "LangGraph Platform serves as the remote actor execution backend; A2A handles the client-server protocol layer above it"
  - number: 48
    title: "Server Application Architecture"
    relationship: "ADR-048 defines the server that implements the A2A standard endpoint; this ADR defines the protocol it speaks"
acceptance:
  votes_for:
    - voter: "Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com>"
      comment: "Adopting the external A2A standard eliminates our bespoke protocol, aligns with the emerging agent ecosystem, and gives us production-quality transports and Agent Card discovery via the SDK"
  votes_against: []
  abstentions: []
---
## Context

ADR-026 established the agent communication protocol as the sole Presentation-Application boundary for all CleverAgents clients. That initial design used a bespoke JSON envelope format transported over a RESTful API (FastAPI/uvicorn, URL-path routing, HTTP verbs, SSE streaming). Since then, the **Agent-to-Agent (A2A) Protocol** has emerged as an open standard ([a2a-protocol.org](https://a2a-protocol.org)) under the **Linux Foundation** (Apache 2.0 license), with official SDKs in **Python, Go, JavaScript, Java, and .NET**. The external standard provides:

- A protocol-binding-agnostic operation model with JSON-RPC 2.0, gRPC, and REST bindings
- **Agent Cards** (`/.well-known/agent.json`) for dynamic capability discovery
- Standard operations for messaging (`message/send`, `message/stream`), task lifecycle (`tasks/get`, `tasks/list`, `tasks/cancel`), push notifications, and agent discovery
- A rich **Task lifecycle** model with states: `submitted`, `working`, `input-required`, `completed`, `failed`, `canceled`, `rejected`
- An **extensibility mechanism** for platform-specific operations (custom methods declared in Agent Card)
- SSE streaming for real-time task status and artifact updates
- Multi-language SDK support with production-quality transport implementations

Adopting this external standard eliminates our bespoke protocol, provides SDK-quality transport implementations, Agent Card-based discovery, and positions CleverAgents within the broader agent interoperability ecosystem.

## Decision Drivers

- The existing bespoke protocol (custom envelope, REST routing, SSE streaming) requires ongoing maintenance and has no ecosystem adoption outside CleverAgents
- The A2A standard covers the core agent interaction lifecycle (messaging, task management, streaming, discovery) which maps directly to CleverAgents SessionWorkflow and plan execution
- Platform operations (plan lifecycle, registry CRUD, entity sync, namespace management) are cleanly handled by A2A's extensibility mechanism
- The A2A Python SDK provides production-quality JSON-RPC and HTTP transports, eliminating the need for our stub transport and custom serialization code
- Agent Card discovery enables third-party agents and clients to dynamically discover CleverAgents capabilities
- IDE plugins, CLI, TUI, and external clients all benefit from speaking a standardized protocol that third parties can implement against
- A2A's Linux Foundation governance and broad industry adoption (22k+ GitHub stars, 140+ contributors) provide long-term ecosystem stability

## Decision

CleverAgents adopts the **external Agent-to-Agent (A2A) Protocol standard** ([a2a-protocol.org](https://a2a-protocol.org)) as the **sole** communication protocol for all client-server interaction. This replaces the bespoke REST+JSON envelope protocol defined in the original ADR-026. The protocol role of A2A — as the Presentation-Application boundary — is unchanged; only the wire format, transport, and method vocabulary change.

**No REST API.** All communication uses A2A via the JSON-RPC 2.0 protocol binding. Standard A2A operations handle agent interactions. A2A extension methods (`_cleveragents/`-prefixed) handle all platform operations.

## Design

### Protocol Architecture

A2A is the **only** protocol between any client and the CleverAgents backend. There are two categories of operations:

**Standard A2A operations** (defined by the external specification):

| Operation | Direction | Purpose |
|-----------|-----------|---------|
| `message/send` | Client → Server | Send a message to the agent, receive a Task or direct response |
| `message/stream` | Client → Server | Send a message with SSE streaming of task updates |
| `tasks/get` | Client → Server | Retrieve current state of a task |
| `tasks/list` | Client → Server | List tasks with optional filtering |
| `tasks/cancel` | Client → Server | Cancel a running task |
| `tasks/subscribe` | Client → Server | Subscribe to task updates via SSE |
| `pushNotificationConfig/*` | Client → Server | Manage push notification webhooks |
| `getExtendedAgentCard` | Client → Server | Fetch authenticated Agent Card with full detail |

**Standard A2A streaming events** (server → client via SSE):

| Event | Emitted When |
|-------|-------------|
| `TaskStatusUpdateEvent` | Task state changes (submitted → working → completed, etc.) |
| `TaskArtifactUpdateEvent` | Agent produces output (response chunks, plan entries, tool results) |

**Multi-turn interactions** (replacing protocol-level callbacks):

| Pattern | Purpose |
|---------|---------|
| Task enters `input-required` state | Human-in-the-loop approval (maps to automation profile gates) |
| Client responds via `message/send` | Provides requested input, file content, or approval |
| `_cleveragents/fs/*` extensions | Agent accesses files on client machine (handled locally by client) |
| `_cleveragents/terminal/*` extensions | Agent runs commands in sandbox on client machine |

**CleverAgents extension methods** (declared in Agent Card via A2A extension mechanism):

All platform operations use the `_cleveragents/` namespace. See the specification's [Server and Client Architecture](#) section for the complete method catalog with parameters and response schemas.

### Mapping to CleverAgents Concepts

| A2A Standard Concept | CleverAgents Concept |
|---------------------|---------------------|
| `message/send` | `SessionWorkflow.tell()` — user talks to orchestrator actor |
| `TaskStatusUpdateEvent` (plan updates) | Plan with entries (content, priority, status) — direct mapping |
| `TaskArtifactUpdateEvent` (tool output) | Tool invocations during plan execution |
| Task `input-required` state | Automation profile human-in-the-loop approval gates |
| `_cleveragents/fs/*` extensions | Agent accesses client-local project resources |
| `_cleveragents/terminal/*` extensions | Agent runs commands in sandbox on client machine |
| Agent Card skills | Advertised plan lifecycle, registry, context, sync capabilities |
| Agent Card security schemes | Authentication methods (OAuth2, API key, bearer token) |

### Agent Discovery: Agent Card

A2A introduces **Agent Cards** — JSON metadata documents that describe an agent's capabilities, skills, security requirements, and supported protocol bindings. The CleverAgents Agent Card is served at `/.well-known/agent.json` in server mode and declares:

- **Skills**: Plan lifecycle management, registry CRUD, context assembly, entity sync, namespace management, diagnostics
- **Extensions**: `_cleveragents/` methods with URI `urn:cleveragents:extensions:v1`
- **Supported interfaces**: `jsonrpc` (primary)
- **Security schemes**: OAuth2, API key, or HTTP bearer

An authenticated extended Agent Card with additional detail is available via the `getExtendedAgentCard` operation.

### Transport Modes

The system supports three transport configurations:

**Local mode — A2A JSON-RPC over stdio:**

```
Client Process  ──stdio──→  Agent Subprocess (A2A server)
                              │
                              ├── A2aLocalFacade (platform ops resolved in-process)
                              └── Actor Graph (LangGraph, local execution)
```

The client spawns the agent as a subprocess. A2A JSON-RPC messages flow over stdin/stdout. Platform operations (registry, plan lifecycle, etc.) are handled by `A2aLocalFacade` which routes to in-process Application-layer services. No network, no serialization beyond JSON-RPC framing.

**Server mode — A2A JSON-RPC over HTTP (CleverAgents server):**

```
Client  ──HTTP──→  CleverAgents A2A Server
                     │
                     ├── Standard A2A operations → SessionWorkflow, Actor Graphs (via LangGraph Platform RemoteGraph)
                     └── Extension methods → PlanService, RegistryServices, SyncService, NamespaceService
```

The client connects to the CleverAgents server via the A2A SDK's HTTP transport. All communication — both agent interactions and platform operations — flows through the single A2A endpoint. The server delegates actor execution to LangGraph Platform via RemoteGraph.

**Server mode — External A2A agent + CleverAgents server:**

```
Client  ──HTTP──→  External A2A Server (agent interactions)
        ──HTTP──→  CleverAgents A2A Server (extension methods only)
```

When an agent is hosted on an external A2A-compatible server, the client sends standard A2A operations to that server and `_cleveragents/` extension methods to the CleverAgents server. This enables interoperability with any A2A-compliant agent.

### Wire Format: JSON-RPC 2.0

All A2A messages use JSON-RPC 2.0 framing (A2A specification Section 9):

**Request (message/send):**
```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [{ "text": "Refactor the auth module to use dependency injection" }]
    }
  }
}
```

**Response (Task created):**
```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "id": "task_01HXRCF1...",
    "status": { "state": "working" }
  }
}
```

**SSE streaming event:**
```json
{
  "jsonrpc": "2.0",
  "method": "message/stream",
  "params": {
    "id": "task_01HXRCF1...",
    "status": { "state": "working" },
    "artifacts": [{ "parts": [{ "text": "I'll start by extracting the authentication..." }] }]
  }
}
```

**Error response:**
```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32001,
    "message": "Plan not found",
    "data": { "plan_id": "01HXRCF1..." }
  }
}
```

**Extension method request:**
```json
{
  "jsonrpc": "2.0",
  "id": 42,
  "method": "_cleveragents/plan/status",
  "params": { "plan_id": "01HXRCF1..." }
}
```

### Error Code Mapping

A2A uses JSON-RPC 2.0 integer error codes (per A2A Section 9.5):

| Code | Meaning | Domain Exception(s) |
|------|---------|---------------------|
| `-32700` | Parse error (malformed JSON) | — |
| `-32600` | Invalid request | — |
| `-32601` | Method not found | `A2aOperationNotFoundError` |
| `-32602` | Invalid params | `ValidationError` |
| `-32603` | Internal error | Any unhandled `Exception` |
| `-32001` | Entity not found | `ResourceNotFoundError` |
| `-32002` | Authentication required | `AuthenticationError` |
| `-32003` | Authorization forbidden | `AuthorizationError` |
| `-32004` | Invalid state | `BusinessRuleViolation` |
| `-32005` | Already exists | `DuplicateEntityError` |
| `-32006` | Budget exceeded | `BudgetExceededError` |
| `-32007` | Version mismatch | `A2aVersionMismatchError` |
| `-32008` | Plan error | `PlanError` |

Application-specific error codes use the range `-32001` to `-32099` per JSON-RPC 2.0 convention.

### Authentication

Authentication uses standard HTTP security schemes declared in the Agent Card:

1. Client discovers the Agent Card at `/.well-known/agent.json`
2. Agent Card's `securitySchemes` field declares supported auth mechanisms (OAuth2, API key, HTTP bearer)
3. Client authenticates using the declared mechanism (e.g., `Authorization: Bearer <token>` header)
4. All subsequent requests include the authentication credentials

For HTTP transport, the `A2A-Version` header communicates the protocol version.

Local mode (stdio transport) bypasses authentication entirely — the agent subprocess runs with the user's local permissions.

### Versioning

- The JSON-RPC protocol version is always `"2.0"` in the `jsonrpc` field
- A2A protocol version is communicated via the `A2A-Version` HTTP header
- CleverAgents extension version is declared in the Agent Card's `extensions` field under `urn:cleveragents:extensions:v1`
- Backward compatibility: servers support current extension version plus one prior minor version
- Breaking changes to extension methods require a major version bump of the `_cleveragents` extension namespace

### Client-Side Architecture

The client uses an `A2aClient` wrapping the A2A Python SDK:

| Component | Role | Notes |
|-----------|------|-------|
| `A2aLocalFacade` | **Extension method dispatch** | Routes `_cleveragents/` methods to in-process Application-layer services in local mode |
| A2A SDK HTTP transport | **Server mode transport** | Production HTTP transport with SSE streaming |
| A2A SDK JSON-RPC types | **Wire format types** | `SendMessageRequest`, `Task`, `Message`, `Part`, `TaskStatusUpdateEvent`, etc. |
| `A2aEventQueue` | **Local mode event delivery** | In-process delivery of task update events |
| Agent Card | **Discovery** | Describes capabilities, skills, extensions, and security schemes |

## Constraints

- All client-server communication **must** use A2A. No REST endpoints, no ad-hoc HTTP calls, no separate API surfaces.
- Standard A2A operations must not be modified or extended — use `_cleveragents/` extension methods for platform-specific operations.
- Extension method names must follow the `_cleveragents/{domain}/{operation}` naming convention.
- Clients must gracefully handle servers that do not advertise `_cleveragents` capabilities (indicating a non-CleverAgents A2A server).

## Consequences

### Positive

- Eliminates the bespoke REST protocol, reducing maintenance burden and protocol-specific code
- Aligns with the A2A interoperability ecosystem — any A2A-compatible client or agent can interact with CleverAgents
- Agent Card discovery enables dynamic capability advertisement and third-party integration
- The A2A Python SDK provides production-quality transports with proper connection lifecycle management
- JSON-RPC 2.0 is a mature, well-tooled standard with broad language support; gRPC and REST bindings are available for future adoption
- IDE plugins benefit from a standard protocol that editor developers may already support
- The extensibility mechanism cleanly separates standard agent operations from platform-specific operations
- Linux Foundation governance and multi-language SDK support provide long-term ecosystem stability

### Negative

- Adopting the standard requires updating all existing protocol source code and tests
- JSON-RPC 2.0's error code scheme (integers) is less self-documenting than string-based codes (e.g., `NOT_FOUND` vs `-32001`)

### Risks

- The extension method namespace (`_cleveragents/`) could collide with other implementations. Mitigation: the `_cleveragents` prefix is unique and registered.

## Alternatives Considered

**Keep the bespoke REST protocol** — Functional but isolated. No ecosystem interoperability, ongoing maintenance of custom envelope format, and no path to IDE-native agent protocol support. Rejected.

**Adopt standard for agent conversations only, keep REST for platform operations** — Simpler initial approach but creates two protocol surfaces, complicating client implementation and authentication. The A2A extensibility mechanism makes this unnecessary. Rejected.

**ACP (Agent Client Protocol)** — The predecessor to A2A. Also built on JSON-RPC 2.0, but lacked Agent Card discovery, had a smaller single-language SDK ecosystem, and is now deprecated. The ecosystem (including ACP's originating platform) has converged on A2A. Rejected in favor of A2A.

**gRPC for platform operations** — Strong typing and streaming but adds code generation dependency, a second protocol surface, and is harder to debug. A2A includes a gRPC binding (Section 10) that can be adopted later if needed. Rejected as the primary binding.

## Compliance

- **Protocol conformance tests**: Validate all standard A2A operation signatures and response schemas against the A2A specification test suite.
- **Extension method tests**: Validate all `_cleveragents/` methods against documented parameter and response schemas.
- **Transport parity tests**: Execute the same test suite over stdio transport (local mode) and HTTP transport (server mode), asserting identical results.
- **SDK integration tests**: Verify A2A Python SDK transport works correctly for both transport modes.
- **Agent Card tests**: Validate the generated Agent Card conforms to the A2A specification schema.
- **Discovery tests**: Verify `/.well-known/agent.json` is served correctly and `getExtendedAgentCard` returns authenticated detail.
- **Bypass detection**: Architecture tests verify no Presentation-layer module bypasses A2A to access Domain or Infrastructure services.
