Forge
markdowndeeb25a2
1<!-- English translation of adr/0016-agent-client-protocol-external-agent.md. Canonical Russian: ../../adr/0016-agent-client-protocol-external-agent.md -->
2
3# ADR 0016: External agent using Agent Client Protocol (stdio, Cursor CLI)
4
5**Status:** Accepted · Implemented
6**Date:** 2026-04-05
7## Related ADRs
8
9| ADR | Role |
10|-----|------|
11| [0008](0008-mcp-contracts-and-testable-infrastructure.md) | MCP - **other** circuit: IDE tool server; not to be confused with ACP |
12
13### Outside ADR
14
15| Document | Role |
16|----------|------|
17| [note-acp-cascade-cursor-v1.md](../ui-ux/note-acp-cascade-cursor-v1.md) | terminology and specification links |
18| [concept-pfd-mfd-cascade-v1.md](../ui-ux/concept-pfd-mfd-cascade-v1.md) | concept pfd mfd cascade v1 |
19
20### Implementation snapshot
21
22| Element | Meaning |
23|---------|----------|
24| — | Cursor ACP / stdio in chat and settings; orthogonal to MCP - see text |
25
26---
27## Context
28
29You need to connect the built-in CascadeIDE chat with an **external** agent (primarily **Cursor** via the official CLI and ACP mode), without embedding the UI Cursor and without your own wire “from scratch”.
30
31**Agent Client Protocol (ACP)** is an open client↔agent contract (JSON-RPC by string, typical transport **stdio**). PoC passed: chat responses, Russian text, session and callbacks to the IDE (fs, terminal) according to the specification.
32
33## Solution
34
351. **Transport:** subprocess `cursor-agent` (or equivalent from the dist-package) with argument **`acp`**, **stdin/stdout** for protocol, no console window (`CreateNoWindow`), stream redirection.
36
372. **Encoding:** for **Windows** explicitly set **UTF-8** for redirected stdin/stdout/stderr of the agent process (and for child ACP-terminal processes), otherwise responses in Russian are decoded in OEM and give “crazy messages”.
38
393. **Client SDK:** library **AgentClientProtocol** (community, upstream [acp-csharp](https://github.com/nuskey8/acp-csharp)) - **vendor** in `externals/acp-csharp/` as sources, connected via `ProjectReference`. Sources under `externals/**/*.cs` are **not** compiled in the main IDE assembly (`Compile Remove` in `CascadeIDE.csproj`) so that the nested sandbox with top-level `Main` does not intercept the application entry point.
40
414. **Integration into the product:** separate chat provider (**Cursor ACP**), setting the path to `cursor-agent.cmd` or to the directory with `dist-package`; ACP session lifecycle and terminal/fs mirroring - in `Services/CursorAcp/`.
42
435. **Cursor authentication:** not interactive inside WinExe chat on first launch; the user passes the **`agent login` / API key** in a normal terminal or through environment variables (as in the Cursor documentation). Agent errors before UI - as development progresses, stderr can be duplicated into chat/log (not part of this ADR).
44
456. **Boundaries:** ACP is about **dialogue with an external agent**. The MCP server IDE (`--mcp-stdio`, agent tools) remains a separate loop ([0008](0008-mcp-contracts-and-testable-infrastructure.md)); combining scenarios with subsequent iterations.
46
47## Consequences
48
49- Upstream `acp-csharp` updates - conscious merge/vendoring; when changing the major ACP specification - checking compatibility with `cursor-agent`.
50- Dependency on CLI Cursor format (argument `acp`); when Cursor documentation changes - manual regression or smoke script.
51- Duplication of types when erroneously including SDK sources and package references - prevented by `Compile Remove` for `externals`.
52
53## Rejected alternatives
54
55- **Ollama only / local LLM only without ACP** - remains a different provider; does not cover the “same agent as in Cursor” scenario.
56- **Own binary protocol over stdio** - rejected in favor of the ACP standard and a ready-made client SDK.
57- **Embedding webview Cursor** is outside the scope of the ACP desktop client.
58
59## Discussion (does not block Accepted)
60
61- Submodule instead of vendoring `externals/acp-csharp` - migration is possible when the update process stabilizes.
62- Output stderr of the agent in the chat UI in case of errors and “Authentication required”.
View only · write via MCP/CIDE