All articles
agentic systems·advanced··Updated

ACP is a client protocol, not a control plane

What the Agent Client Protocol standardizes, what it leaves to the host, and how Coding Agent Control Plane composes project, environment, provider, model, and harness before any handshake.

architecturecoding-agentssecuritytoolingworkflows
Resources
Resource Link
Protocol ACP architecture
Overview ACP protocol overview
Version boundary ACP v1 to v2 migration
Implementation coding-agent-control-plane
Runtime design ACP runtime architecture
Environment model Environment domain model

An ACP connection can be healthy while the coding product around it is unusable.

The agent may accept initialize, create a session, stream updates, and answer a prompt. The editor can still lose the session after a reload, leave a child process running after the window closes, expose the wrong workspace, or have no way to explain why a tool call was denied.

That is not a protocol failure. It is a control-plane failure.

The Agent Client Protocol standardizes communication between a client application and a coding agent. It does not start the executable, choose the repository, resolve a credential, apply an environment policy, or prove that the work is complete. A launcher that pretends otherwise becomes a pile of harness-specific conditionals.

The goal is not to pretend that every coding agent is identical. The goal is one reliable control plane with agent-specific behavior at explicit adapter boundaries.

The protocol boundary

ACP defines two participants. The agent uses generative AI to modify code. The client provides the interface, manages access to resources, and handles user interaction. They communicate through JSON-RPC methods, requests, responses, and notifications.

That boundary is useful because editors and agents can evolve independently. An editor can connect to several agents. An agent can work inside several editors. The protocol carries the interaction contract without forcing either side to adopt the other’s internal architecture.

The protocol is not the same thing as the process that carries it.

The four boundaries
Boundary Owns Does not own
Protocol Initialization, capabilities, sessions, prompts, updates, cancellation, and permission requests Process supervision, persistence, retries, or product policy
Client User interface, environment access, resource permissions, and client-side requests The agent’s model loop or the meaning of its internal plans
Runtime host Process launch, identity, working directory, credentials, restart, shutdown, and logs Durable product decisions that belong to the application
Product control plane Projects, environments, worlds, audit records, recovery policy, and completion evidence Agent-specific wire details that belong in an adapter

The exact names vary by product. The separation does not.

What ACP gives — and what it does not

The protocol gives a client a standard conversation surface. A typical connection negotiates capabilities, creates or loads a session, sends a prompt, receives progress notifications, handles permission requests, and cancels the active turn when needed.

The client can use those messages to build an editor, terminal, desktop application, or browser interface. It can render text, file changes, tool activity, permission prompts, and session progress without knowing how the agent implements its model loop.

The client also remains an active participant. ACP is not a one-way stream from an agent to a display. In ACP v1, an agent can ask the client to read or write a file and create or use a terminal. ACP v2 removes those client methods in favor of client-provided MCP servers. Permission requests remain part of the interaction. Every version still crosses a trust boundary that needs a policy decision on the client side.

An ACP implementation still needs answers the wire contract cannot give:

The missing control plane
Question Why the protocol alone cannot answer it
Which executable should start? A protocol describes messages, not installation discovery or executable selection.
Which repository is exposed? The client must resolve and validate the working directory before launch.
Where do credentials come from? Authentication and secret storage depend on the host environment and provider.
Who owns the child process? A connection can close while a subprocess continues running.
What survives a reload? Session loading is only useful if the product stores an identity and can find the agent again.
Which tools are allowed? Capabilities do not replace sandboxing, approval rules, or resource policy.
When is the task complete? A final protocol response is not proof that tests passed or the requested artifact exists.

Treating ACP as the runtime creates predictable bugs. A connection object becomes a session database. A subprocess becomes a workspace manager. A stream of updates becomes an audit log. None of those substitutions are safe.

Compose the session before the handshake

Coding Agent Control Plane is the desktop product that owns that composition. A coding session is not “start Claude.” It is an explicit combination assembled before any ACP message is sent:

Coding session
  = project
  + environment
  + LLM provider
  + model
  + coding-agent harness

The user selects the combination. The application resolves the working directory, provider route, model policy, agent command, permissions, tools, and credential references needed to start. Claude Code, Codex, Grok Build, and OpenCode remain interchangeable harnesses, not the product’s domain model.

Coding Agent Control Plane composing a Claude Code session against the Claude Certification project

An environment is the primary runtime context: where the work happens and which working directories apply. A project groups the work. A world is separate — an operator-authored catalog of approved providers and harnesses. Exactly one world is active. World descriptors never contain raw secrets.

What belongs where
Portable core Agent adapter
Project, environment, and world identity CLI flags, argv, and configuration files
Session lifecycle Agent-specific session creation and resume calls
Prompt turn and cancellation Wire messages on the ACP byte pipe
Permission request Agent-specific permission schema and tool names
Event timeline Stream parsing and dialect normalization
Completion evidence Agent result fields and host-side verification
Agent capabilities Version-specific feature negotiation

The core answers “what is happening?” The adapter answers “how does this agent express it?”

Separate launch from connection

Launching an agent and connecting to an agent are different phases.

The control plane first resolves the harness descriptor, validates the workspace, prepares credentials, creates a child process, and records the process identity. Only then does the protocol client negotiate a connection and create a session.

The launch lifecycle
Phase Success means A failure usually means
Discover The executable and adapter are known Installation or registry problem
Validate Workspace, credentials, and policy are acceptable Configuration or authorization problem
Launch The child process started with the expected identity Spawn, path, or environment problem
Handshake The agent and client negotiated capabilities Protocol or version problem
Create session A durable conversation can begin Agent-side session problem
Run turn Progress and requests are flowing Provider, tool, or permission problem
Verify The requested outcome has evidence Task or validation problem

Without these phases, every failure becomes “the agent did not work.” That message is operationally useless.

Agents resolve from PATH and are never bundled into the signed application. An approved harness that is not installed stays visible with an explanation. A descriptor in the world catalog is not a license to hide the gap: resume: false must remain visible. A host-managed login flow must not be represented as an environment variable just because another agent uses one.

Keep the host a byte pipe

A useful architecture keeps the ACP client next to the UI and the process supervisor next to the operating system.

One product, four owners
Layer Responsibility Why it stays separate
React WebView ACP sessions, streaming messages, plans, permissions, cancellation, and product UI Protocol state stays next to the interface that presents and controls it
Native host Agent discovery, process lifecycle, Keychain access, security checks, and lossless byte transport The host supervises the executable without becoming a second ACP peer
World and environment model Approved providers, models, harnesses, permissions, plugins, Skills, and MCP connections Launch policy remains explicit and reproducible across projects
Services Provider routing, plugin catalogs, MCP aggregation, updates, and harness evaluation Supporting infrastructure evolves without expanding the protocol adapter

In the repository, apps/native-host/src/acp.zig starts an agent and moves bytes. It does not interpret JSON-RPC. apps/web-ui/src/lib/acp owns the conversation protocol, including a dual-stack client that prefers ACP v2 and still accepts v1. Raw credentials remain in the macOS Keychain and are resolved only for an approved launch path.

The native host never implements ACP fs or terminal execution APIs. The WebView negotiates the protocol dialect, while file and terminal execution stay outside the native byte pipe. That separation also matches ACP v2, which replaces the v1 client methods with client-provided MCP servers.

Where failures actually appear

The most confusing failures happen when a healthy protocol connection is mistaken for a healthy product.

The agent connects but the UI is empty

The connection may be streaming updates into a handler that is not attached to the active session. The protocol works; the product lost event ownership.

The session disappears after reload

The client kept an in-memory connection but never persisted the session identity, workspace, or harness descriptor. ACP may support loading a session, but the application still has to know what to load and where.

The window closes but the agent keeps running

The UI lifecycle and process lifecycle are detached. A runtime supervisor needs explicit ownership, shutdown, and orphan cleanup.

The agent finishes but the task is not done

The protocol returned a stop reason. The product still needs verification: tests, artifact checks, repository state, or an evaluation result.

The right abstraction boundary

The control plane should make these decisions once:

  • how a user selects a project and environment
  • which world of providers and harnesses is active
  • how credentials and permissions are governed
  • how sessions are identified and recovered
  • how processes are supervised and cleaned up
  • how failures become actionable states

The adapter should make these decisions locally:

  • how to invoke the agent
  • how to negotiate its protocol dialect
  • how to translate prompts and events
  • how to map its capabilities
  • how to close its connection safely

ACP makes the protocol seam portable. The control plane makes the product dependable.

Takeaways

ACP standardizes communication

It gives clients and coding agents a shared interaction contract. It does not define launch, workspace, credentials, or completion evidence.

Compose before handshake

Project, environment, provider, model, and harness are product decisions. The protocol starts after those are resolved.

Keep the host a byte pipe

Discover, spawn, and transport without becoming a second ACP peer. Protocol state belongs next to the UI that presents it.

Agent-agnostic does not mean agent-identical

A control plane should expose capability differences instead of hiding them behind the lowest common denominator.