The Agent Client Protocol (ACP): A Complete Technical Guide

ACP — the Agent Client Protocol — is an emerging open standard that allows any editor to communicate with any AI coding agent through a unified, JSON‑RPC–based interface. If LSP standardized language servers, ACP is doing the same for AI assistants.

This guide explains ACP from first principles, including architecture, message types, streaming, tool calling, and how to integrate ACP with your own model backends (like a WebSocket → Ollama gateway).

What ACP Is

ACP is a transport‑agnostic protocol that defines how editors and AI agents communicate. It uses JSON‑RPC 2.0 as its message envelope and supports:

ACP is designed to be editor‑agnostic and agent‑agnostic.

Why ACP Exists

Before ACP, every editor had to integrate every AI agent separately:

This created a combinatorial explosion of integrations.

ACP collapses this into a single standard, just like LSP did for language servers.

ACP Architecture

ACP defines a clean separation of concerns:

Editor  ⇄  ACP Agent  ⇄  Model Backend

ACP does not care what model you use — only how messages are exchanged.


JSON‑RPC 2.0 Primer

ACP uses JSON‑RPC 2.0 for all communication.

Request

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "requestExplanation",
  "params": { "code": "func main() {}" }
}

Response

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "This function does nothing."
}

Notification (no response expected)

{
  "jsonrpc": "2.0",
  "method": "progress",
  "params": { "id": 1, "content": "Thinking..." }
}

ACP uses notifications heavily for streaming.


Core ACP Message Types

ACP defines a set of high-level operations:

Initialization

File Operations

User Requests

Agent Responses

Streaming

Tool Calling

Lifecycle


Streaming in ACP

ACP supports streaming via progress notifications.

Example:

{
  "jsonrpc": "2.0",
  "method": "progress",
  "params": {
    "id": 42,
    "content": "First, the program initializes..."
  }
}

Editors render these tokens incrementally.


Tool Calling

ACP includes a built‑in tool calling mechanism similar to OpenAI’s function calling.

Agent → Editor

{
  "jsonrpc": "2.0",
  "method": "toolCall",
  "params": {
    "id": 99,
    "tool": "search",
    "arguments": { "query": "raft consensus" }
  }
}

Editor → Agent

{
  "jsonrpc": "2.0",
  "method": "toolCallResult",
  "params": {
    "id": 99,
    "result": "RAFT is a consensus algorithm..."
  }
}

This enables:


Sessions and State

ACP sessions track:

Sessions allow multi-turn reasoning and context retention.


ACP vs LSP

Feature LSP ACP
Purpose Language servers AI coding agents
Transport stdio/TCP stdio/TCP/WebSocket
Streaming No Yes
Tool calling No Yes
Multi-turn chat No Yes
Diff application Yes Yes
Contextual reasoning No Yes

ACP is essentially LSP + AI + streaming + tool calling.


Building Your Own ACP Agent

An ACP agent is simply:

  1. A process that reads JSON‑RPC messages from stdin or a socket
  2. Processes them
  3. Sends JSON‑RPC responses back

A minimal agent loop looks like:

for {
    msg := readJSONRPC()
    switch msg.Method {
    case "initialize":
        sendCapabilities()
    case "requestExplanation":
        handleExplanation(msg)
    case "toolCallResult":
        resumeToolCall(msg)
    }
}

The agent is responsible for:


ACP + WebSocket Gateway Architecture

If you have a WebSocket → Ollama gateway, your ACP agent becomes the orchestrator:

Editor → ACP Agent → WebSocket Gateway → Ollama

ACP Agent Responsibilities

Gateway Responsibilities

This separation keeps your ACP agent clean and backend‑agnostic.


End-to-End Message Flow

1. Editor → ACP Agent

{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "requestExplanation",
  "params": { "code": "func main() {}" }
}

2. ACP Agent → Gateway

{"model":"llama3.1:8b","prompt":"Explain this code: func main() {}"}

3. Gateway → ACP Agent (streaming)

"First, the program..."
"Then it..."
"[DONE]"

4. ACP Agent → Editor (streaming)

{
  "jsonrpc": "2.0",
  "method": "progress",
  "params": { "id": 7, "content": "First, the program..." }
}

5. ACP Agent → Editor (final)

{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "explanation": "This Go program defines an empty main function..."
  }
}

Conclusion

ACP is the missing glue layer between editors and AI agents. It standardizes:

By pairing ACP with a backend‑agnostic gateway (like a WebSocket → Ollama bridge), you can build a universal AI coding agent that works in any editor without custom plugins.

ACP is to AI agents what LSP was to language servers — a unifying protocol that simplifies everything.