Technology & Engineering · Deep

MCP and ACP: two protocols that make AI programs talk

Both are thin layers of newline-delimited JSON that let one program drive another, and both exist so nobody has to write a custom integration for every pair of tools. This page shows what each protocol connects, what actually travels over the wire, and where the two plug into each other inside a coding agent.

Read the original MCP introduction ↗

Userwrites one prompt
EditorACP client
AgentACP server, MCP client
MCP serverstools and data
One conversation crosses two protocols: the editor speaks ACP to the agent, and the agent speaks MCP to its tools.

Two protocols, one problem: nobody wants N × M integrations

Before any standard existed, connecting an AI application to an external service meant writing bespoke glue for each pair: one integration for your editor talking to one agent, another for that agent talking to GitHub, a third for the database, and so on. With N applications and M tools, the work grows as N × M. Both MCP and ACP attack this multiplication, but at different layers of the stack. [Introduction]

MCP (Model Context Protocol) connects an AI application to external systems: files, databases, APIs, browsers. Its own documentation calls it "a USB-C port for AI applications." ACP (Agent Client Protocol) connects a code editor to an autonomous coding agent: the program that reads your repository, plans edits, runs commands, and reports back. [ACP introduction]

Underneath, both are dialects of JSON-RPC 2.0, a minimal messaging rule: every message is a UTF-8 JSON object that is either a request (carries an id and a method, expects a response echoing that id), a response (carries the same id plus a result or error), or a notification (no id, one-way, never answered). Nothing else is required: no schemas in the envelope, no session tokens, no streaming format. [JSON-RPC]

DimensionMCPACP
ConnectsAI app ↔ tools and dataEditor ↔ coding agent
Core unitTool, resource, prompt (stateless calls)Session: a long, stateful conversation turn
Who calls whomClient sends requests; server answers (recent spec: servers do not initiate requests)Bidirectional: agent sends streaming notifications and can call the editor back
OriginAnthropic, open-sourced November 2024Zed, in collaboration with Google, 2025
AnalogyUSB-C for peripheralsLSP (Language Server Protocol), but for agents

MCP standardizes the tool plane; ACP standardizes the conversation plane. An agent that codes uses both at once, which is why they are easy to confuse.

MCP is a pipe with newline-delimited JSON, wrapped around a small set of primitives

An MCP deployment has three roles. The host is the AI application (Claude Code, VS Code, ChatGPT). For every configured server the host instantiates one client, and each client holds a dedicated connection to one server — the program that actually knows how to touch the filesystem, query the database, or call an API. [Architecture]

How that connection works is the transport layer, and there are exactly two standard answers. Stdio: the host spawns the server as a child process and writes one JSON-RPC message per line into its stdin; the server replies on stdout, also one message per line, and may write human-oriented logs to stderr, which the host may capture or ignore. There is no network, no port, no handshake beyond the protocol itself. Streamable HTTP: each message is an HTTP POST to a single MCP endpoint, with the reply arriving either as a plain JSON object or as a request-scoped text/event-stream for long-running work; authentication rides on standard HTTP headers. Protocol semantics are identical on both bindings — only framing and delivery change. [Transport spec]

Message direction is deliberately asymmetric: clients send requests and notifications, servers send responses and notifications, and nothing else exists. Cancellation follows the binding — a notifications/cancelled message on stdio, closing the response stream on HTTP. [Transport spec]

Spawnhost starts child process
server/discoverversions and capabilities
tools/listnames and JSON Schemas
tools/callarguments in, content out
The MCP data layer in order: discovery, then listing, then execution — all plain request/response pairs.

The data layer defines what the messages mean. Servers expose three primitives: tools (executable functions with a JSON Schema for arguments — the ones the model decides to call), resources (readable data such as a file's contents or a database schema), and prompts (reusable templates for structuring conversations). Each has discovery methods (tools/list, resources/list), and tools add tools/call for execution. Clients discover what a server supports with server/discover, which returns the supported protocol versions and a capabilities object, for example {"tools": {"listChanged": true}}. Every later request also carries the protocol version and the client's own capabilities in a metadata field, so the design can treat requests as self-contained. [Architecture]

A concrete turn looks like this — first the listing, then one call:

--> {"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}
<-  {"jsonrpc":"2.0","id":2,"result":{"tools":[
      {"name":"weather_current","description":"Current weather...",
       "inputSchema":{"type":"object","properties":
         {"location":{"type":"string"}},"required":["location"]}}]}}
--> {"jsonrpc":"2.0","id":3,"method":"tools/call",
     "params":{"name":"weather_current","arguments":{"location":"San Francisco"}}}
<-  {"jsonrpc":"2.0","id":3,"result":{"content":[
      {"type":"text","text":"68°F, partly cloudy..."}]}}

Tool results are arrays of typed content blocks — text, images, embedded resources — not bare strings, so a server can return a screenshot next to a sentence. Servers can also announce change: after a client opens a subscription stream asking for toolsListChanged, the server emits a one-way notifications/tools/list_changed whenever its tool set changes, and the client reacts by listing again. [Architecture]

ACP turns one user message into a long, cancellable stream of typed events

ACP's setup is simpler to state: the editor boots the agent as a subprocess on demand, and everything flows over stdin/stdout as newline-delimited JSON. Messages must not contain embedded newlines; stdout carries nothing but valid ACP messages; stderr is free for logs. One connection multiplexes several concurrent sessions, so two threads of thought can run side by side. [ACP transports]

Every connection begins with an initialize request. The client names the newest protocol version it knows (a single integer — breaking changes bump it) and its capabilities, such as whether it can serve file reads, file writes, and terminal methods. The agent answers with the version it will speak and its own capabilities: whether it can load old sessions, and what content its prompts accept (text always; images, audio, embedded context optionally). If the two cannot agree on a version, the client closes the connection and tells the user. [Initialization]

--> {"jsonrpc":"2.0","id":0,"method":"initialize","params":{
      "protocolVersion":1,
      "clientCapabilities":{"fs":{"readTextFile":true,"writeTextFile":true},
                            "terminal":true}}}
<-  {"jsonrpc":"2.0","id":0,"result":{"protocolVersion":1,
      "agentCapabilities":{"loadSession":true,
        "promptCapabilities":{"image":true}}}}

Then comes the shape that makes ACP different from MCP: a prompt turn. The client sends session/prompt with content blocks; that single request stays open — a pending JSON-RPC request — while the agent streams progress back as session/update notifications, each tagged with a variant field. The variants are the editor's UI vocabulary: agent_message_chunk (streamed answer text), agent_thought_chunk (reasoning), tool_call and tool_call_update (a tool appearing, moving to in_progress, finishing with content), plan (the to-do list the agent is following), usage_update (tokens used and dollars spent), plus mode, slash-command, and session metadata updates. Only when the work ends does the agent answer the original request with a stopReason such as end_turn, max_tokens, refusal, or cancelled. [Prompt turn]

session/promptuser message, request stays open
session/updateplan, chunks, tool_call
request_permissionagent asks the editor
tool_call_updatein_progress → completed
stopReasonend_turn closes the request
One ACP turn: a single request answered at the end, with everything in between arriving as notifications.

Two design choices carry most of ACP's weight. First, traffic is bidirectional. While the prompt request is pending, the agent can issue its own requests back to the editor: session/request_permission before running a dangerous command, fs/read_text_file and fs/write_text_file to touch the workspace through the editor rather than directly, terminal/create to run shell commands in a managed pane, and elicitation/create to ask the user a structured question. The agent never needs its own filesystem privileges — the editor is the gatekeeper. [ACP overview]

Second, interruption is first-class. The client may send session/cancel at any moment; it then marks unfinished tool calls as cancelled and answers any pending permission requests with a cancelled outcome, while the agent must abort model calls and in-flight tools and — critically — must convert whatever exception its libraries throw into the meaningful cancelled stop reason, because editors display raw errors to users. [Prompt turn]

The two protocols meet inside the agent

An ACP agent is typically also an MCP client. When the editor forwards your prompt, it passes along the configuration of the MCP servers you have set up, and the agent connects to them itself — that is how your filesystem, Sentry, or Postgres tools become visible to a Gemini or Claude agent running under ACP. If the editor wants to offer its own tools to such an agent, it does not try to run MCP and ACP on one socket: it starts a small MCP server proxy that tunnels MCP requests back to the editor. [ACP architecture]

ACP was also built to reuse MCP's homework: it is JSON-RPC-based and re-uses MCP's JSON types wherever possible so integrators do not maintain two representations of the same content, and agents advertise their MCP transport support (http, sse) during initialization. [ACP architecture] [Initialization]

ChooseWhenCost
MCPYou are exposing a capability (query, read, act) to any AI applicationNo notion of a conversation; you manage state yourself
ACPYou are building an editor UI over a stateful, streaming, permission-asking agentHeavier session machinery; smaller ecosystem than MCP
BothEvery serious coding agent: ACP to the editor, MCP to the toolsTwo specs to keep up with

Their histories show two different paths to legitimacy

  1. NOV 2024Anthropic open-sources MCP as an internal project turned public standard. [LF press]
  2. SEP 2025Google's Gemini CLI becomes the reference ACP agent in Zed, the first proof the editor-and-agent split works. [Zed ACP]
  3. OCT 2025Claude Code arrives in Zed over ACP, through a dedicated adapter. [Zed ACP]
  4. DEC 2025Anthropic donates MCP to the Agentic AI Foundation under the Linux Foundation, co-founded with Block and OpenAI; MCP reports 97M+ monthly SDK downloads and roughly 10,000 published servers. [AAIF announcement]
  5. NOWMCP's specification is dated 2026-07-28 and ACP ships a stable v1 with a v2 draft published for review. [Transport spec] [v2 draft]

The pattern is the opposite of each other: MCP began as one company's protocol and spent a year buying neutrality through a foundation; ACP began as one editor's protocol and grew by getting rival editors and agents to adopt it — its ecosystem now lists Zed, JetBrains, VS Code, Emacs and Neovim as clients, and Claude, Codex, Gemini CLI and others as agents. [Zed ACP]

How the ideas connect

FromRelationTo
Pipes and subprocessesenablesstdio transport in both protocols
JSON-RPC 2.0formalized-by (from the protocol's view)MCP and ACP message format
LSP precedentenablesACP's editor/agent split
Primitivespart-ofMCP data layer
Capability negotiationpart-ofMCP discovery and ACP initialize
Session updatespart-ofACP prompt turn
ACPrequiresMCP (agents consume MCP tool servers)
MCPenablestool registries and connectors
ACPenableseditor-agnostic agents
MCPcontrasts-withACP (tool plane vs conversation plane)

Edges follow the descriptions in the MCP architecture overview and the ACP architecture page. [Architecture] [ACP architecture]

What this does not show

Three limits deserve explicit words. First, the moving target: MCP's revision history is aggressive — recent versions moved to per-request metadata and deprecated server-initiated requests such as model sampling, and ACP's v2 draft would restructure the prompt lifecycle and permission model, so any wire-level detail here should be re-checked against the current spec before you implement it. [Transport spec] [v2 draft] Second, remote ACP is unfinished: stdio dominates both protocols today, and ACP's own documentation marks streamable HTTP for agents as a draft in progress, so cloud-hosted agents are not yet a first-class story. [ACP transports] Third, this page assumes trust it does not examine: ACP is explicitly designed for an editor talking to a model you trust, where the editor hands the agent filesystem and MCP access; the permission requests are the control surface, and how strictly an implementation gates them is a security question this page does not answer. [ACP architecture] Also out of scope: model quality, prompt design, and any performance comparison — the protocols only guarantee delivery of messages, not what the model does with them. [Architecture]

Go deeper

References

  1. MCP — What is the Model Context Protocol?Supports the USB-C framing, the N×M integration problem, and the ecosystem of clients (Claude, ChatGPT, VS Code, Cursor). Sections "What is MCP" and "Why does MCP matter".
  2. MCP — Architecture overviewSupports host/client/server roles, the data-layer and transport-layer split, the three server primitives, discovery via server/discover, content blocks, and notification semantics. Sections "Participants", "Layers", "Primitives", "Notifications".
  3. MCP specification — TransportsSupports stdio and Streamable HTTP bindings, message-direction rules, cancellation per binding, custom transports, and the 2026-07-28 revision date with backward-compatibility notes.
  4. ACP — IntroductionSupports the editor/agent decoupling argument, the LSP comparison, and local (stdio) versus remote (HTTP/WebSocket) scenarios.
  5. ACP — ArchitectureSupports the MCP-friendly design principle, subprocess boot over stdin/stdout, concurrent sessions, bidirectional requests for permissions, forwarding MCP server configuration to agents, and the MCP-proxy pattern.
  6. ACP v1 — OverviewSupports the baseline method list (initialize, session/new, session/prompt), client methods (fs, terminal, elicitation, request_permission), the message flow, and camelCase conventions.
  7. ACP — TransportsSupports newline-delimited framing rules, the stdout/stderr contract, streamable HTTP being in draft, and custom transport requirements.
  8. ACP — InitializationSupports the initialize request/response examples, integer protocol version negotiation, client and agent capability objects, and MCP transport capabilities (http, sse).
  9. ACP — Prompt TurnSupports the full turn lifecycle, the session/update variant table, permission requests during tool calls, usage updates, stop reasons, and cancellation rules including the MUST-catch-errors requirement.
  10. JSON-RPC 2.0 SpecificationSupports the definitions of request, response, and notification objects, id correlation, and the error object both protocols reuse.
  11. MCP joins the Agentic AI FoundationSupports the December 9, 2025 donation date, the Linux Foundation / AAIF governance structure, 97M+ monthly SDK downloads, and roughly 10,000 active servers.
  12. Zed — Agent Client ProtocolSupports the Apache-licensed open standard claim, the editor and agent ecosystem lists, Gemini CLI arriving September 3, 2025, and Claude Code in Zed on October 2, 2025.
  13. Linux Foundation press release — Agentic AI Foundation formedSupports the November 2024 open-sourcing date, founding contributions from Anthropic, Block, and OpenAI, and adoption across Claude, Cursor, Copilot, Gemini, VS Code, and ChatGPT.
  14. ACP announcement — v2 available in draftSupports the claim that a v2 protocol revision is published in draft form for review alongside stable v1.