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 / семантического поиска»).
Решение¶
- Цель продукта (направление): комфортный ежедневный диалог с тем же внешним агентом Cursor в панели чата Cascade IDE, с сохранением workspace и сценариев IDE (открытие файлов, сборка, отладка — по мере доступности через инструменты). Полное совпадение с каждой возможностью чата/агента в UI Cursor не объявляется обязательным критерием v1.
- Инструменты — не «встроены в модель»: возможности вроде поиска по коду, семантического поиска, обхода репозитория «как в Cursor» задаются хостом и/или подключёнными MCP-серверами, а не самим фактом запуска LLM. В контуре IDE + ACP список инструментов агента определяется:
- возможностями ACP и реализацией клиента IDE (
IAcpClient: fs, terminal и т.д. по спецификации); - списком MCP-серверов, переданных агенту при создании сессии (
NewSessionRequest.mcpServersв Agent Client Protocol); - политикой самого cursor-agent (что он экспонирует модели поверх этого).
- Связка 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 (направление: подмешивание по умолчанию).
- Единый конфиг списка MCP для автономки и для ACP: JSON массива внешних MCP в настройках (
[mcp] external_servers_json/ UI «Внешние MCP-серверы») используется: - автономным агентом (клиент MCP в IDE — см.
McpClientService); - и при создании ACP-сессии: преобразование в
McpServer[]дляsession/new(формат AgentClientProtocol:stdio/http/sse; для записей безtype— тот же договор, что и для автономки:name,command,arguments,enabled, опциональноenv).
Запись с "enabled": true включает сервер в оба контура (как уже для автономки). При изменении JSON сессия ACP сбрасывается, чтобы следующий диалог поднял новый список MCP.
- Паритет с «чатом в Cursor» формулируется честно:
- Достижимо: тот же бинарь агента, та же авторизация Cursor, те же MCP-серверы (если прописаны), плюс инструменты ACP к IDE.
- Не гарантируется без доработок: идентичный набор инструментов и контекста хоста Cursor (grep/search UI, специфичные для Cursor интеграции), если они не воспроизведены отдельным MCP или возможностями IDE.
- История чата в IDE остаётся по 0045; выбор провайдера Cursor ACP не отменяет event log и проекции.
- Направление — «тулы 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), приоритет явной пользовательской записи при конфликте — зафиксировать в реализации.
- Цель UX п. 7: агент в ACP видит инструменты
ide_*«как по умолчанию», без обязательного дублирования в UI внешних MCP только ради IDE. Отдельный процесс с--mcp-stdioпри этом по-прежнему допустим (тот же бинарь, другая роль); что процесс может показывать окно или нет — зависит от реализации режима--mcp-stdio, не фиксируется как инвариант ADR.
- Границы п. 7: авто-подмешивание IDE MCP не заменяет инструменты хоста Cursor (семантический поиск, специфичные интеграции и т.д.) и не добавляет их «магически»; расширяется только предсказуемое наличие контура
ide_*в сессии ACP при включённом флаге.
Реализация в коде (на момент принятия ADR)¶
- Передача
mcpServersвNewSessionAsyncизCascadeAcpMcpServerCatalog.FromExternalServersJson(...), источник — строка настроек внешних MCP; кэш сессии ACP учитывает изменение этой строки. - Подробности контрактов команд — по MCP-PROTOCOL.md.
- П. 7–9 (авто-подмешивание IDE MCP): реализовано —
CascadeAcpMcpServerCatalog.MergeForAcpNewSessionдобавляет stdiocascade-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 пробела (субъективно, для приоритизации бэклога)¶
- Семантический / codebase search по репозиторию.
- Repo-wide grep (или эквивалент одним-двумя вызовами).
- 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_command → IdeCommands |
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). |