Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chapter: 9 — OpenCode’s Unique Contributions Book Title: Claude Code VS OpenCode: Architecture, Design and The Road Ahead Model: openai/gpt-5.4 Token Usage: ~2,800 tokens Generated: 2026-04-01

9.2 ACP: Agent Client Protocol

OpenCode’s support for ACP, or Agent Client Protocol, is one of its most strategically important features. The code under packages/opencode/src/acp/—especially agent.ts, session.ts, and types.ts—shows that OpenCode is not only a standalone agent runtime. It is also designed to be controlled by an external client through a formal protocol boundary. That distinction matters because it moves the system from “tool you run” to “agent engine other software can drive.”

ACP in OpenCode is implemented through the @agentclientprotocol/sdk package. At a high level, the pattern is JSON-RPC over stdio. JSON-RPC is a lightweight remote procedure call protocol where client and server exchange structured JSON messages describing methods, parameters, results, and errors. stdio means standard input and standard output, the simplest transport available to local processes. Put together, JSON-RPC over stdio creates a robust way for an editor or IDE to launch an agent process and talk to it without inventing a custom wire protocol.

This should immediately be contrasted with MCP, the Model Context Protocol. MCP standardizes how an agent talks to tools and external resources. ACP standardizes how a client application talks to the agent itself. The two protocols live at different layers. MCP is agent-to-capability. ACP is client-to-agent. That separation is conceptually clean and practically useful.

acp/types.ts contains the minimal session state structure OpenCode needs to maintain ACP-backed conversations: session ID, current working directory, MCP servers, optional model selection, variant, and mode ID. acp/session.ts then wraps this into an ACPSessionManager, which can create, load, retrieve, and update ACP sessions. This is important because editor integration is never just about sending prompts. It requires lifecycle control: restoring sessions, switching models, changing modes, and maintaining working-directory context.

The heavy lifting lives in acp/agent.ts. There, OpenCode defines an ACP.Agent class implementing the protocol-facing agent surface. The class owns the connection, references the OpenCode SDK, manages session state, subscribes to global events, translates permission requests, and emits updates back to the client. In other words, ACP is not a thin adapter. It is a full mediation layer between the OpenCode runtime and an external host.

Several details reveal why this matters. First, the ACP layer listens to OpenCode event streams and forwards meaningful updates. That lets a client stay synchronized with agent progress, usage, and permissions. Second, the ACP implementation contains explicit logic for permission handling. When the agent needs approval for an operation such as file editing, ACP can request that decision from the external client instead of assuming a terminal prompt. This is critical for IDE integration, where the approval UX may need to appear as a native editor dialog rather than a shell confirmation.

Third, OpenCode includes URI handling for editor-specific contexts. In agent.ts, parseUri includes support for zed:// URIs, directly signaling an intended integration path with the Zed editor. This is not hypothetical protocol design. It is protocol design informed by a concrete client.

Why is this such a big deal? Because most agent-integrated editors today rely on one of two awkward strategies. Either they embed the entire agent logic inside an editor extension, creating duplication and maintenance burden, or they communicate with a CLI in an ad hoc way, parsing logs and inventing custom commands. ACP offers a third path: treat the coding agent as a protocol-speaking local service that any editor can host.

That has several consequences. IDE vendors no longer need to write a totally custom plugin layer for every agent. Agent developers no longer need to maintain separate integrations for each editor from scratch. The integration point becomes standardized enough that clients can focus on user experience, while the agent runtime focuses on planning, tools, permissions, and execution.

This is especially notable when compared with Claude Code. Claude Code integrates well with editor-adjacent workflows, but its architecture is not centered on an openly inspectable client-agent protocol of this kind. Oh-My-OpenCode extends agent behavior dramatically, but it inherits OpenCode’s surfaces rather than redefining the external client protocol layer. ACP is therefore a distinct OpenCode contribution.

There is also a philosophical point here. The first protocol wave in agent systems focused on tool interoperability. That was necessary, but incomplete. If agents are to become infrastructure, the industry also needs standards for agent hosting, session control, permission mediation, streaming updates, and editor context attachment. ACP hints at this second wave.

For builders of future coding agents, the design lesson is straightforward: do not fuse the agent and the client into one inseparable application. Put a protocol boundary between them. Once that boundary exists, IDEs, terminals, notebooks, browsers, and automation systems can all speak to the same engine. OpenCode’s ACP support is an early but important step in that direction.