Forge
markdowndeeb25a2
1# ADR 0082: ACP и MCP IDE — одна копия процесса (loopback HTTP/SSE вместо второго `CascadeIDE --mcp-stdio`)
2
3**Статус:** Proposed
4**Дата:** 2026-04-20
5## Связанные ADR
6
7| ADR | Роль |
8|-----|------|
9| [0048](0048-cursor-acp-chat-ide-parity-and-mcp-tool-surface.md) | чат Cursor ACP, `mcpServers`, авто-подмешивание IDE MCP |
10| [0016](0016-agent-client-protocol-external-agent.md) | ACP, stdio, границы с MCP |
11| [0008](0008-mcp-contracts-and-testable-infrastructure.md) | MCP IDE как контур |
12| [0038](0038-agent-facade-ai-provider-and-tool-orchestration.md) | фасад агента |
13| [0043](0043-mcp-transport-recovery-human-agent-parity.md) | транспорт MCP; ортогонально ACP, но полезно при сбоях |
14
15### Вне ADR
16
17| Документ | Роль |
18|----------|------|
19| [`externals/acp-csharp/.../McpServer.cs`](../../externals/acp-csharp/src/AgentClientProtocol/Schema/McpServer.cs) | вендор ACP SDK (McpServer) |
20
21---
22## Контекст
23
24При включённом **`acp_auto_inject_ide_mcp`** в `session/new` подмешивается **`StdioMcpServer`** с тем же бинарём, что и GUI, и аргументами **`--mcp-stdio`**. Процесс **`cursor-agent`** поднимает **отдельный** экземпляр Cascade IDE как MCP-сервер по stdio.
25
26Это **два разных процесса**: у второго — свой жизненный цикл, **нет** общего `MainWindowViewModel`, открытых вкладок редактора и прочего состояния «той» сессии, в которой пользователь ведёт чат.
27
28**Важно:** режим **`--mcp-stdio` в текущей реализации не headless** — стартует полноценный Avalonia desktop lifetime с **`MainWindow`** и тем же `MainWindowViewModel`, параллельно поднимается MCP на stdio ([`App.axaml.cs`](../../App.axaml.cs): `RunMcpStdio` → окно + `RunMcpServerAsync`). На экране получается **вторая полная копия приложения**; при мультиоконной конфигурации workspace это легко выглядит как **несколько лишних окон** (например три), дублирующих chrome отдельного экземпляра. Инструменты `ide_*` обслуживает **эта** вторая копия, а не окно, где открыт чат с ACP — отсюда расхождение с ожиданием «агент управляет **этим** окном».
29
30В [0048 § последствия](0048-cursor-acp-chat-ide-parity-and-mcp-tool-surface.md) уже зафиксировано: дублирование процессов допустимо; оптимизация «один процесс» — **отдельное** архитектурное решение. Этот ADR — как раз оно.
31
32---
33
34## Проблема
35
361. **Паритет состояния:** пользователь и агент должны опираться на **один и тот же** контекст IDE (файлы, фокус, выделение), когда речь о командах `ide_*`.
372. **Лишний процесс и дублирование UI:** второй `CascadeIDE` — не фоновый хост, а **полный второй экземпляр** с окнами; лишняя память, диск, точка отказа; путаница при отладке и визуальный шум («какой процесс смотрю в Task Manager», «зачем ещё одно главное окно»).
383. **Текущий stdio-путь остаётся валидным** для внешних хостов (Cursor запускает IDE только с `--mcp-stdio`) — новое решение **не** обязано его ломать.
39
40---
41
42## Решение (направление)
43
44<a id="adr0082-p1"></a>
45
46### 1. Цель
47
48Для сессии **чата с Cursor ACP внутри GUI Cascade IDE** подмешивание **`cascade-ide`** в `McpServers` должно по умолчанию (или по явному флагу) указывать агенту на **MCP-сервер в том же процессе**, что и окно чата — без запуска второго `CascadeIDE.exe`.
49
50<a id="adr0082-p2"></a>
51
52### 2. Транспорт: loopback HTTP или SSE
53
54В схеме Agent Client Protocol уже есть не только `stdio`, но и **`http`** / **`sse`** (`url` + `headers`). Направление реализации:
55
56- В **основном процессе** IDE поднять **локальный** endpoint MCP (совместимый с тем, что ожидает клиент MCP в **cursor-agent** для выбранного типа сервера): например **`127.0.0.1`**, динамический или конфигурируемый порт, только **loopback** (не `0.0.0.0`).
57- В **`MergeForAcpNewSession`** (или эквиваленте при формировании списка для ACP) генерировать **`HttpMcpServer` или `SseMcpServer`** с этим `url` и при необходимости **`headers`** (см. §3).
58
59Выбор **streamable HTTP vs SSE** — зафиксировать при реализации по фактической поддержке в **cursor-agent** и в используемой библиотеке MCP на стороне IDE (единый контракт с существующим `IdeMcpServer` / `McpServer.Create`).
60
61<a id="adr0082-p3"></a>
62
63### 3. Безопасность
64
65- Только **localhost**; не слушать внешние интерфейсы без отдельного решения.
66- **Секрет сеанса:** передавать в `headers` (например `Authorization`) **одноразовый или короткоживущий токен**, выданный GUI при старте ACP-сессии, чтобы другой локальный процесс не мог подключиться соседним PID без знания токена.
67- Порт: избегать фиксированного глобального порта, конфликтующего с другими приложениями; при необходимости — выбор свободного порта + запись в снимок для `session/new`.
68
69<a id="adr0082-p4"></a>
70
71### 4. Сосуществование со stdio
72
73- Режим **`--mcp-stdio`** в отдельном процессе **сохранить** для сценария «внешний хост (Cursor) запускает IDE как MCP» ([MCP-PROTOCOL.md](../../MCP-PROTOCOL.md)).
74- Для ACP внутри IDE: переключатель настроек или эвристика «если уже главное окно — loopback; иначе stdio» — уточнить в реализации; допустимы явные ключи в **`[mcp]`** (например транспорт для авто-подмешивания в ACP).
75
76<a id="adr0082-p5"></a>
77
78### 5. Альтернатива (не приоритет): прокси во втором процессе
79
80Оставить второй процесс, но научить его **проксировать** вызовы в главный по IPC. Выше по сложности, дублирует контракты; рассматривать только если loopback в **cursor-agent** окажется неподъёмным.
81
82---
83
84## Последствия
85
86- Появится **второй путь** хостинга MCP в IDE: наряду с **stdio-only** в отдельном процессе — **в процессе GUI** (инициализация при старте ACP-сессии или лениво), с корректным **shutdown** при смене провайдера / закрытии чата.
87- Документация [MCP-PROTOCOL.md](../../MCP-PROTOCOL.md) и подсказки Environment Readiness — обновить, когда появится стабильный флаг/порт.
88- **Тесты:** интеграционные сценарии «один процесс» не должны регрессить сценарий внешнего `--mcp-stdio`.
89
90---
91
92## Открытые вопросы
93
941. Какой тип **`McpServer`** в `session/new` гарантированно поддерживает **cursor-agent** для IDE MCP (приоритет проверки экспериментом).
952. Нужна ли **стабильная привязка** порта в пользовательских настройках для файрвола/скриптов.
963. Поведение при **нескольких окнах** Cascade IDE: один endpoint на процесс приложения vs привязка к окну — уточнить с моделью [0017](0017-multi-window-workspace-and-agent-surfaces.md).
97
View only · write via MCP/CIDE