Building an ACP-Compatible Agent Live — Bennet Fenner, Zed
Live-building session where Bennet Fenner (Zed) creates a coding agent implementing ACP (Agent Client Protocol), covering protocol design, session lifecycle management, and tool call handling. Ends with a demo of the agent running inside Zed, illustrating both sides of the protocol.
# Channel Identity Observations — "Building an ACP-Compatible Agent Live — Bennet Fenner, Zed"
## Creator Self-Description (Explicit Claims)
- **Creator identity and affiliation:** Speaker introduces himself as "Bennett. I work at Zed," describing Zed as building "an AI code editor all written in Rust."
- **Role in the project:** Positions himself as a builder of the **Agent Client Protocol (ACP)**: "that's why we decided we need some kind of type of protocol uh called agent client protocol... similar to like MCP or uh LSP."
- **Honest framing of limitations:** Repeatedly flags his own gaps — "I'm a Rust developer. I have basically zero clue about TypeScript" — and cautions the demo code: "please don't use it in production. It's all agent generated."
## Claimed Scope and Ecosystem
- **Protocol scope:** ACP is described as a "JSON RPC based protocol" letting "agents and clients... talk to each other through through a unified interface."
- **Ecosystem claims:** Claims "a wide variety of agents already supporting this," naming **OpenCode, Cursor** (with built-in ACP mode), and clients "up to 40 that uh implement this including open claw," **JetBrains and Obsidian**.
- **Openness claims:** "It's online. It's open source. Uh you can contribute if you want."
- **Call to action:** Directs viewers to **agentclientprotocol.com** and promises to upload demo code ("it's an empty repository. I'm going to upload it in a second").
## Intended Audience (Observed)
- **Developer audience, specifically agent/tool builders:** The talk assumes familiarity with agent loops, tool calls, model APIs, and concepts like MCP and LSP without basic explanation.
- **Technical practitioners comfortable with live coding:** Format is a hands-on live build — "I'm going to do a live coding session. Let's see how well that goes" — targeting viewers who can follow TypeScript/SDK implementation in real time.
- **Conference/talk setting:** Time constraints ("am I out of time"), a Q&A, and "thank you for listening" indicate a live conference presentation audience.
## Demonstrated Presentation Patterns
- **Educational, incremental build style:** Walks from a minimal agent ("two tools. One to read a file and one to edit an existing file") through ACP compatibility step by step: initialize → sessions → prompt → session updates → tool call updates → terminal capability.
- **Transparency about failure:** Openly acknowledges live-coding issues — "Okay, something is going wrong because everything is duplicated... no time to debug right now. Sorry."
- **Concrete, observable demos:** Demonstrates streaming output ("here's Opus talking"), file reads, diffs ("the agent sends old text, new text, and then Zed does the diffing for you"), and a self-bootstrapping moment: "add a terminal tool to itself."
- **Technical depth in Q&A:** Answers questions on diff content types and transport ("the connection works over standard IO"), citing community work on remote transport by JetBrains.
## Observable Channel Positioning
- This presentation positions the channel/speaker as a **first-party authority on ACP from Zed**, aimed at developers who want to build ACP-compatible agents, with evidence grounded in both claims (ecosystem stats, open-source status) and live demonstration (working code within Zed).
- **Note:** The transcript is a single talk; no channel-wide metadata was provided, so channel-level conclusions beyond this video's presentation cannot be drawn.
# Delivery Observations — "Building an ACP-Compatible Agent Live — Bennet Fenner, Zed"
## Tone & Overall Demeanor
- **Casual, conversational engineering tone**: hedging filler words are constant ("like," "uh," "um," "kind of") throughout the talk — e.g., *"we built like an AI code editor all written in Rust"*.
- **Self-deprecating and candid about limits**: he openly flags his own inexperience — *"I'm a Rust developer. I have basically zero clue about TypeScript."*
- **Light humor about demo risk**: *"Let's see how well that goes"*, *"Let's hope the demo gods uh stay with us."*
- **Calm under live failure**: when the demo duplicates output, he doesn't panic — *"Okay, something is going on because everything is duplicated... I'm yeah, yeah, no time to debug right now. Sorry."*
## Vocabulary & Technical Framing
- **Analogy-based explanations**: introduces ACP by comparison — *"which is similar to like MCP or uh LSP. It's a JSON RPC based protocol."*
- **Recurring informal descriptors**: heavy use of **"kind of," "basically," "like," "just," "pretty simple"** to downplay complexity:
- *"it's kind of the bare minimum you need to like build a coding agent"*
- *"the way all agents basically work is the model APIs are stateless"*
- *"that's also pretty pretty simple"*
- **Explains by walking the loop/mechanism**: describes the agent loop step-by-step — *"you call the endpoint... we get like a message from the model and either it can be like a end_turn... or it can call a tool."*
## Teaching Habits & Structure
- **Incremental build pattern**: introduces minimal code first, then adds one feature at a time (streaming text → tool call updates → file proxying → terminal tool).
- **Signposting transitions**: *"So, that's one piece. The next thing though is like..."*, *"Right. So, now the question is how do we make this thing ACP compatible?"*
- **Demo-verify loop**: repeatedly builds, restarts the agent in Zed, and tests live — *"if we build again, uh we go back to Zed. I'm going to have to restart the agent... and I say, 'Hello.'"*
- **Points to debug tooling as a teaching aid**: shows the ACP debug view — *"you can see like Zed sends a session new request."*
- **Narrates expected vs. actual outcomes**: *"nothing. Which is what we expect, right?"* — using "right?" as a frequent check-in with the audience (appears dozens of times).
## Recurring Phrases (stable patterns)
- **"right?"** as a constant rhetorical verification tag.
- **"kind of" / "basically"** as qualifiers in nearly every explanation.
- **"So, yeah" / "Um, yeah"** as pivots between sections.
## Isolated Moments (not stable patterns)
- The **"bootstrap" finale** (agent adding a terminal tool to itself) is a one-off flourish: *"now we can kind of bootstrap the agent itself."*
- The **all-caps ending "YEAH."** and audience Q&A section differ in delivery style from the main talk; the transcript's capitalization there may reflect audio dynamics rather than delivery choice (uncertain).
- The **"please don't use it in production. It's all agent generated"** disclaimer appears once.
## Uncertainty Notes
- Pauses, mouse fumbles (*"Oops"*), and time-checks (*"am I out of time or do I still have"*) are directly observable but infrequent; pacing beyond these moments can't be judged from the transcript alone.
- No timestamps of pauses/audience reactions are available, so audience engagement quality cannot be assessed.
# Position Extraction: "Building an ACP-Compatible Agent Live — Bennet Fenner, Zed"
## Speaker
- **Bennet Fenner**, self-identified as working at **Zed**, an AI code editor written in Rust.
## Core Positions and Claims
### Motivation for ACP (Agent Client Protocol)
- Zed observed the rise of AI coding agent terminal UIs from major model providers (Claude Code, Codex, Gemini CLI).
- **Central question posed by Zed**: how to let users bring their agent of choice into a unified interface.
- **Position**: A protocol was needed — ACP, analogous to **MCP** or **LSP**, a **JSON RPC-based protocol** letting agents and clients communicate through a unified interface.
- Status claims: ACP is **online and open source**; supported via adapters or native modes (OpenCode, Cursor's CLI agents with built-in ACP mode); roughly **40 clients** implement it, including OpenClaw (both client and agent), JetBrains, and Obsidian.
### How Coding Agents Work (as explained)
- A minimal agent has **two tools**: read file and edit file (path + old text replaced with new text).
- The agent loop: model APIs are **stateless**; conversation is attached and resent per call. Model responses are either an **end-turn** text output or a **tool call**, executed locally, with the result fed back to the model.
### ACP Integration Requirements (claimed minimal set)
- Implement the agent interface via the TypeScript SDK; at minimum **three to four functions**:
- **initialize** — respond with protocol version; capabilities are optional and advertised by both sides; authentication "irrelevant" in this demo (env var API key).
- **session/new** — each thread in a client creates a new session; agent generates a random ID and stores the coding agent instance.
- **prompt** — receives content blocks (text, images); the demo's helper **ignores non-text content** because images aren't supported.
- **cancel** (nice-to-have) — supports cancellation.
- Zed integration claim: **no special code** needed — just tell Zed to run the agent with `node` and a path to `agent.js`.
### Session Updates Mechanism
- **Position**: tokens streaming from Anthropic must be surfaced to the client via **session/update notifications**, which can occur at any time outside request/response.
- `agent_message_chunk` is the update type for new model output; tool calls require an initial **tool_call** update, then subsequent **tool_call_update** messages to set status and return content.
- **File system proxying**: ACP proxies file system access when the client provides the capability. **Stated rationale**: editors may hold unsaved buffer changes not yet on disk, which the agent should still see.
### Live Demo Observations (with admitted uncertainty)
- Streaming text and tool calls were demonstrated working.
- **Acknowledged bug**: output was "duplicated" — he did not resolve it live ("something is going wrong because everything is duplicated").
- Connection error during the edit-file demo: "something is going wrong with the connection... no time to debug."
- A terminal-management ACP capability was demonstrated: the agent successfully added a terminal tool to itself and ran `sleep 5; ls`.
### Qualifications and Caveats
- Self-declared limited TypeScript knowledge: "I'm a Rust developer. I have basically zero clue about TypeScript."
- Demo code: **"please don't use it in production. It's all agent generated."** Repository was empty at talk time; upload promised.
- Timeframe claim: built "in 15 minutes or so" (earlier target was 10 — a slight inconsistency he acknowledged mid-talk).
### Q&A Claims
- **Diffs**: ACP has multiple content types including **diff**; agent sends old text and new text, and **Zed does the diffing**.
- **Transport**: currently works over **standard IO**; a **remote transport** is being worked on ("I think from the JetBrains people") and expected "soon" — explicitly a tentative claim ("I think").
# Speaker Attribution Record — Building an ACP-Compatible Agent Live
## Speakers
- **Bennett Fenner** (self-identified as "Bennett" / "Bennet" in transcript) — **Creator / Presenter**
- Employee at **Zed**; introduces himself as a **Rust developer** with limited TypeScript experience (self-declared).
- Sole substantive speaker throughout the talk and live-coding demo.
- **Audience / Q&A participants** (unnamed)
- Ask questions at the end (about diffs and connection transport); their questions are largely paraphrased within Bennett's responses rather than transcribed verbatim.
## Roles Summary
| Role | Holder | Evidence |
|---|---|---|
| Creator / Presenter | Bennett Fenner | Title, self-introduction |
| Q&A questioners | Unnamed audience members | Closing Q&A segment |
## Referenced Sources & Third-Party Claims
- **Zed** — Bennett's employer; AI code editor written in Rust.
- **Agent Client Protocol (ACP)** — JSON-RPC-based protocol; described as **open source** and available at **agentclientprotocol.com** (speaker-claimed).
- **Comparable protocols named**: MCP, LSP.
- **Named agents/CLIs supporting ACP** (per speaker claim): Claude Code, Codex, Gemini CLI, Open Code, Cursor (ACP mode in CLI), Open Claw (client and server).
- **Named clients** (speaker claim: "up to 40"): JetBrains, Obsidian.
- **APIs/SDKs used in demo**: Anthropic API and Anthropic SDK (TypeScript SDK for ACP); model referenced as "Opus".
- **Third-party claim**: "folks… from the JetBrains people are working on… remote transport" — attributed to Bennett, not verified.
## Promotional Segments
- Speaker promotes **ACP / agentclientprotocol.com** and invites open-source contributions ("It's open source. You can contribute if you want").
- Speaker promotes his **demo repository** (stated as not yet uploaded; "empty repository… I'm going to upload it in a second") with an explicit **use disclaimer**: "please don't use it in production. It's all agent generated."
## Provenance & Availability Notes
- **Demo code availability**: Not yet uploaded at time of talk; speaker commits to uploading it.
- **Live-demo caveats**: Speaker acknowledges a duplication bug ("everything is duplicated") and a connection issue during the demo, left undiagnosed.
- **No curated metadata was supplied** beyond title and transcript; no comment availability information provided.
I'm Bennett. I work at Zed and we built like an AI code editor all written in Rust. And last year was kind of as you probably all know the rise of the uh AI coding agent terminal user
interfaces with every major model provider like building Claude code, Codex, Gemini CLI, and so on. And so at Zed, we asked ourselves like how can we let users bring their agent of choice to our tool and enjoy like a nice interface that is unified across all of them. And so that's why we decided we need some kind of type of protocol uh called agent client protocol, uh which is similar to like MCP or uh LSP. It's a JSON RPC based protocol. And the idea is basically that uh agents and clients can talk to each other through through a unified interface. And uh yeah, the it's yeah, online. It's open source. Uh you can contribute if you want. Um at this point we have a wide variety of agents already supporting this either by like an adapter that kind of like translates um the agent's native language to the ACP one. Uh and then we have like for example open code and co- uh and cursor uh having like ACP mode built into their like CLI agents. And we also have a bunch of uh clients at this point up to 40 that uh implement this including open claw for example. Like open claw itself is a client and a server actually like a client and an agent. Um and JetBrains and Obsidian and other people are supporting this. Um Great. So, um I'm going to do a live coding session. Let's see how well that goes. Um So, Right. Uh basically, we have some pre-existing code. So, this is Zed. Uh here I have some TypeScript code. Also, bear with me. I'm I'm a Rust developer. I have basically zero clue about TypeScript. So, if you see anything that you don't do in TypeScript, tell me afterwards. Um but yeah, like here's a very minimal coding agent that just doesn't support ACP, but it's kind of the bare minimum you need to like build a coding agent.
So, all it has is really like two tools. One to read a file and one to edit an existing file. Um Yeah, this is like pretty basic. It provides the model has
to provide a path. Then it has to provide an old text that is like then just replaced with new text and that's kind of everything. And then we have uh in this case like I'm using Anthropic. Uh there's a way to prompt the agent um uh with yeah, the user can prompt the agent, which is the function that we will going to call here. And then we enter the agent loop and that is kind of like the way all agents basically work is the model APIs are stateless. So, you just attach some like conversation up to this point. You call the endpoint. In this case it's like the Anthropic API. And then we um yeah, we get like a message from the model and either it can be like a end turn. That means like the model decided to uh yeah, just output some text and do nothing or it can call a tool. And in this case it would be like a read or a write uh tool call. And then in the case of a tool call, we like run the for example the edit file tool call locally, um collect the result, and then send it up to the model again. That's where this this loop um And then we call the API again with the conversation up to that point and that's kind of everything. And then we have like these this like handle tool call function here, which yeah, handles like read and write uh tool calls, which does what you expect. We get the path. We read it from the file system and we return some some uh result. Right. So, now the question is how do we make this thing ACP compatible? And hopefully we can do it in 10 minutes. So, let's see. Um so, yeah, I have some boilerplate here. Uh in this case I'm using the TypeScript SDK as I said. Um and the way this works, you implement uh the agent interface provided by this uh library. And then you have to at minimum implement these three uh four functions. So, the first one that we're looking at is kind of this initialize here. Um all we really have to do here is like respond with the protocol version we
support, which in this case is just the latest. There's also like some capabilities like client and uh the agent can itself advertise capabilities of stuff it supports, but we're building
a very minimal coding agent, so we don't support anything outside that's necessary, I guess. Um then for us like authentication is irrelevant since it's just using my API key from an env var. And then there's this concept of sessions in ACP. So, basically every time you start a thread in Zed or in a different editor or client, uh you you call a new session. And in a session you can prompt and then yeah, from there on you can like get get your output. So, all we really do here is like we generate a random ID. Um then we um instantiate uh this coding agent with the current working directory, which we get from the client. Um we store it in our internal map and then just return the ID to the client so that the client knows um yeah, knows the ID and that is kind of then used inside prompt. Um because what prompt does in this case, um it like prompt the prompt request, if we go to the definition here, all this is kind of doing is uh it provides a prompt, which is an array of content blocks that can be like text, images, whatever, the session ID for reference. And so all we kind of have to do here is yeah, we look it up in our internal state. We get the relevant agent uh for that uh current session. And then I have a help helper function here, which just in this case ignores
everything that's not a text because we don't support images and stuff like this. Um and then we call this like prompt function I showed earlier, which then uh runs tool calling loop.
And so then just like as a nice to have uh feature, we also support cancellation. Uh that's also pretty pretty simple. So, these are kind of like the four minimal things we have to implement. And I have this hooked up in Zed just by there's no special code. All I have is kind of like I tell Zed there's some ACP compatible agent and you can run it with node and then my path to that agent.js file. Um so, when I uh let's do that in here as well. So, when I run, I'm going to build. Um I'm going to build, right? And then I'm going to restart uh yeah, launch a new ACP demo agent. And you can see if I ask it for something, you can see wait indicator. And now it's done. So, nothing. Which is what we expect, right? Because like what we can see here, if I go over Oops. Um If I go over here, we have some kind of like ACP debug view in Zed. So, to make it easier for us to develop. And you can see like Zed sends a session new request. We respond with a session ID and as soon as I type in something,
we get prompt. And now we got a stop reason, right? So, these red arrows come from the uh from the adapter that we are building from the agent. But
it's not outputting tokens, right? Like behind the scenes it's obviously like Anthropic is giving us tokens, but how do we make them show up in Zed? So, that's the next thing that we uh yeah, want to focus on. So, the first thing that we kind of need to do, like our coding agent itself uh needs to have a way to um send something over to the connection. So, what we're going to do here is like the coding agent is going to take the ACP connection and then also the session ID. And then inside here, we have to provide this uh connection and the ID. And then if we go Okay, I'm just going to close this. Right. If we go back here, now inside of uh prompt, Anthropic like this is the Anthropic SDK. So, in this case like in Oops. You can just use um this like stream on uh Yeah, that's like a Anthropic SDK. Like you can react to a text event. So, every time we basically get a chunk, uh we send this kind of what ACP calls a session update. As I said, a session is like a single thread or a conversation. And then you can send updates kind of like notifications to the client that are not like a usual request response, right? It can happen at any time and the client reacts to it. And so here we are associating with the session update with a session ID. And then this like There's a type of session updates. There are multiple. We will see more in a second. But this agent message chunk is just like, "Okay. Hey, here's some new output from the model." And so if we build again, uh we go back to Zed. I'm going to have to restart the agent. I go here and I say, "Hello."
Hello. Hello. Well, here's Opus talking, right? You can see like we're streaming in these individual uh
chunks, right? Right, that we got from Anthropic. So, so far so good. Let's hope the demo gods uh stay with us. Um Right. So, that's one piece. The next thing though is like I want to like it's a coding agent, right? It's supposed to edit code. So, I can actually tell it already because we have tool support, right? I can tell it to read, for example, this like helpers .ts file and it's going to give me if the Wi-Fi isn't too slow, it's giving me a description of what this file actually contains. Like if you look here, that's basically the description of the file, but again, you don't see it in the UI, right? So, now we need to emit more session updates, similar to like what we did for text. So, if we actually go towards the read file, kind of what we need to do here is like the way it works usually in ACP, like you emit an initial tool call update, uh which I'm going to paste in here. So, yeah, again we're emitting a session update in this in this case, it's uh type of tool call. And then there are multiple properties we can specify, for example, like the title, kind of some kind of data um
that Z uses, for example, for like yeah, using some icons and stuff like this. And then we indicate that the status is in progress, and you can also like associate tool calls with like actual uh
locations. And so, now we signaling over ACP that something is in progress, right? This tool call. But then we also want to at the end, like once the tool call has finished, like at the bottom here, we kind of want to send another update. And in this case it's not tool call itself, but it's a tool call update. So, you have to emit on the agent, you have to emit like a tool call, like session update of type tool call, and then once once the client knows about it, uh you can emit updates for that. Uh and this is the way that we set the status, and we can also return the content. Um and then one additional thing that I'm going to do here is the um instead of like if you can see here, we're calling, I guess it's a bit hard to see, but like here we're calling fs.readFile, right? So, we're just using the native file system APIs. But MC uh ACP actually proxies the file system too. Like the client can provide a uh a file system capability, and if it does, um we can like proxy those uh file system tool calls over ACP. And it kind of makes sense, for example, for an editor, right? You want to um if I have unsafe changes in my buffer, they're not actually on the file system, but the agent should still see them. So, that's why we call this like uh read text file um over ACP. And so, now if we go back here and hit npm run build, and then go back here, restart, and say read uh this file. Oops, not the rust. Then we should be seeing um
Yeah, so now we see read tool calls, right? Okay, something is going wrong because everything is duplicated. Um
yeah, but like here you can see the output um of the actual file. And because I think I'm low on time, um we're we're going to basically going to do the same for edit file. Um and I'm going to compile again. And if I again restart, and say add a comment at the top of agent source agent.typescript, then you're going to see um uh hello world is good. Hopefully, clo- uh Opus is going to decide to add hello world at the top of the file, and we actually get a diff here because the over ACP we send like a diff of the file. Okay. Yeah, I think there's something going wrong with the connection. I'm yeah, yeah, no time to debug right now. Sorry. Uh am I out of time or do I still have Okay, maybe like we can see. So, now that Okay, just another minute. Um now that the coding agent supports reading and writing files, we can actually Oh, great. Uh okay, then I don't need to rush. Um now we can kind of bootstrap the agent itself, right? Like the coding agent supports reading and writing files. I can just ask it, I prepared a prompt here, to add a terminal tool to itself, right? Let's see how this works out with like the duplication we're seeing. Uh but basically I'm telling it some something about the ACP um APIs, and there's some there's some APIs in ACP which also, that's another like capability of the client, where the client can um advertise that it supports creating terminal and managing terminals for the agent. Like the agent can also do it itself, of course. Um but it's a nice way uh for us to add
some more interactivity. And so, the agent here decided to add a new tool description. Now it yeah, I'm live coding basically this terminal tool.
Um and let's see if it actually builds. It does. Well, that's good. Um and then again, I'm going to going to restart the agent. I'm going to run our demo agent, and I'm going to ask it to run sleep five ls. Let's see. There you go. You can see a terminal running, sleeping 5 seconds. There is the output. And there's Yeah, and that's it, basically. Thank you. Yeah, so that's how you kind of build an ACP compatible coding agent in 15 minutes or so. Um yeah, if you want to uh check it out, just go to agentclientprotocol.com. Um in case anyone wants the demo code, but please don't use it in production. It's all agent generated. Um it's not upload it yet, but it it's an empty repository. I'm going to upload it in a second. Uh yeah, thank you for listening. Happy to answer questions. That's it. YEAH. UH THE DIFFS UH YEAH, WE HAVE LIKE IN in ACP there are multiple content types, and one content type is diff, and so the agent sends old text, new text, and then Z does the diffing for you. Yeah. Yeah. Cool. Do I need to go or can I Okay, one more question. Yes. Yeah, the connection works over standard IO. Uh there are some folks well, I think from the JetBrains people are working on like remote uh transport, uh which we're going to have soon, I think. So, yeah. But right now it works over standard IO. Yeah.
