Forge
markdown5e452b8e
1# DotnetDebugMcp
2
3**Автор:** Дмитрий Каратаев (Dmitry Karataev)
4
5MCP-сервер для отладки .NET (C#) через **DAP** (netcoredbg): брейкпоинты, запуск, стек, переменные, шаги, continue/stop.
6
7**Cursor:** примеры правил для копипаста — **[docs/cursor-rules-examples.md](docs/cursor-rules-examples.md)**.
8
9## Требования
10
11- .NET 10
12- [netcoredbg](https://github.com/Samsung/netcoredbg); путь в переменной `NETCOREDBG_PATH` или в параметре **netcoredbg_path** при launch.
13
14## Сборка и запуск
15
16```bash
17cd dotnet-debug-mcp
18dotnet build
19dotnet run
20```
21
22Сервер работает по **stdio** (MCP-клиент запускает процесс и общается через stdin/stdout).
23
24## Публикация exe (для MCP в Cursor)
25
26### Быстрый локальный publish (рекомендуется)
27
28`publish-and-deploy.ps1` делает publish self-contained `win-x64`, зеркалит в фиксированный путь (по умолчанию `D:\dotnet-debug-mcp`) и гасит процесс, если он лочит файлы:
29
30```powershell
31.\publish-and-deploy.ps1
32```
33
34### Релизы (zip + GitLab upload)
35
36`scripts/publish-release-win.ps1` — мультиплатформенный сценарий (win/linux/osx): упаковка в zip и загрузка в GitLab Generic Packages/Release.
37
38```bash
39dotnet publish DotnetDebugMcp.csproj -c Release -o publish
40```
41
42В конфиге MCP укажи **command** — путь к `DotnetDebugMcp.exe` в папке `publish`, **args** — `[]`.
43
44## Каталог тулов (автогенерация)
45
46Полный список имён и текстов `description` — в [`docs/MCP-TOOLS.md`](docs/MCP-TOOLS.md); машиночитаемый манифест — [`mcp-tools.manifest.json`](mcp-tools.manifest.json). Обновление из корня репозитория `dotnet-debug-mcp`:
47
48```bash
49dotnet run --project tools/ExportMcpManifest -- --write
50```
51
52## Инструменты
53
54| Инструмент | Описание |
55|------------|----------|
56| **debug_ping** | Проверка доступности сервера. |
57| **debug_set_breakpoints** | Записать брейкпоинты: workspace_path, target_path (.dll/.exe), breakpoints[] (file_path, line; опционально condition). Файл `.dotnet-debug-mcp-breakpoints.json` в workspace. |
58| **debug_list_breakpoints** | Показать сохранённые брейкпоинты (по workspace, опционально по target_path). |
59| **debug_clear_breakpoints** | Удалить брейкпоинты (по workspace или по target_path). |
60| **debug_launch** | Запустить отладку: workspace_path, target_path; опционально **netcoredbg_path**, **program_args** (массив строк — аргументы для целевой программы). Загружает брейкпоинты, передаёт в DAP setBreakpoints, ждёт первого события stopped (до 5 с). |
61| **debug_attach** | Подключиться к уже запущенному .NET-процессу по **process_id** (PID). workspace_path обязателен; опционально **target_path** (путь к .dll/.exe процесса) — тогда загружаются сохранённые брейкпоинты для этого target. |
62| **debug_continue** | Продолжить выполнение (DAP continue). |
63| **debug_step_over** | Шаг через строку (DAP next). |
64| **debug_step_into** | Шаг в вызов (DAP stepIn). |
65| **debug_step_out** | Шаг из кадра (DAP stepOut). |
66| **debug_stop** | Завершить сессию (dispose клиента). |
67| **debug_stack_trace** | Стек вызовов текущего потока (DAP stackTrace). При необходимости сервер ждёт остановки (до 5 с) и повторяет запрос при временных ошибках. |
68| **debug_variables** | Переменные кадра (frame_index=0 по умолчанию). Сначала запрос **scopes** по frameId, затем **variables** по variablesReference каждого scope (netcoredbg отдаёт переменные через scopes); при ошибке — fallback на variables(frameId). |
69
70## Рекомендации по отладке
71
72- **Собирай цель в Debug**, не Release: путь к `bin/Debug/net10.0/YourApp.dll` в target_path и при set_breakpoints. Иначе брейкпоинты могут не срабатывать (пути в PDB).
73- **Пути:** `file_path` в брейкпоинтах и `target_path` могут быть относительными — они разрешаются относительно **workspace_path**, чтобы совпадать с путями в PDB при сборке из этого каталога.
74- **Условный брейкпоинт:** в `debug_set_breakpoints` у каждого брейкпоинта можно указать **condition** — выражение на C# (например `i > 10`, `name == "test"`). Остановка только когда условие истинно; удобно для цикла или часто вызываемого метода.
75- Если целевая программа без аргументов сразу выходит — передай **program_args** (например `["dummy"]`), чтобы выполнение дошло до нужной строки.
76
77## Пример сценария
78
791. `debug_set_breakpoints` — workspace_path, target_path (путь к .dll), breakpoints: [{ file_path, line: 7 }].
802. `debug_launch` — те же workspace_path, target_path; при необходимости program_args.
813. `debug_stack_trace` → стек.
824. `debug_variables` → переменные (Locals и др. по scopes).
835. `debug_step_over` → следующий шаг.
846. `debug_continue` → продолжить.
857. `debug_stop` → завершить сессию.
86
87## Поведение
88
89- После **debug_launch** сервер ждёт первое событие **stopped** (до 5 с); при таймауте пробует получить threadId через запрос **threads**.
90- При вызове **debug_stack_trace**, **debug_variables**, **debug_step_*** без остановки сервер ждёт следующее **stopped** (до 5 с).
91- При временных ошибках DAP (например «target is running», 0x80004005) запросы повторяются до 3 раз с паузой 250 ms.
92- Событие **continued** сбрасывает «текущий поток»; следующий stack_trace/variables снова ждут **stopped**.
93
94## Отпускание приложения
95
96- Чтобы приложение снова выполнялось после остановки на брейкпоинте — вызывай **debug_continue**. После этого можно снова вызывать stack_trace/variables (сервер будет ждать следующего stopped до 5 с).
97- **debug_stop** перед отключением отправляет **continue** целевой программе, чтобы она не оставалась зависшей. После stop сессия завершена; для новой отладки нужен снова **debug_launch**.
98- Перед **пересборкой** целевого проекта вызывай **debug_stop**: netcoredbg держит открытыми exe/dll и PDB целевого процесса; пока сессия активна, копирование PDB при сборке может падать (файл занят netcoredbg.exe).
99- В глубоких стеках **debug_step_over** / **debug_step_into** иногда могут оставить приложение без ответа; в таком случае вызови **debug_stop** (он сделает continue и отключится) или заверши процесс netcoredbg снаружи. При обрыве netcoredbg сервер сбрасывает сессию (OnConnectionLost) и не падает.
100
101## Планы (что не покрыто)
102
1031. ~~Проверить **debug_step_into** и **debug_step_out**, а также **debug_stop** после step~~ **Проверено:** step_into заходит в вызов (Main → Foo → Bar), step_out возвращает в вызывающий кадр (Bar → Foo → Main). debug_stop после step отрабатывает: continue и dispose без зависания.
1042. ~~Прогнать на практике условный брейкпоинт~~ **Проверено:** condition передаётся в DAP, остановка только при истинном условии (например `i == 2` в цикле). При желании — прогнать **program_args** при launch.
1053. При желании — таймаут/отмена для DAP-запросов; уточнить в доке про параллельные вызовы stack_trace/variables.
106
107## Лицензия
108
109MIT. См. [LICENSE](LICENSE).
110
View only · write via MCP/CIDE