Turn any local LLM (Ollama, llama.cpp, OpenAI-compatible) into an Agent Client Protocol-compatible agent. Spawn it from Zed, JetBrains, ACP UI, Meuxe, or Codex CLI — your data stays on your machine.
You write code in your editor. Your editor spawns acp-bridge as a subprocess and talks to it through JSON-RPC over stdin/stdout. acp-bridge talks to your local LLM (Ollama, llama.cpp, vLLM, LM Studio — anything OpenAI-compatible) over its native HTTP API. Tool calls stay on your box.
acp-bridge negotiates the protocol version with each Client at init time. The table below shows which Client speaks which version today and what you can expect.
| Client | ACP version | acp-bridge wire | Tested |
|---|---|---|---|
| Zed | v1 | v1 | ✓ via zed_style.rs e2e |
| JetBrains IDEs | v1 | v1 | ✓ mirrors Zed shape |
| ACP UI | v1 | v1 | ✓ via inspector_style.rs e2e |
| ACP Inspector | v1 | v1 | ✓ via inspector_style.rs e2e |
| Meuxe | v1 | v1 | ✓ — issue #13 fixed |
| Codex CLI adapter | v1 (minimal) | v1 | ✓ via minimal_style.rs e2e |
| Claude Code (Claude Agent SDK) | v1 | v1 | interop verified manually |
| OpenCode | v2 (preview) | v1 (negotiated) | will negotiate v2 once OpenCode ships v2 |
acp-bridge implements ACP v1 fully and ACP v2 on the same code base. The negotiation is automatic: at init the Client sends its preferred protocolVersion, acp-bridge picks the highest version both sides support, and every subsequent notification uses the corresponding wire shape.
| Concept | v1 wire | v2 wire |
|---|---|---|
initialize response | agentInfo + agentCapabilities | Unified info + capabilities |
image capability | true / false | {} (marker) or omit |
| Tool start notification | tool_call with toolCallId + kind + status: "in_progress" | tool_call_update with the same fields (legacy tool_call not emitted) |
| Plan | {sessionUpdate: "plan", entries[]} | {sessionUpdate: "plan_update", plan: {type: "items", planId, entries[]}} |
| End-of-turn | (none) | state_update with stopReason |
tool_calls field — the agent stalled on such rounds. acp-bridge now strips think-tag scaffolding and recovers embedded tool-call JSON (fenced or bare) into the normal tool dispatch. 185 tests passing.session/close and session/list, Ollama native tool.arguments object handling, and web_fetch redirect re-validation. 171 tests passing.protocolVersion at init; emit v1 or v2 wire shape accordingly. Same code base, dispatch by version.One binary. Negotiation at init picks the right wire shape per Client. Today that means Zed / JetBrains / ACP UI / Meuxe / Codex CLI on v1, future v2-only Clients on v2.
read_file, list_dir, search_code, write_file, edit, web_fetch (opt-in), bash, git_status / git_diff / git_log / git_commit. Sandboxed to the session working dir.
Single 5 MB static Rust binary. No npm. No models.dev fetches. No LSP. Outbound only to the configured LLM endpoint, opt-in via LLM_WEB_ALLOWLIST.