C#代码重构MCP服务

RoslynMcp是一款MCP服务器,通过Roslyn为C#项目提供代码结构分析、符号查找、重命名、代码操作与诊断等能力,适用于AI代理辅助C#代码重构场景。

  • by AI-Guiders
  • C#
  • 本地部署
  • 更新于
在 GitHub 查看 KarataevDmitry/RoslynMcp

使用说明

RoslynMcp

MCP-сервер (stdio) — тонкая обёртка над AIGuiders.RoslynMcp.Core (../guiders-core/src/RoslynMcp.Core). Вся семантика Roslyn (code actions, rename, diagnostics) живёт в Core; этот репозиторий — MCP host + манифест тулов.

MCP-сервер для помощи агенту при рефакторинге C#: доступ к Roslyn (синтаксические деревья, семантика, символы, find usages, rename, code actions). Цель — стабильный тул без глюков (альтернатива Bifrost).

Cursor: примеры .cursor/rules для копипаста — docs/cursor-rules-examples.md.

Текущий статус: работают roslyn_ping, roslyn_get_document_symbols, roslyn_get_symbol_at_position, roslyn_find_usages, roslyn_go_to_definition, roslyn_rename, roslyn_get_code_actions, roslyn_apply_code_action, roslyn_get_diagnostics, roslyn_get_workspace_navigation_context (эвристики «связанных файлов» по MSBuild solution; не эквивалентно дереву файлов Cascade IDE — см. описание тула).

MSBuild workspace

Семантическая навигация (roslyn_get_workspace_navigation_context)

Источник файлов — документы, которые поднимает MSBuildWorkspace по переданному .sln/.csproj, а не произвольное дерево из IDE. Встроенные пресеты (peers_only, no_namespace_noise, tests_and_peers, structure_only) задаются аргументом preset или своими include_kinds / exclude_kinds.

Свойство RoslynMcpWorkspace и блокировка DLL анализаторов при dotnet build

RoslynMcp всегда передаёт в MSBuild свойство RoslynMcpWorkspace=true вместе с отключением design-only сборки (см. ServiceLayer/RoslynMcpWorkspaceProperties.cs). Это не привязка к конкретному репозиторию: любой .csproj может при желании проверять $(RoslynMcpWorkspace) и, например, не подключать ProjectReference на локальный проект Roslyn-анализатора (OutputItemType="Analyzer"), пока workspace открыт через MCP.

Зачем: процесс RoslynMcp иначе может держать загруженной ту же сборку в bin\…, которую dotnet build затем перезаписывает — на Windows это даёт «file is being used by another process». Отключение такой ссылки только при RoslynMcpWorkspace=true оставляет обычные сборки и CI без этого флага с полным набором анализаторов; детали опт-in — в документации того решения, где условие добавлено.

Source generators (MVVM Toolkit и др.)

Для проектов с source generators (например [ObservableProperty] / [RelayCommand] в CommunityToolkit.Mvvm) roslyn_get_diagnostics поднимает сгенерированные документы через GetSourceGeneratedDocumentsAsync и берёт проект и компиляцию из актуального workspace.CurrentSolution — см. ServiceLayer/GetDiagnostics.cs. Глобальные свойства MSBuild те же, что для остальных вызовов MSBuildWorkspace в этом сервере (RoslynMcpWorkspaceProperties).

Раньше без такого конвейёра при зелёном dotnet build возможны были ложные CS1061; в текущей реализации это учтено. Если вывод инструмента всё же расходится со сборкой, ориентир — dotnet build. Подробнее — docs/source-generators-and-diagnostics.md.

Требования

  • .NET 10

Сборка

cd roslyn-mcp
dotnet build
dotnet run

Полный перечень имён и описаний (как у инструментов в MCP) — docs/MCP-TOOLS.md. Тот же источник даёт mcp-tools.manifest.json в корне проекта. Обновить оба файла из кода:

dotnet run --project tools/ExportMcpManifest -- --write (рабочий каталог — корень roslyn-mcp).

Публикация exe (для MCP в Cursor)

Чтобы Cursor запускал MCP из exe, а не из проекта, сборка не будет блокироваться запущенным процессом.

Быстрый локальный publish (рекомендуется)

В репозитории есть publish-and-deploy.ps1: он прогоняет генерацию mcp-tools.manifest.json / docs/MCP-TOOLS.md, публикует self-contained win-x64, зеркалит в фиксированный путь (по умолчанию D:\roslyn-mcp) и гасит процесс, если он лочит файлы. Скрипт проверяет наличие BuildHost-netcore\Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.dll рядом с RoslynMcp.exe — без этой папки MSBuildWorkspace в Cursor падает с «build host could not be found».

.\publish-and-deploy.ps1
# Если в mcp.json указан другой каталог (например D:\RoslynMcp):
.\publish-and-deploy.ps1 -Target "D:\RoslynMcp"

Релизы (zip + GitLab upload)

scripts/publish-release-win.ps1 — это отдельный сценарий: мультиплатформа (win/linux/osx), упаковка в zip и загрузка в GitLab Generic Packages/Release.

В csproj заданы RuntimeIdentifiers (в т.ч. win-x64) и SelfContained=true — самодостаточная сборка (рантайм в папке, не зависит от установленного .NET в системе). Достаточно:

cd roslyn-mcp
dotnet publish -c Release -r win-x64 -o publish

Exe появится в roslyn-mcp/publish/RoslynMcp.exe. В конфиге MCP в Cursor укажи этот exe (command — полный путь к нему, args — []).

Обновить exe после правок: снова выполни ту же команду publish, затем перезапусти MCP или Cursor.

VS Code + Claude Code

Сервер работает по stdio. Подключение через Claude Code (VS Code с расширением Claude).

Требования: .NET 10 (или собранный exe), установленный Claude Code CLI.

Вариант 1: через exe (рекомендуется)

Собери exe (см. «Публикация exe» выше), затем добавь MCP:

claude mcp add --transport stdio roslyn -- C:\path\to\roslyn-mcp\publish\RoslynMcp.exe

На macOS/Linux подставь свой путь к exe, например ~/projects/roslyn-mcp/publish/RoslynMcp.

Вариант 2: через dotnet run (из папки проекта)

Если не собираешь exe, можно запускать из папки репо:

cd /path/to/roslyn-mcp
claude mcp add --transport stdio roslyn -- dotnet run --project .

(При первом запуске Claude Code выполнит dotnet run --project . в текущей папке — открой проект так, чтобы текущим каталогом была папка roslyn-mcp, или укажи полный путь: dotnet run --project /path/to/roslyn-mcp/RoslynMcp.csproj.)

Общий конфиг в проекте (.mcp.json)

Чтобы все в команде использовали один и тот же MCP, положи в корень C#-проекта файл .mcp.json:

{
  "mcpServers": {
    "roslyn": {
      "type": "stdio",
      "command": "C:\\path\\to\\roslyn-mcp\\publish\\RoslynMcp.exe",
      "args": []
    }
  }
}

Путь к command каждый подставляет свой (или используй переменные окружения, если Claude Code их поддерживает в .mcp.json). После сохранения Claude Code предложит доверять серверу; в чате можно проверить статус командой /mcp.

Стиль кода и .editorconfig

Генераторы кода (конструктор, override, интерфейс, базовый класс) учитывают .editorconfig в каталоге файла и выше (ближайший к файлу переопределяет). Учитываются опции в [*.cs]:

  • Типы: dotnet_style_predefined_type_for_locals_parameters_members, dotnet_style_predefined_type_for_member_access — ключевые слова C# (int, string, …) vs .NET (Int32, String).
  • Отступы: indent_style, indent_size, tab_width — при вставке в файл используется отступ из файла, при его отсутствии — из .editorconfig.
  • var: csharp_style_var_for_built_in_types, csharp_style_var_when_type_is_apparent, csharp_style_var_elsewhere — зарезервировано для будущего использования в генерируемом коде.
  • Скобки и переносы: csharp_prefer_braces, csharp_new_line_before_open_brace — зарезервировано для форматирования блоков.

В Generate constructor не добавляются backing-поля, если для них уже есть свойство (например _source при наличии Source).

Сам проект RoslynMcp имеет свой .editorconfig в корне: стиль (indent, типы, var, скобки) и severities анализаторов (IDE0049, IDE0055, CS0219, naming и т.д. — suggestion/warning/info/hidden/none). Сборка с EnforceCodeStyleInBuild и AnalysisLevel учитывает эти настройки.

Инструменты (tools)

Инструмент Описание
roslyn_ping Проверка доступности сервера.
roslyn_get_document_symbols Структура C# файла: namespace, class, method, property, field, enum, enum_member, delegate с номерами строк. Параметр: file_path.
roslyn_get_symbol_at_position Символ в позиции (файл + строка + столбец, 1-based): kind и имя. Опционально solution_or_project_path — тогда в ответе Qualified (полное имя). Параметры: file_path, line, column.
roslyn_find_usages Все ссылки на символ в solution/project. В выводе: квалифицированное имя (FullyQualifiedFormat), место определения (Definition:), затем список ссылок. Параметры: solution_or_project_path, file_path, line, column (на идентификаторе).
roslyn_go_to_definition Переход к определению символа: по позиции возвращает file:line:column объявления (для partial — несколько строк). Параметры: solution_or_project_path, file_path, line, column.
roslyn_rename Переименование символа по solution. Параметры: solution_or_project_path, file_path, line, column, new_name, опционально apply (превью/запись), rename_in_comments, rename_in_strings, rename_overloads, rename_file (аналог опций в VS), rename_partial_type_files (для топ-уровневого типа — переименовать все TypeName.cs / TypeName.*.cs в проекте под новое имя типа).
roslyn_get_code_actions Список Quick Actions / рефакторингов в позиции (как лампочка в VS). Параметры: solution_or_project_path, file_path, line, column. Опционально end_line, end_column — диапазон выделения для рефакторингов вроде Extract method / Extract local function. Возвращает нумерованный список.
roslyn_apply_code_action Применить выбранное code action. Параметры: solution_or_project_path, file_path, line, column, action_index (0-based). Опционально: end_line, end_column (тот же диапазон, что при get); fix_all_scope: "document" | "project" | "solution"; constant_name — для Introduce constant; action_options — JSON-объект опций для действий с диалогом (Extract interface, Extract base class: имена членов и т.д.). Подробнее: REFACTORINGS.md.
roslyn_get_diagnostics Диагностики компиляции и анализаторов по solution/project. Учитывается .editorconfig целевого проекта: исключаются диагностики с dotnet_diagnostic.<Id>.severity = none и уровень Hidden от анализаторов. Параметры: solution_or_project_path, опционально file_path.
roslyn_get_solution_structure Список проектов в solution (имя, путь к .csproj). Параметр: solution_or_project_path (.sln или .csproj). Для реп с только .slnx: передай путь к главному .csproj — вернётся список подгруженных проектов.
roslyn_generate_interface_from_class Сгенерировать C# интерфейс по классу без диалогов (обходной путь для Extract Interface). Позиция на класс: solution_or_project_path, file_path, line, column. Опционально: interface_name, output_file_path, member_names (массив). Дальше вручную или через code action добавь классу : IName и примени «Implement interface».
roslyn_generate_base_class_from_class Сгенерировать абстрактный базовый класс по классу без диалогов (обходной путь для Extract Base Class). Позиция на класс: solution_or_project_path, file_path, line, column. Опционально: base_class_name, output_file_path, member_names (массив). Дальше: добавить классу : BaseName и проставить override у членов.
roslyn_generate_overrides Generate Overrides без диалога: по позиции на класс генерирует override виртуальных/абстрактных членов базового типа. Опционально: member_names (массив), insert_into_file (true — вставить в тело класса).
roslyn_generate_constructor_from_members Generate constructor без диалога: по позиции на класс генерирует конструктор по instance полям и свойствам с set. Опционально: member_names, insert_into_file.
roslyn_generate_equals_gethashcode Generate Equals and GetHashCode без диалога: по позиции на класс генерирует override Equals/GetHashCode по выбранным полям/свойствам. Опционально: member_names, insert_into_file.

Лицензия

Software: MIT (текст OSI) · Ethical use: declaration