Перейти к содержанию

ADR 0048: Чат через Cursor ACP в IDE — цель паритета с хостом Cursor, поверхность инструментов и MCP

Статус: Accepted (частично: Cursor ACP в IDE, auto-inject MCP; полный parity — по ADR)
Дата: 2026-04-14
Обновлено: 2026-04-14 — mcp.json ↔ CIDE; «Открыть папку» в UI и MCP. Подробности — § История.

Связанные ADR

ADR Роль
0016 ACP, stdio, границы с MCP
0008 MCP IDE как отдельный контур
0038 фасад: чат / ACP / автономка / внешние MCP
0045 история чата в IDE
0043 транспорт MCP, не смешивать с ACP

Вне ADR

Документ Роль
north-star-cursor-mcp-cascade-workbench-v1.md переход из Cursor

Резюме

  • Паритет чата Cursor ACP внутри IDE: mcpServers, авто IDE MCP, разбор mcp.json ↔ CIDE.
  • Workspace «открыть папку» и пробелы тулов — зафиксированы как продуктовые задачи.
  • Внешний агент (0016) ортогонален встроенному UI чата.

Контекст

Пользователь может проводить основное время в диалоге с ассистентом (в т.ч. в Cursor), редко открывая код. Целевой сценарий для Cascade IDE — тот же класс диалога (внешний агент Cursor по ACP, уже залогиненный в CLI), но внутри IDE, с привычным workspace и без обязательного переключения в отдельное приложение Cursor для чата.

При этом хост Cursor и хост Cascade IDE — разные среды:

  • В Cursor у агента есть набор инструментов и контекста, который задаёт продукт Cursor (поиск по репозиторию, интеграции, MCP из конфига хоста и т.д.).
  • В Cascade IDE чат с тем же cursor-agent идёт через ACP-клиент в процессе IDE: базовые обратные вызовы к IDE по спецификации ACP (например fs, terminal) плюс то, что явно передано в session/new в поле mcpServers.

Без явной фиксации ожидание «как в Cursor, но в IDE» легко смешивает паритет UX диалога с паритетом всех инструментов хоста, что ведёт к разочарованию («почему нет grep / семантического поиска»).

Решение

  1. Цель продукта (направление): комфортный ежедневный диалог с тем же внешним агентом Cursor в панели чата Cascade IDE, с сохранением workspace и сценариев IDE (открытие файлов, сборка, отладка — по мере доступности через инструменты). Полное совпадение с каждой возможностью чата/агента в UI Cursor не объявляется обязательным критерием v1.

  1. Инструменты — не «встроены в модель»: возможности вроде поиска по коду, семантического поиска, обхода репозитория «как в Cursor» задаются хостом и/или подключёнными MCP-серверами, а не самим фактом запуска LLM. В контуре IDE + ACP список инструментов агента определяется:
  2. возможностями ACP и реализацией клиента IDE (IAcpClient: fs, terminal и т.д. по спецификации);
  3. списком MCP-серверов, переданных агенту при создании сессии (NewSessionRequest.mcpServers в Agent Client Protocol);
  4. политикой самого cursor-agent (что он экспонирует модели поверх этого).

  1. Связка IDE MCP (--mcp-stdio) и ACP: встроенный MCP-сервер Cascade IDE (команды ide_* для внешнего клиента MCP) и процесс cursor-agent по ACP — разные процессы и разные роли (0008, 0016). Чтобы агент в сессии ACP мог вызывать инструменты IDE тем же механизмом, что и в Cursor (отдельный stdio-процесс MCP), в session/new должен попасть соответствующий stdio-сервер. Источник этого элемента списка — см. п. 4 (ручной JSON) и п. 7–9 (направление: подмешивание по умолчанию).

  1. Единый конфиг списка MCP для автономки и для ACP: JSON массива внешних MCP в настройках ([mcp] external_servers_json / UI «Внешние MCP-серверы») используется:
  2. автономным агентом (клиент MCP в IDE — см. McpClientService);
  3. и при создании ACP-сессии: преобразование в McpServer[] для session/new (формат AgentClientProtocol: stdio / http / sse; для записей без type — тот же договор, что и для автономки: name, command, arguments, enabled, опционально env).

Запись с "enabled": true включает сервер в оба контура (как уже для автономки). При изменении JSON сессия ACP сбрасывается, чтобы следующий диалог поднял новый список MCP.

  1. Паритет с «чатом в Cursor» формулируется честно:
  2. Достижимо: тот же бинарь агента, та же авторизация Cursor, те же MCP-серверы (если прописаны), плюс инструменты ACP к IDE.
  3. Не гарантируется без доработок: идентичный набор инструментов и контекста хоста Cursor (grep/search UI, специфичные для Cursor интеграции), если они не воспроизведены отдельным MCP или возможностями IDE.

  1. История чата в IDE остаётся по 0045; выбор провайдера Cursor ACP не отменяет event log и проекции.

  1. Направление — «тулы IDE по умолчанию» для ACP (аналог хоста Cursor): в Cursor агент не обязан вручную собирать JSON: хост подмешивает конфигурацию MCP (например из mcp.json). Для Cascade IDE как хоста чата с ACP принимается направление реализации: при формировании McpServer[] для session/new опционально подмешивать (флаг в настройках; дефолт вкл/выкл — отдельное решение при внедрении) запись stdio на текущий исполняемый файл IDE и аргументы ["--mcp-stdio"], путь брать из каноничного API процесса (например путь к CascadeIDE.exe у запущенного экземпляра). Список сливать с результатом разбора external_servers_json: дедупликация по стабильному ключу (например name), приоритет явной пользовательской записи при конфликте — зафиксировать в реализации.

  1. Цель UX п. 7: агент в ACP видит инструменты ide_* «как по умолчанию», без обязательного дублирования в UI внешних MCP только ради IDE. Отдельный процесс с --mcp-stdio при этом по-прежнему допустим (тот же бинарь, другая роль); что процесс может показывать окно или нет — зависит от реализации режима --mcp-stdio, не фиксируется как инвариант ADR.

  1. Границы п. 7: авто-подмешивание IDE MCP не заменяет инструменты хоста Cursor (семантический поиск, специфичные интеграции и т.д.) и не добавляет их «магически»; расширяется только предсказуемое наличие контура ide_* в сессии ACP при включённом флаге.

Реализация в коде (на момент принятия ADR)

  • Передача mcpServers в NewSessionAsync из CascadeAcpMcpServerCatalog.FromExternalServersJson(...), источник — строка настроек внешних MCP; кэш сессии ACP учитывает изменение этой строки.
  • Подробности контрактов команд — по MCP-PROTOCOL.md.
  • П. 7–9 (авто-подмешивание IDE MCP): реализованоCascadeAcpMcpServerCatalog.MergeForAcpNewSession добавляет stdio cascade-ide (текущий Environment.ProcessPath + --mcp-stdio), если включено [mcp] acp_auto_inject_ide_mcp (по умолчанию true) и в external_servers_json нет сервера с тем же именем; CursorAcpChatConnection передаёт объединённый список в NewSessionRequest.McpServers.
  • Workspace «папка без .sln» (§ ниже): реализовано — меню Файл → Открыть папку…, кнопка на тулбаре, LoadSolution принимает путь к каталогу; MCP: ide_load_solution (путь к папке или к .sln), ide_open_folder_dialog. Детали — в том же §.

Последствия

  • Подведение итогов длинной сессии чата (внешний агент по MCP и «внутренний» контур чата IDE) зафиксировано в MCP-PROTOCOL.md (раздел «Подведение итогов сессии чата»): поддерживаемый сценарий — chat_export_readable → краткое резюме → согласование; плейбук — knowledge/playbook-session-summary-and-chat-export-v1.md в каноне agent-notes (тот же относительный путь под knowledge/). Без MCP IDE тот же смысл покрывается веткой B плейбука: agent-transcripts / архив *.jsonl, поиск сессии через rg по фразе, читаемый экспорт скриптом tools/Export-CursorJsonlTranscript.ps1 (корень репо / канон agent-notes — каталог tools/).
  • При включённом acp_auto_inject_ide_mcp явная запись cascade-ide в external_servers_json не обязательна; при конфликте имён приоритет у явной пользовательской записи.
  • Документация сценария «тулы IDE в ACP по умолчанию»: флаг [mcp] acp_auto_inject_ide_mcp, UI «Cursor ACP: автоматически передавать MCP IDE…».
  • Дублирование процессов (IDE + отдельный MCP-процесс IDE) допустимо; оптимизация «один процесс» — отдельное архитектурное решение: 0082 (loopback HTTP/SSE MCP в GUI вместо второго CascadeIDE --mcp-stdio для ACP).
  • Семантический поиск / grep «как в Cursor» либо приходит от cursor-agent и подключённых MCP, либо оформляется отдельным MCP в конфиге.

Приложение: пробелы инструментов (агент в ACP vs хост Cursor)

Цель таблиц — явная карта: чего чаще всего не хватает агенту в контуре IDE + ACP + MCP из session/new по сравнению с привычным чатом в Cursor, и где это может закрываться. Статусы не подменяют аудит IdeCommands — при расхождении приоритет у MCP-PROTOCOL.md и кода.

Легенда колонки «Покрытие»: IDE MCP — команды ide_* при подключённом сервере IDE; ACP — fs/terminal по ACP; Внешний MCP — отдельная запись в external_servers_json; Нет — нет стандартного контура; TBD — решение не зафиксировано.

Высокий приоритет (навигация и картина кода)

Потребность Зачем Покрытие (ориентир)
Поиск по смыслу по репозиторию Найти «где живёт логика X» без угадывания путей Нет / Внешний MCP (индекс, embeddings) / TBD ide_*
Массовый текстовый поиск по репо (grep/rg) Строки, символы, TODO, паттерны по дереву ACP — точечное чтение файлов; Нет repo-wide без MCP или тула
Find references / usages символа Правки без пропусков взываний Внешний MCP (например Roslyn) / частично IDE MCP — по наличию команд навигации/диагностик
Диагностики по решению (не только текущий файл) Общая картина ошибок Частично IDE MCP — зависит от экспонированных команд; TBD расширение

Средний приоритет (цикл «изменил — проверил»)

Потребность Зачем Покрытие (ориентир)
Git (status, diff, log; иногда blame) Контекст изменений Внешний MCP (git) / IDE MCP — если есть обёртки
Сборка / тесты с разбором вывода Быстрый цикл проверки IDE MCP / ACP terminal — по сценарию
Отладка (брейкпоинты, стек, шаг) Расхождение с «только текстом» Внешний MCP (dotnet-debug) / IDE MCP — по командам
Обзор структуры решения Ориентация в крупном репо Частично IDE MCP (дерево/файлы) — по командам

Ниже по списку (заметно, но реже блокирует)

Потребность Зачем Покрытие (ориентир)
Документация библиотек (Context7, MS Learn и т.д.) Меньше ошибок по API Внешний MCP
Веб (URL, снимок UI) Фронт, доки в браузере Внешний MCP (browser)
Переименование символа по решению Рефакторинг Внешний MCP (Roslyn) / TBD ide_*

Топ-3 пробела (субъективно, для приоритизации бэклога)

  1. Семантический / codebase search по репозиторию.
  2. Repo-wide grep (или эквивалент одним-двумя вызовами).
  3. Find all references / стабильный Roslyn-контур в MCP, если не покрыто ide_*.

Таблицы живые: при появлении новых ide_* или внешних MCP строки уточнять; крупные добавки — отдельные ADR или подпункты здесь по согласованию.

Разбор типичного mcp.json хоста Cursor ↔ Cascade IDE (ide_*)

Ниже — логическая карта: ключи из mcpServers (как в конфиге Cursor), тип транспорта, какой зазор из таблиц выше закрывает сервер, и пересечение с MCP самой IDE (MCP-PROTOCOL.md). Пути к exe, URL, API keys и токены намеренно не приводятся — только роли; для ACP тот же набор переносится в external_servers_json / McpServer[] с учётом типов stdio / http / sse в AgentClientProtocol.

Ключ в mcp.json Транспорт (обобщённо) Закрывает (связь с пробелами) CIDE (cascade-ide / ide_*)
context7 HTTP MCP Документация библиотек (сторонний API) Нет аналога в ide_*; остаётся внешним MCP
MS Learn Docs HTTP MCP Официальная документация Microsoft Нет аналога в ide_*; внешний MCP
Playwright stdio (npx) Браузерная автоматизация, сценарии в вебе В CIDE: превью/окна (ide_show_preview, …), не полный Playwright
dbhub stdio SQL, базы по конфигу Нет в ide_*; внешний MCP
rentahuman stdio Внешний контур «human-in-the-loop» (продукт) Нет в ide_*
roslyn stdio Символы, переходы, диагностики Roslyn, рефакторинги Дополняет IDE: в протоколе есть get_current_file_diagnostics, навигация workspace, метрики; Roslyn MCP даёт углубленный C#-контур
dotnet-debug stdio Отладка DAP: attach, step, переменные Дополняет ide_set_breakpoint / снятие и UI отладки
tinvest stdio Доменный API (брокер) Нет в ide_*
cascade-ide stdio --mcp-stdio Полная поверхность команд IDE Канон: все ide_* и ide_execute_commandIdeCommands
cascade-ide-debug stdio --mcp-stdio То же, отдельная сборка (например publish-debug) То же; удобно не смешивать с релизным процессом
agent-notes stdio Заметки/KB, ревизии, поиск по архиву Пересечение: в CIDE есть ide_write_agent_notes, ide_read_agent_notes, секции, архив, router — см. IdeCommands в MCP-протоколе; agent-notes MCP может давать дополнительный контракт (внешний репо)
webcam-mcp / webcam-capture-mcp / webcam-analysis-mcp stdio Камера, кадры, анализ Нет в ide_*; см. ADR про сенсоры при необходимости
gitlab stdio (обёртка) Удалённый GitLab: MR, wiki, pipeline CIDE: ide_git_*локальный git в каталоге решения; GitLab — другой контур
github stdio (обёртка) Удалённый GitHub API Аналогично: локальное vs GitHub
dotnet-build-test stdio Сборка/тесты, парсеры вывода (отдельный продукт) Пересечение: ide_build, ide_run_tests, ide_run_affected_tests уже дают структурированный JSON; dotnet-build-test MCP — дополнительная политика/парсинг
git stdio Операции git через GitMcp Пересечение с ide_git_status, ide_git_diff, ide_git_commit, … — разные поверхности; можно держать оба или выбрать один
kokoro-tts-mcp stdio Синтез речи Нет в ide_*
telegram-relay stdio relay в Telegram Нет в ide_*

Вывод по «пробелам» при таком хосте: строки таблицы про find references / Roslyn, сборку/тесты, отладку, git (локально), обзор workspace частично или полностью закрываются связкой cascade-ide + roslyn + dotnet-debug + git + dotnet-build-test и не требуют отдельного изобретения — нужно зеркало списка в ACP (session/new). Остаётся узким местом, если не подключено иное: семантический поиск по всему репозиторию как у некоторых хостов (в перечисленных серверах явно не выделен; возможно встроенный поиск Cursor или отдельный MCP). Repo-wide grep — не дублируется отдельной строкой; при необходимости: терминал ACP, ide_*, Roslyn или будущий MCP.

Workspace: «открыть папку» (репозиторий), а не только решение

Чтобы осмысленно строить сценарии именно по репозиторию (корень git, единый контекст для агента, будущие индексы и поиск по дереву), в Cascade IDE нужен режим Открыть папку (folder workspace) в дополнение к Открыть решение (.sln / .slnx). От корня папки задаётся тот же смысл workspace root, что и от каталога с .sln: git, пути в ide_*, терминал, MCP и ACP (cwd / GetWorkspacePath) согласованы через канонический корень (BreakpointsFileService.GetWorkspaceRoot / эквивалент: файл решения → его каталог; путь к открытой папке → сама папка).

Реализовано (код):

  • UI: пункт меню Файл → Открыть папку…, кнопка «Открыть папку» на тулбаре; диалог выбора каталога (OpenFolderPickerAsync), затем тот же вход, что и для решения: MainWindowViewModel.LoadSolution(path).
  • Модель: Workspace.SolutionPath при открытой папке хранит нормализованный путь к каталогу (не .sln). Сборка по кнопке «Собрать» не активна без файла решения — ожидаемо.
  • Дерево обозревателя: FolderWorkspaceTreeBuilder — рекурсивное дерево каталогов и файлов с отсечением по глубине/числу узлов и исключением типичных шумных каталогов (.git, bin, obj, node_modules, …). Корень — SolutionItem.CreateFolderWorkspaceRoot; иконка корня — папка.
  • Загрузка: SolutionWorkspaceViewModel.LoadSolutionTreeAsync: если путь существует как каталог — дерево папки; иначе — прежний SolutionParser для .sln / .slnx / .slnf.
  • Стартовый проект / .cascade-ide: StartupProjectStore и логика стартового .csproj используют корень workspace через GetWorkspaceRoot, чтобы .cascade-ide и относительные пути не уезжали в родитель каталога при открытой папке.
  • Терминал: рабочий каталог — каталог решения или открытая папка, если SolutionPath указывает на каталог.
  • MCP / палитра: команда load_solution (ide_load_solution) — аргумент path может быть путём к папке или к файлу решения; добавлена open_folder_dialog (ide_open_folder_dialog) — как меню «Открыть папку…». Описания в IdeCommands и сгенерированном IdeCommandsDoc / контракте обновлены.

Связь с ACP: тот же вычисляемый корень workspace для NewSessionRequest.cwd и настроек агента, что и при открытом .sln (корень репозитория = папка workspace).

Возможные доработки (не блокируют текущий ADR): тонкая настройка лимитов дерева, дополнительные фильтры расширений, отдельный заголовок окна для режима «только папка».

Открытые вопросы

  • ~~Имя флага и дефолт для п. 7~~ — зафиксировано: acp_auto_inject_ide_mcp (по умолчанию true), UI в настройках AI/чата; дедупликация по name без учёта регистра, при конфликте приоритет у явной записи в JSON.
  • Нужен ли curated пресет «чат как в Cursor» (минимальный набор MCP + подсказки) поверх п. 7.
  • Наблюдаемость: как в UI показать, какие MCP реально переданы в session/new (в т.ч. авто-подмешанные; отладка расхождений с Cursor).
  • Закрытие строк приложения «пробелы инструментов» со статусом Нет / TBD — отдельные эпики или ADR (не смешивать с п. 7–9).
  • Открыть папку — базовая реализация закрыта по § выше; остаются только улучшения (лимиты, фильтры, подписи UI).

Отклонённые альтернативы (пока)

  • Смешивание транспортов ACP и MCP IDE в одном stdio без явного списка — отклонено в пользу явной конфигурации и совместимости с форматом ACP.
  • Обещание полного паритета с Cursor host без перечисления инструментов — отклонено как вводящее в заблуждение.

История изменений

Дата Изменение
2026-04-14 разбор mcp.json ↔ CIDE; workspace «открыть папку» для сценариев по репо; реализация «Открыть папку» в UI и MCP (см. § workspace).