# ADR-026: Agent Client Protocol (ACP)

**Status:** Proposed  
**Date:** 2026-02-17  
**Supersedes:** None  
**Author(s):** CleverAgents Team  
**Approver(s):**

## Context

CleverAgents is accessed through multiple presentation-layer clients — CLI, TUI, Web, and an IDE plugin — and can operate in both local (single-process) and server (multi-user HTTPS) modes. Without a shared, versioned contract between clients and the backend, each client would require bespoke integration code that drifts from the core domain model, making interoperability fragile and third-party client development impractical. The architecture needs a single protocol surface that all clients rely on regardless of deployment mode.

## Decision

CleverAgents adopts the **Agent Client Protocol (ACP)** as the versioned contract governing all client-to-backend communication. ACP defines canonical operations for sessions, plans, registries, context, and event streaming. In local mode ACP maps to in-process service facade calls; in server mode it is implemented by the REST API over HTTPS.

## Design

### Protocol Scope

ACP covers five operation groups:

| Group | Operations |
|-------|-----------|
| **Session lifecycle** | create, resume, list, show, delete, export, import, tell |
| **Plan lifecycle** | use, execute, apply, cancel, status, tree, explain, correct, diff, artifacts, prompt, rollback |
| **Registries** | list / show / add / update / remove for actors, skills, tools, validations, resources, resource types, projects, actions, automation profiles, invariants |
| **Context operations** | context show, context inspect, context simulate, context set |
| **Event streaming** | plan state changes, tool execution events, validation results, structured log events |

### Request / Response Envelope

Every ACP operation uses a canonical JSON envelope:

```json
{
  "acp_version": "1.0",
  "request_id": "<ULID>",
  "operation": "plan.status",
  "params": { "plan_id": "01HXRCF1..." },
  "auth": { "token": "..." }
}
```

Responses follow a matching envelope with `status`, `data`, and `error` fields. Error objects carry `code`, `message`, and optional `details`.

### Transport

- ACP is **transport-agnostic** at the specification level.
- The default server implementation uses **HTTPS + JSON** via the FastAPI REST API.
- Streaming updates use **Server-Sent Events (SSE)** in server mode with structured event payloads.
- Local mode resolves operations to direct Python method calls on the Service Facade, bypassing serialization entirely.

### Versioning and Compatibility

- Each client advertises `acp_version` during connection.
- Servers must support the current minor version plus one prior minor version.
- Backward-compatible additions (new optional fields, new operations) are permitted within a major version; breaking changes require a major version bump.

### Authentication and Authorization

- **Server mode**: Token-based authentication (`server.token`) required for all ACP requests. Authorization is enforced per namespace.
- **Local mode**: Authentication is bypassed but the ACP operation surface remains identical.

### Service Facade Mapping

Each ACP operation group maps to an Application-layer service:

| ACP Group | Service |
|-----------|---------|
| Session | `SessionWorkflow` |
| Plan | `PlanService`, `PlanLifecycle`, `CorrectionFlow` |
| Registries | `ActorService`, `ToolService`, `SkillService`, `ResourceService`, `ProjectService` |
| Context | `ContextService` |
| Events | `EventEmitter` (via SSE or in-process subscription) |

## Constraints

- Clients must not bypass ACP to access storage, repositories, or internal domain services directly.
- All ACP operations must be implementable in both local and server modes with identical semantics.
- All ACP operations in server mode must require valid authentication.
- ACP responses must use the canonical JSON envelope; ad-hoc response shapes are prohibited.
- Event streaming must preserve causal ordering within a single plan lifecycle.

## Consequences

### Positive
- Clients are interchangeable — new clients (e.g., mobile, third-party dashboards) can be built against the same stable contract.
- Local and server modes share the same operational surface, eliminating behavioral drift.
- Versioning guarantees backward compatibility for at least one prior minor version.

### Negative
- The protocol adds upfront design and versioning overhead.
- Some client-specific optimizations (e.g., batching, caching) are harder when constrained to a shared contract.

### Risks
- Protocol evolution could lag feature development if versioning discipline is not maintained.
- SSE streaming channels may become a bottleneck for plans with very high event throughput.

## Alternatives Considered

**Per-client bespoke APIs** — Faster initial development but leads to drift, duplicated logic, and higher long-term maintenance costs. Rejected.

**Direct database access for local clients** — Faster reads in local mode but breaks parity with server mode and tightly couples clients to storage schema. Rejected.

**gRPC** — Strong typing and streaming but adds a code-generation dependency and is less accessible for browser-based clients than JSON over HTTPS. May be revisited for high-throughput server-to-server communication.

## Compliance

- **Contract tests**: Validate all ACP endpoints against the canonical schema for every supported version.
- **Local/server parity tests**: Execute the same ACP test suite in both deployment modes and assert identical results.
- **Authentication tests**: Verify token enforcement and namespace authorization in server mode.
- **Streaming tests**: Ensure event ordering and schema compliance for SSE event payloads.
- **Bypass detection**: Architecture tests verify that no Presentation-layer module imports from the Infrastructure layer directly.

## Related ADRs

| ADR | Title | Relationship |
|-----|-------|-------------|
| [ADR-001](ADR-001-layered-architecture.md) | Layered Architecture | ACP sits at the Presentation-Application boundary defined by the layered architecture |
| [ADR-020](ADR-020-session-model.md) | Session Model | ACP defines the session lifecycle operations exposed to clients |
| [ADR-023](ADR-023-server-mode.md) | Server Mode | ACP is the client-server contract for remote execution in server mode |
| [ADR-027](ADR-027-language-server-protocol.md) | Language Server Protocol (LSP) Integration | The LSP server communicates with the backend exclusively through ACP |

## Acceptance

### Votes For

| Voter | Comment |
|-------|---------|

**Total: 0**

### Votes Against

| Voter | Comment |
|-------|---------|

**Total: 0**

### Abstentions

| Voter | Comment |
|-------|---------|

**Total: 0**
