ADR 0082: ACP и MCP IDE — одна копия процесса (loopback HTTP/SSE вместо второго CascadeIDE --mcp-stdio)¶
Статус: Proposed
Дата: 2026-04-20
Связанные ADR¶
| ADR | Роль |
|---|---|
| 0048 | чат Cursor ACP, mcpServers, авто-подмешивание IDE MCP |
| 0016 | ACP, stdio, границы с MCP |
| 0008 | MCP IDE как контур |
| 0038 | фасад агента |
| 0043 | транспорт MCP; ортогонально ACP, но полезно при сбоях |
Вне ADR¶
| Документ | Роль |
|---|---|
externals/acp-csharp/.../McpServer.cs |
вендор ACP SDK (McpServer) |
Контекст¶
При включённом acp_auto_inject_ide_mcp в session/new подмешивается StdioMcpServer с тем же бинарём, что и GUI, и аргументами --mcp-stdio. Процесс cursor-agent поднимает отдельный экземпляр Cascade IDE как MCP-сервер по stdio.
Это два разных процесса: у второго — свой жизненный цикл, нет общего MainWindowViewModel, открытых вкладок редактора и прочего состояния «той» сессии, в которой пользователь ведёт чат.
Важно: режим --mcp-stdio в текущей реализации не headless — стартует полноценный Avalonia desktop lifetime с MainWindow и тем же MainWindowViewModel, параллельно поднимается MCP на stdio (App.axaml.cs: RunMcpStdio → окно + RunMcpServerAsync). На экране получается вторая полная копия приложения; при мультиоконной конфигурации workspace это легко выглядит как несколько лишних окон (например три), дублирующих chrome отдельного экземпляра. Инструменты ide_* обслуживает эта вторая копия, а не окно, где открыт чат с ACP — отсюда расхождение с ожиданием «агент управляет этим окном».
В 0048 § последствия уже зафиксировано: дублирование процессов допустимо; оптимизация «один процесс» — отдельное архитектурное решение. Этот ADR — как раз оно.
Проблема¶
- Паритет состояния: пользователь и агент должны опираться на один и тот же контекст IDE (файлы, фокус, выделение), когда речь о командах
ide_*. - Лишний процесс и дублирование UI: второй
CascadeIDE— не фоновый хост, а полный второй экземпляр с окнами; лишняя память, диск, точка отказа; путаница при отладке и визуальный шум («какой процесс смотрю в Task Manager», «зачем ещё одно главное окно»). - Текущий stdio-путь остаётся валидным для внешних хостов (Cursor запускает IDE только с
--mcp-stdio) — новое решение не обязано его ломать.
Решение (направление)¶
1. Цель¶
Для сессии чата с Cursor ACP внутри GUI Cascade IDE подмешивание cascade-ide в McpServers должно по умолчанию (или по явному флагу) указывать агенту на MCP-сервер в том же процессе, что и окно чата — без запуска второго CascadeIDE.exe.
2. Транспорт: loopback HTTP или SSE¶
В схеме Agent Client Protocol уже есть не только stdio, но и http / sse (url + headers). Направление реализации:
- В основном процессе IDE поднять локальный endpoint MCP (совместимый с тем, что ожидает клиент MCP в cursor-agent для выбранного типа сервера): например
127.0.0.1, динамический или конфигурируемый порт, только loopback (не0.0.0.0). - В
MergeForAcpNewSession(или эквиваленте при формировании списка для ACP) генерироватьHttpMcpServerилиSseMcpServerс этимurlи при необходимостиheaders(см. §3).
Выбор streamable HTTP vs SSE — зафиксировать при реализации по фактической поддержке в cursor-agent и в используемой библиотеке MCP на стороне IDE (единый контракт с существующим IdeMcpServer / McpServer.Create).
3. Безопасность¶
- Только localhost; не слушать внешние интерфейсы без отдельного решения.
- Секрет сеанса: передавать в
headers(напримерAuthorization) одноразовый или короткоживущий токен, выданный GUI при старте ACP-сессии, чтобы другой локальный процесс не мог подключиться соседним PID без знания токена. - Порт: избегать фиксированного глобального порта, конфликтующего с другими приложениями; при необходимости — выбор свободного порта + запись в снимок для
session/new.
4. Сосуществование со stdio¶
- Режим
--mcp-stdioв отдельном процессе сохранить для сценария «внешний хост (Cursor) запускает IDE как MCP» (MCP-PROTOCOL.md). - Для ACP внутри IDE: переключатель настроек или эвристика «если уже главное окно — loopback; иначе stdio» — уточнить в реализации; допустимы явные ключи в
[mcp](например транспорт для авто-подмешивания в ACP).
5. Альтернатива (не приоритет): прокси во втором процессе¶
Оставить второй процесс, но научить его проксировать вызовы в главный по IPC. Выше по сложности, дублирует контракты; рассматривать только если loopback в cursor-agent окажется неподъёмным.
Последствия¶
- Появится второй путь хостинга MCP в IDE: наряду с stdio-only в отдельном процессе — в процессе GUI (инициализация при старте ACP-сессии или лениво), с корректным shutdown при смене провайдера / закрытии чата.
- Документация MCP-PROTOCOL.md и подсказки Environment Readiness — обновить, когда появится стабильный флаг/порт.
- Тесты: интеграционные сценарии «один процесс» не должны регрессить сценарий внешнего
--mcp-stdio.
Открытые вопросы¶
- Какой тип
McpServerвsession/newгарантированно поддерживает cursor-agent для IDE MCP (приоритет проверки экспериментом). - Нужна ли стабильная привязка порта в пользовательских настройках для файрвола/скриптов.
- Поведение при нескольких окнах Cascade IDE: один endpoint на процесс приложения vs привязка к окну — уточнить с моделью 0017.