AI coding agents are becoming more capable, but the way they connect to editors is still surprisingly fragmented.
Imagine that an editor wants to support five coding agents. Without a shared protocol, the editor may need five custom integrations. Each integration has to handle prompts, streamed responses, file access, terminal output, tool calls, permissions, diffs, session history, and cancellation.
The same problem exists on the other side. An agent developer who wants to support five editors may need to implement five different editor APIs.
That creates a growing integration matrix:
Agent A Agent B Agent C
Editor 1 ✓ ✓ ✓
Editor 2 ✓ ✓ ✓
Editor 3 ✓ ✓ ✓
Every new row or column creates more custom work.
The Agent Client Protocol, usually called ACP, is an attempt to replace that matrix with one shared contract.
ACP standardizes communication between coding agents and the clients that present them to users.
The client is often an IDE or code editor, but it can also be a terminal UI, desktop application, web interface, notebook, or another agent-facing product.
The simplest mental model is:
LSP connects editors to language intelligence. ACP connects editors to coding agents.
In this post, I explain what ACP does, how its session and permission flows work, how it differs from MCP, and what I would consider before building on it.
The Problem ACP Solves
An editor integration for a coding agent is much more than a chat box.
A useful coding-agent UI may need to:
- send text, images, and file context
- stream the agent’s response
- show the agent’s plan
- display tool calls and their progress
- ask the user to approve sensitive actions
- render file diffs
- show live terminal output
- let the agent read unsaved editor content
- cancel a running turn
- preserve and restore sessions
- expose model, mode, or reasoning options
If every agent invents its own message format for these features, editor developers spend their time writing adapters. If every editor exposes a different agent API, agent developers face the same problem in reverse.
ACP creates a shared boundary:
┌──────────────────────────┐
│ Client │
│ IDE, editor, TUI, or UI │
└────────────┬─────────────┘
│
│ ACP
│ prompts, updates, permissions,
│ diffs, terminals, sessions
│
┌────────────▼─────────────┐
│ Coding agent │
│ model loop + agent tools │
└────────────┬─────────────┘
│
│ MCP, APIs, local tools
│
┌────────────▼─────────────┐
│ External capabilities │
│ GitHub, databases, docs │
└──────────────────────────┘
Once an agent speaks ACP, any compatible client can provide a UI for it. Once a client supports ACP, it can connect to compatible agents without learning a completely new protocol for each one.
This does not make every agent identical. Agents can still use different models, planning strategies, tools, memory systems, and permission policies. ACP standardizes the communication surface, not the internal intelligence.
Why ACP Is Compared With LSP
The comparison with the Language Server Protocol is useful because the integration problem is similar.
Before LSP, an editor often needed a custom implementation for each programming language. A language tool also needed custom support for each editor.
LSP introduced a common interface for features such as:
- autocomplete
- go to definition
- diagnostics
- symbol lookup
- refactoring
ACP applies the same interoperability idea to agents.
| Protocol | Connects | Standardizes |
|---|---|---|
| LSP | Editor ↔ language server | Language intelligence such as diagnostics and completion |
| ACP | Client ↔ coding agent | Agent conversations, tools, permissions, diffs, terminals, and sessions |
| MCP | AI application ↔ tools and context | Access to external data sources and capabilities |
The analogy is not perfect. A coding agent is more stateful, autonomous, and interactive than a traditional language server. It may run commands, edit many files, pause for permission, use external tools, and continue through several model calls before completing one user request.
That is why ACP needs concepts beyond simple request and response.
ACP Is Not MCP
ACP and the Model Context Protocol are complementary, but they solve different problems.
MCP connects an AI application to tools, resources, and external context.
For example, an agent may use MCP to access:
- a GitHub repository
- a database
- internal documentation
- a browser
- an issue tracker
ACP connects the agent to the user-facing client.
It carries the interaction between the editor and the agent:
- the user’s prompt
- streamed agent messages
- tool-call status
- approval requests
- file diffs
- terminal output
- session state
A real system can use both:
Developer
│
▼
Editor or agent UI
│
│ ACP
▼
Coding agent
│
│ MCP
▼
Tools and data sources
The ACP architecture also allows the client to pass MCP server configuration when it creates a session. The agent can then connect to those MCP servers directly.
My rule of thumb is:
If the question is “How does the user interface talk to the agent?”, think ACP.
If the question is “How does the agent reach a tool or data source?”, think MCP.
How ACP Communicates
ACP v1 uses JSON-RPC 2.0. It has two basic message shapes:
- methods, which are request-response pairs
- notifications, which are one-way events and do not receive a response
For local use, the client normally starts the agent as a subprocess. The two sides exchange newline-delimited JSON-RPC messages over standard input and standard output.
Editor starts agent process
editor ── JSON-RPC request ──> agent stdin
editor <─ JSON-RPC response ── agent stdout
editor <─ update notification ─ agent stdout
This transport is simple, fast, and well suited to a local editor. The ACP transport documentation says messages must be UTF-8 JSON-RPC, separated by newlines. Logs belong on stderr; stdout must remain valid protocol traffic.
Remote agents are part of the direction of the project, but this is an area where it is important to read the current status carefully. The introductory documentation discusses HTTP and WebSocket for remote scenarios, while the stable v1 transport page still describes Streamable HTTP as a draft in progress.
The ACP Lifecycle
A normal ACP conversation follows four broad stages.
1. Initialize the connection
Before creating a session, the client calls initialize.
This is where the client and agent negotiate:
- the ACP protocol version
- client capabilities
- agent capabilities
- implementation information
- available authentication methods
A simplified request looks like this:
{
"jsonrpc": "2.0",
"id": 0,
"method": "initialize",
"params": {
"protocolVersion": 1,
"clientCapabilities": {
"fs": {
"readTextFile": true,
"writeTextFile": true
},
"terminal": true
},
"clientInfo": {
"name": "my-editor",
"version": "1.0.0"
}
}
}
The agent responds with the version it selected and the features it supports.
This capability negotiation is important. A client should not assume that every agent accepts images, restores sessions, connects to every MCP transport, or supports every optional feature. Likewise, an agent should not assume that every client exposes filesystem or terminal methods.
The current stable wire protocol version is 1. The repository also contains a v2 draft, so implementers should distinguish stable v1 behavior from proposals that have not stabilized.
2. Create a session
After initialization and authentication, the client can call session/new.
{
"jsonrpc": "2.0",
"id": 1,
"method": "session/new",
"params": {
"cwd": "/home/nitin/project",
"mcpServers": []
}
}
The agent returns a unique sessionId.
A session represents one conversation or work thread. It has its own context and state. One connection can support multiple sessions, which means a client can maintain separate agent tasks without starting a completely new integration for each one.
ACP also defines session-management features such as listing, loading, resuming, closing, and deleting sessions, but support is capability-driven. Clients must check what the agent advertises before calling optional methods.
3. Send a prompt and stream updates
The user message arrives through session/prompt.
{
"jsonrpc": "2.0",
"id": 2,
"method": "session/prompt",
"params": {
"sessionId": "sess_abc123",
"prompt": [
{
"type": "text",
"text": "Find the bug in the authentication flow."
}
]
}
}
The prompt is an array of content blocks rather than one plain string. ACP reuses MCP’s content-block representation where possible, so a prompt can include text, resource links, and—when capabilities allow them—images, audio, or embedded resources.
The agent does not have to remain silent until the work is complete. It sends session/update notifications as the turn progresses.
Those updates can represent:
- agent message chunks
- thought chunks
- plans
- tool calls
- tool-call status changes
- available slash commands
- mode changes
- context and cost usage
This is what allows a client to render an agent as an active workflow instead of a spinner followed by a wall of text.
4. Finish or cancel the turn
When the turn ends, the agent responds to the original session/prompt request with a stop reason.
Examples include:
end_turnmax_tokensmax_turn_requestsrefusalcancelled
The client can interrupt ongoing work by sending a session/cancel notification. The agent should stop model requests and tool invocations as soon as possible, resolve pending permission requests, and finish the prompt with the cancelled stop reason.
This may sound like a small detail, but consistent cancellation behavior matters when an agent is running expensive model calls or a long terminal command.
Tool Calls Are Designed for the UI
One of ACP’s most useful ideas is that tool execution is not treated as invisible internal activity.
When the model asks to read a file, edit code, search, fetch data, or run a command, the agent can report a structured tool call with:
- a unique tool-call ID
- a human-readable title
- a kind such as
read,edit,delete,search, orexecute - a status such as
pending,in_progress,completed, orfailed - affected file locations
- input, output, and displayable content
The client can use this information to show a meaningful activity feed.
Instead of:
Working...
the user can see:
✓ Read src/auth/session.ts
✓ Searched for refreshToken
● Running authentication tests
○ Update token expiry handling
ACP also has coding-specific output types. A tool result can contain a file diff, and it can reference a live terminal created through the client. This is a good example of the protocol’s UX-first design: a generic chat protocol would not know how an editor should render a code modification or a running process.
Permissions Are Bidirectional
JSON-RPC traffic in ACP is bidirectional.
The client calls methods on the agent, but the agent can also call methods on the client.
Permission requests are the clearest example. Before a tool executes, the agent can call session/request_permission and provide choices such as:
- allow once
- always allow
- reject once
- always reject
The client presents those choices according to the user’s settings and returns the selected result.
This separation is useful:
- the agent describes the action it wants to perform
- the client owns the user interaction
- the user or client policy makes the authorization decision
ACP does not make a dangerous tool safe by itself. The agent still needs sensible tool design, and the client still needs an appropriate trust and approval policy. The protocol gives both sides a consistent way to represent the decision.
Why the Client Owns Filesystem and Terminal Capabilities
At first, it may seem strange for the agent to ask the editor to read a file when the agent process could read the filesystem directly.
The editor may know more than the disk does.
For example, a developer can modify a file without saving it. If the agent reads only the on-disk version, it may analyze stale code. ACP’s fs/read_text_file method lets the client return the text it currently knows about, including unsaved editor state.
Client-mediated writes also let the editor track modifications and integrate them with its own buffers, undo history, and UI.
Terminal methods follow a similar pattern. The client can create and manage a terminal, stream its output, expose the running command inside a tool call, and let the user see what is happening.
These methods are optional. The client advertises them during initialization, and the agent must check support before using them.
What ACP Standardizes—and What It Does Not
ACP standardizes the interface, but it deliberately leaves many implementation choices open.
It standardizes:
- protocol and capability negotiation
- authentication flow
- session lifecycle
- prompts and streamed updates
- structured content blocks
- tool-call reporting
- permission requests
- file and terminal integration
- plans, diffs, modes, and configuration options
- cancellation and stop reasons
It does not standardize:
- which language model an agent uses
- how the agent plans
- the agent’s system prompt
- how memory and compaction work
- which tools the agent has
- how much autonomy the agent should receive
- how an editor designs its UI
- the quality of the agent’s code changes
That boundary is healthy. A protocol should make implementations interoperable without forcing them to become identical.
The Ecosystem Is Already Broader Than One Editor
The current ACP documentation lists clients across editors, terminal applications, desktop and web interfaces, notebooks, mobile apps, and messaging tools. It also lists many compatible agents and adapters, including implementations around Codex CLI, Claude Agent, Gemini CLI, GitHub Copilot, Cline, Goose, OpenCode, and others.
The ACP Registry provides a curated way to discover and distribute compatible agents. Official SDKs are listed for Kotlin, Java, Python, Rust, and TypeScript.
The exact list changes quickly, so I would use the live agents and clients pages instead of copying an old compatibility table into project documentation.
The important signal is not that every combination is perfect today. It is that the ecosystem is converging on a shared integration layer.
Where ACP Still Has Rough Edges
ACP is promising, but I would keep several caveats in mind.
Remote transport is still evolving
Local subprocess communication over stdio is well defined. The remote story is actively developing, and the stable and draft documentation do not yet describe it with the same finality.
Capability combinations create testing work
ACP avoids breaking changes by adding optional capabilities. That is flexible, but it means implementations must behave correctly across many combinations.
An agent may support session restore but not images. A client may support file reads but not terminals. A feature that works in one client-agent pairing may be unavailable in another for a valid reason.
Adapters can hide mismatches
An existing agent does not need a native ACP implementation if an adapter translates between ACP and the agent’s own protocol. That accelerates adoption, but an adapter may not expose every underlying feature perfectly.
Compatibility should be tested at the workflow level, not assumed from the presence of an ACP process.
A protocol does not replace product judgment
Showing every internal thought, automatically approving every command, or rendering raw tool output without context can still create a poor experience.
ACP provides useful primitives. Clients and agents still need to make good decisions about trust, clarity, interruption, error handling, and information density.
My Take
The most important thing about ACP is not JSON-RPC or stdio. It is the separation of concerns.
An editor should not need to understand the internal architecture of every coding agent. An agent should not need to understand the private UI protocol of every editor.
They need a shared language for:
- what the user asked
- what the agent is doing
- what changed
- what needs approval
- when the work is finished
That is the layer ACP is trying to become.
LSP made it normal for one language server to work across many editors. MCP is making it easier for AI applications to reach many tools. ACP could do the same for the connection between coding agents and the interfaces developers use every day.
The protocol is still developing, especially for remote agents and the future v2 wire format. But the architectural direction makes sense:
let editors compete on experience, let agents compete on capability, and give them a standard way to work together.