Let AI assistants like Claude safely refactor your C# codebase using the same Roslyn compiler platform that powers Visual Studio.
Roslyn MCP Server is a Model Context Protocol (MCP) server that exposes 66 Roslyn-powered tools to AI assistants and other MCP clients. It combines 37 refactoring operations, 5 code navigation tools, 6 analysis and metrics tools, 5 code generation tools, and 13 code conversion tools -- giving your AI deep code intelligence, comprehensive refactoring, and modern C# syntax transformations with full solution-wide reference tracking and preview support.
- Why RoslynMcpServer?
- Prerequisites
- Quick Start
- Standalone CLI
- Configuration
- Available Tools
- Preview Mode
- Troubleshooting
- NuGet Libraries
- Contributing
- License
- 66 tools -- refactoring, navigation, analysis, generation, and conversion tools, the most comprehensive Roslyn MCP server available
- Preview mode on every operation -- see exactly what will change before applying
- Atomic file writes with rollback -- if any file write fails, all changes are reverted
- Solution-wide reference updates -- renames and moves propagate across your entire solution
- Single command install --
dotnet tool install -g RoslynMcp.Server, no repo cloning needed - Cross-platform -- works on Windows, Linux, and macOS
Before installing, make sure you have:
- .NET 9.0 SDK or later -- Download here
- A C# solution (
.slnor.slnx) or project (.csproj) to work with
Verify your .NET SDK version:
dotnet --versionThe output should be 9.0.x or higher.
dotnet tool install -g RoslynMcp.ServerCreate a .mcp.json file in your project root (for Claude Code):
{
"mcpServers": {
"roslyn-refactor": {
"type": "stdio",
"command": "roslyn-mcp",
"args": []
}
}
}Then restart Claude Code or run /mcp to connect.
Ask Claude:
"Run the roslyn diagnose tool for my solution at C:/path/to/MySolution.sln"
You should see a health report with Roslyn version, MSBuild status, and workspace details.
Ask Claude:
"Rename the class UserService to AccountService in C:/path/to/MySolution.sln"
Claude will use the rename_symbol tool to rename the class and update every reference across your entire solution.
All 66 tools are also available as a standalone CLI for use in scripts, CI/CD pipelines, and terminals without an AI assistant.
dotnet tool install -g RoslynMcp.Cliroslyn-cli <solution-path> <tool-name> [--option value ...]
roslyn-cli <tool-name> --help
roslyn-cli --help# Check environment health
roslyn-cli C:/path/to/MySolution.sln diagnose --format text
# Rename a symbol across the entire solution
roslyn-cli C:/path/to/MySolution.sln rename-symbol --source-file C:/path/to/Foo.cs --symbol-name Bar --new-name Baz
# Get compiler diagnostics (errors only), pipe to jq
roslyn-cli C:/path/to/MySolution.sln get-diagnostics --severity-filter Error | jq '.data'
# Preview a refactoring without applying
roslyn-cli C:/path/to/MySolution.sln extract-method --source-file Foo.cs --start-line 10 --end-line 20 --method-name DoWork --previewOutput is JSON by default (pipeable to jq). Use --format text for human-readable output. Exit codes: 0=success, 1=tool error, 2=CLI error, 3=environment error.
Create .mcp.json in your project root:
{
"mcpServers": {
"roslyn-refactor": {
"type": "stdio",
"command": "roslyn-mcp",
"args": []
}
}
}Add to your claude_desktop_config.json:
{
"mcpServers": {
"roslyn-refactor": {
"command": "roslyn-mcp",
"args": []
}
}
}Config file locations:
| OS | Path |
|---|---|
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
All tools accept a solutionPath parameter (absolute path to a .sln, .slnx, or .csproj file). Refactoring tools also accept a preview parameter (set to true to see changes without applying them).
| Tool | Description | Key Parameters |
|---|---|---|
move_type_to_file |
Move a C# type declaration to a different file. Updates all references automatically. (line disambiguates same-named top-level types by start-line equality when several share the name; omitted with several matches is SymbolAmbiguous; a single match ignores line; column picks the top-level type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest covering type; omitted keeps today's symbolName + optional line pick so indented types still move; column without line keeps today's omitted-line path rather than substituting each candidate's own start line; nested types stay unmoveable). Process a single type or all files in the solution. allFiles: true walks every C# file and extracts every eligible top-level type into {directory}/{TypeName}.cs; optional sourceFile when true limits the walk via FilterAllFilesDocumentsBySourceFile; cannot be combined with symbolName, targetFile, line, or column. Already well-placed single-type matching files, nested types, SameLocation, NameCollision / occupied destinations, and uneditable documents are skipped. |
sourceFile, allFiles, symbolName, targetFile, createTargetFile, line, column, preview |
move_type_to_namespace |
Change the namespace of a C# type. Updates all using directives and qualified references. (line disambiguates same-named top-level types by start-line equality when several share the name; omitted with several matches is SymbolAmbiguous; a single match ignores line; column picks the top-level type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest covering type; omitted keeps today's symbolName + optional line pick so indented types still move; column without line keeps today's omitted-line path rather than substituting each candidate's own start line; nested types stay unmoveable). Process a single type or all files in the solution. allFiles: true walks every C# file and moves every eligible top-level type into targetNamespace; optional sourceFile when true limits the walk via FilterAllFilesDocumentsBySourceFile; cannot be combined with symbolName, line, or column. Types already in the target namespace, nested types, multi-type files, NameCollision, and uneditable documents are skipped. updateFileLocation stays valid; later destination claims are skipped on collision. |
sourceFile, allFiles, symbolName, targetNamespace, updateFileLocation, line, column, preview |
rename_symbol |
Rename any C# symbol (type, method, property, field, variable, etc.) with automatic reference updates across the solution. Process a single symbol or all files in the solution. allFiles: true walks every C# file and renames every eligible declaration whose simple name equals symbolName to newName under today's single-site validation; sourceFile is optional when true and limits the walk to that one file; cannot be combined with line or column. Symbols already at newName, name conflicts, constructors/destructors/operators, and uneditable / source-generated documents are skipped. Linked multi-views are skipped (same contract as safe_delete / rename_namespace / remove_parameter). Deduplicates by symbol identity (and overload groups when renameOverloads expands the set). symbolName / newName remain required. renameOverloads / renameImplementations / renameFile / renameInComments / renameInStrings / preview remain valid with allFiles. Omitted / false renameInComments / renameInStrings keep today's no-comment / no-string rewrite. Does not invent convert_anonymous_to_class / convert_tuple_to_struct allFiles. |
sourceFile, allFiles, symbolName, newName, line, column, renameOverloads, renameImplementations, renameFile, renameInComments, renameInStrings, preview |
rename_file_to_match_type |
Rename a source file so its name matches the primary type declared in it, without renaming the type or its references. Process a single file or all files in the solution. allFiles: true walks every C# file and renames each unambiguous mismatched single-type file; optional sourceFile when true limits the walk via FilterAllFilesDocumentsBySourceFile; cannot be combined with typeName, line, or column. Multi-type, zero-type, already-matching, and destination-occupied files are skipped. (column picks the smallest type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest covering declaration; omitted keeps today's typeName + optional line covering-span pick so a multi-line declaration still matches when line is inside the body; column without line keeps today's omitted-line path rather than inventing column-only cross-line disambiguation). |
sourceFile, allFiles, typeName, line, column, preview |
rename_namespace |
Rename a C# namespace across the solution, updating declarations, using directives, and qualified name references. Does not move folders by default. (column picks the smallest namespace whose name or declaration span covers that 1-based column when set with line — name preferred, then smallest covering declaration; omitted keeps today's namespaceName + optional line covering-span pick so a multi-line declaration still matches when line is inside the body; column without line keeps today's omitted-line path rather than inventing column-only cross-line disambiguation). Process a single namespace or all files in the solution. allFiles: true walks every C# file and renames every eligible top-level namespace declaration to newName under today's single-site validation; sourceFile is optional when true and limits the walk to that one file; cannot be combined with namespaceName, line, or column. Namespaces already at newName, name conflicts, and uneditable / source-generated documents are skipped. Linked multi-views are skipped (same contract as safe_delete / remove_parameter). newName remains required. updateFolders / renameInComments / renameInStrings / preview remain valid with allFiles. Omitted / false renameInComments / renameInStrings keep today's no-comment / no-string rewrite on the last-segment Renamer path; full-namespace rewrites stay declaration + reference only. Does not invent convert_anonymous_to_class / convert_tuple_to_struct. |
sourceFile, allFiles, namespaceName, newName, line, column, updateFolders, renameInComments, renameInStrings, preview |
| Tool | Description | Key Parameters |
|---|---|---|
extract_method |
Extract selected code into a new method. Automatically detects parameters and return values. Process a single site or all files in the solution. allFiles: true walks every C# file and extracts every eligible contiguous ≥2-statement proper-subset run inside method/accessor/local-function blocks under today's single-site validation, naming each method from sanitized statement text (prefer first invoked simple name / created type name); sourceFile is optional when true; cannot be combined with startLine, startColumn, endLine, endColumn, or methodName. Yield, multiple returns, name collisions, empty/invalid derived names, uneditable / source-generated docs are skipped. visibility / makeStatic / preview remain valid with allFiles where they apply (sites that cannot honor them are skipped). |
sourceFile, allFiles, startLine, startColumn, endLine, endColumn, methodName, visibility, makeStatic, preview |
extract_variable |
Extract an expression to a local variable. Process a single site or all files in the solution. allFiles: true walks every C# file and extracts every eligible outermost non-trivial expression (invocation / object creation / binary / conditional / element access / await / cast / interpolated string / switch-expression / is/as-pattern) inside method/accessor/local-function blocks under today's single-site validation, naming each variable from sanitized expression text (prefer invoked simple name / created type name); sourceFile is optional when true; cannot be combined with startLine, startColumn, endLine, endColumn, or variableName. Void, missing statement/block, name collisions, side-effecting sites when replaceAll is set, empty/invalid derived names, uneditable / source-generated docs, and linked multi-views that diverge are skipped. useVar / replaceAll / preview remain valid with allFiles where they apply (sites that cannot honor them are skipped). |
sourceFile, allFiles, startLine, startColumn, endLine, endColumn, variableName, useVar, replaceAll, preview |
extract_constant |
Extract a literal value to a named constant. Process a single site or all files in the solution. allFiles: true walks every C# file and extracts every eligible compile-time literal (constant named from the literal value); sourceFile is optional when true; cannot be combined with startLine, startColumn, endLine, endColumn, or constantName. visibility / replaceAll / preview remain valid with allFiles where they apply (sites that cannot honor them are skipped). |
sourceFile, allFiles, startLine, startColumn, endLine, endColumn, constantName, visibility, replaceAll, preview |
extract_interface |
Extract an interface from a class's public members (line picks the type whose identifier or declaration span covers that 1-based line when several types share the name — identifier preferred, then smallest containing type, including nested types; omitted keeps today's typeName FirstOrDefault pick so two same-named types still succeed; a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest containing type; omitted keeps today's typeName + optional line pick so indented types still extract; column without line keeps today's first-match after the typeName filter rather than substituting each candidate's own start line; indexers emit this[...] declarations via CreateInterfaceIndexer; ordinary properties stay on CreateInterfaceProperty; members matches Item / this[] / this[int i]). Process a single type or all files in the solution. allFiles: true walks every C# file and extracts I{TypeName} for every eligible non-static type with extractable public members into a sibling I{TypeName}.cs; sourceFile is optional when true (limits the walk to that file); cannot be combined with typeName, line, column, interfaceName, members, or targetFile. Static types, interfaces, types with no extractable members, name collisions, occupied destinations, and uneditable documents are skipped. |
sourceFile, allFiles, typeName, line, column, interfaceName, members, targetFile, separateFile, addInterfaceToType, preview |
extract_base_class |
Extract members (methods, properties, fields, events, and indexers) to a new base class (line picks the type whose identifier or declaration span covers that 1-based line when several types share the name — identifier preferred, then smallest containing type, including nested types; omitted keeps today's typeName FirstOrDefault pick on ClassDeclarationSyntax so two same-named classes still succeed; a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest containing type; omitted keeps today's typeName + optional line pick so indented types still extract; column without line keeps today's first-match after the typeName filter rather than substituting each candidate's own start line). Field-like and accessor-style events move by name; a multi-variable event field moves only the selected declarator. Indexers move as legal this[...] declarations; members matches Item / this[] / this[int i]. Private events and indexers become protected on the new base. makeAbstract makes extracted methods, properties, events, and indexers abstract on the new base and keeps override implementations on the derived type; fields still move as concrete. Process a single class or all files in the solution. allFiles: true walks every C# file and extracts {TypeName}Base for every eligible non-static class with extractable members into a sibling {TypeName}Base.cs; sourceFile is optional when true (limits the walk to that file); cannot be combined with typeName, line, column, baseClassName, members, or targetFile. Static types, unsupported kinds, types with no extractable members, types that already have a non-Object base, generics, nested types, name collisions, occupied destinations, and uneditable documents are skipped. makeAbstract / preview remain valid with allFiles. |
sourceFile, allFiles, typeName, line, column, baseClassName, members, targetFile, separateFile, makeAbstract, preview |
pull_members_up |
Move selected members (methods, properties, fields, events, and indexers) from a derived type onto an existing base class or interface (line picks the type whose identifier or declaration span covers that 1-based line when several types share the name — identifier preferred, then smallest containing type, including nested types; omitted keeps today's typeName FirstOrDefault pick on TypeDeclarationSyntax so two same-named types still succeed; a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest containing type; omitted keeps today's typeName + optional line pick so indented types still extract; column without line keeps today's first-match after the typeName filter rather than substituting each candidate's own start line). Field-like and accessor-style events move by name; a multi-variable event field moves only the selected declarator. Indexers move as legal this[...] declarations; members matches Item / this[] / this[int i]. Private events and indexers become protected on the base. makeAbstract on a class target makes the event or indexer abstract and keeps an override on the derived type; interface targets keep the implementation on the derived type. Cross-assembly makeAbstract reduces protected internal method, property, event, and indexer overrides (and a more-restricted accessor) to protected (CS0507); same-assembly keeps protected internal. Process a single type or all files in the solution. allFiles: true walks every C# file and pulls every pullable member from each eligible derived type onto its default target (nearest class base, or the single implemented interface); sourceFile is optional when true (limits the walk to that file); cannot be combined with typeName, line, column, members, or targetBaseType. Types with no base/interface, multiple interfaces requiring an explicit target, sealed / non-editable bases, empty pullable sets, and uneditable documents are skipped. makeAbstract / preview remain valid with allFiles. |
sourceFile, allFiles, typeName, line, column, members, targetBaseType, makeAbstract, preview |
push_members_down |
Move selected members (methods, properties, fields, events, and indexers) from a base type down onto derived types (line picks the type whose identifier or declaration span covers that 1-based line when several types share the name — identifier preferred, then smallest containing type, including nested types; omitted keeps today's typeName FirstOrDefault pick on TypeDeclarationSyntax so two same-named types still succeed; a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest containing type; omitted keeps today's typeName + optional line pick so indented types still extract; column without line keeps today's first-match after the typeName filter rather than substituting each candidate's own start line). Field-like and accessor-style events move by name; a multi-variable event field moves only the selected declarator. Indexers move as legal this[...] declarations; members matches Item / this[] / this[int i]. leaveAbstract on a class source makes the event or indexer abstract on the base and adds an override on each derived type. Cross-assembly leaveAbstract reduces protected internal method, property, event, and indexer overrides (and a more-restricted accessor) to protected (CS0507); same-assembly keeps protected internal. Push to an interface emits a legal this[...] signature (only publicly accessible accessors). Process a single type or all files in the solution. allFiles: true walks every C# file and pushes every pushable member from each eligible base type onto all direct derived types; sourceFile is optional when true (limits the walk to that file); cannot be combined with typeName, line, column, members, or targetDerivedTypes. Types with no derived targets, empty pushable sets, and uneditable documents are skipped. leaveAbstract / preview remain valid with allFiles. |
sourceFile, allFiles, typeName, line, column, members, targetDerivedTypes, leaveAbstract, preview |
use_base_type |
Replace derived-type references with a compatible base type or interface (line picks the type whose identifier or declaration span covers that 1-based line when several types share the name — identifier preferred, then smallest containing type, including nested types; omitted keeps today's typeName first-match on TypeDeclarationSyntax — matches[0] when the name has no . or there is a single match, else semantic TypeNameMatches for FQN — so two same-named types still succeed; a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest containing type; omitted keeps today's typeName + optional line pick so indented types still rewrite; column without line keeps today's omitted-line PickOmittedLineMatch after the typeName filter rather than substituting each candidate's own start line). Process a single type or all files in the solution. allFiles: true walks every C# file and rewrites eligible references of every TypeDeclarationSyntax (class/struct/interface); optional sourceFile when true limits the walk via FilterAllFilesDocumentsBySourceFile; cannot be combined with typeName, line, or column. Bulk walks every eligible type rather than broadening search for one typeName. Types with no common base, a missing named targetBaseType, no eligible references, incompatible used members, or uneditable documents are skipped. Combining two types that would collapse sibling overloads onto the same signature (CS0111) is skipped. |
sourceFile, allFiles, typeName, line, column, targetBaseType, preview |
introduce_field |
Turn a selected local variable or expression into a class field, optionally initializing it in a constructor. Process a single site or all files in the solution. allFiles: true walks every C# file and promotes every eligible local (field named from that local); sourceFile is optional when true; cannot be combined with startLine, startColumn, endLine, endColumn, or fieldName. isReadonly / isStatic / initializeInConstructor / replaceAll / preview remain valid with allFiles where they apply (sites that cannot honor them are skipped). |
sourceFile, allFiles, startLine, startColumn, endLine, endColumn, fieldName, isReadonly, isStatic, initializeInConstructor, replaceAll, preview |
safe_delete |
Delete a selected symbol only when it has no remaining references. If usages exist, reject with their locations. Process a single site or all files in the solution. allFiles: true walks every C# file and deletes every eligible unused private (or local) declaration under today's single-site validation (public / protected / internal symbols are skipped in bulk so solution-local walks cannot wipe public API); sourceFile is optional when true and limits the walk to that one file; cannot be combined with startLine, startColumn, endLine, endColumn, or symbolName. Symbols with remaining usages, uneditable / source-generated docs, and linked multi-views that diverge are skipped. preview remains valid with allFiles. |
sourceFile, allFiles, startLine, startColumn, endLine, endColumn, symbolName, preview |
make_static |
Make a selected instance method static when it does not use instance state. Adds the static modifier and updates call sites and method-group conversions to the containing type name. Process a single method or all files in the solution. allFiles: true walks every C# file and makes every eligible ordinary instance method static; sourceFile is optional when true and limits the walk to that one file; cannot be combined with startLine, startColumn, endLine, endColumn, or symbolName. Already-static, virtual/override/abstract/extern, interface / interface-implementing, instance-member-using, uneditable, and otherwise ineligible methods are skipped. |
sourceFile, allFiles, startLine, startColumn, endLine, endColumn, symbolName, preview |
make_non_static |
Make a selected static method an instance method when a valid instance receiver exists. Removes the static modifier and updates type-name call sites and method-group conversions to an instance receiver (or this in the same type). Process a single method or all files in the solution. allFiles: true walks every C# file and makes every eligible ordinary static method an instance method; sourceFile is optional when true and limits the walk to that one file; cannot be combined with startLine, startColumn, endLine, endColumn, or symbolName. Already-instance, extension, virtual/override/abstract/extern, static-class, interface / interface-implementing, no-valid-receiver, uneditable, and otherwise ineligible methods are skipped. |
sourceFile, allFiles, startLine, startColumn, endLine, endColumn, symbolName, preview |
invert_if |
Flip an if-statement condition and swap the if/else branches, preserving semantics. Comparison operators are inverted (> ↔ <=, == ↔ !=, …); && / ` |
|
add_braces |
Add braces to control statements (if, else, for, foreach, while, using) that have a single-statement body, preserving semantics. Process a single file or all files in the solution (allFiles: true walks every C# file at file scope; optional sourceFile when true limits the walk; omitted scope uses file; cannot be combined with scope=statement or scope=type). scope is statement (default; wrap the body at line / optional column; single-file only), file (every braceless control body in the file), or type (bodies inside typeName; single-file only). else if stays a single construct in file/type scope. column picks the control statement whose keyword span covers that 1-based column when set with line (exclusive-end; today's shortest keyword / First among covering); omitted keeps today's first/leftmost-keyword-on-line-by-SpanStart pick so indented statements still wrap; column without line keeps today's required-line validation rather than inventing column-only cross-line disambiguation. |
sourceFile, allFiles, line, column, scope, typeName, preview |
remove_braces |
Remove braces from control statements (if, else, for, foreach, while, using) whose body is a single-statement block, preserving semantics. Process a single file or all files in the solution (allFiles: true walks every C# file at file scope; optional sourceFile when true limits the walk; omitted scope uses file; cannot be combined with scope=statement or scope=type). scope is statement (default; unwrap the body at line / optional column; single-file only), file (every eligible single-statement braced control body in the file), or type (bodies inside typeName; single-file only). else if stays a single construct in file/type scope. column picks the control statement whose keyword span covers that 1-based column when set with line (exclusive-end; today's shortest keyword / First among covering); omitted keeps today's first/leftmost-keyword-on-line-by-SpanStart pick so indented statements still unwrap; column without line keeps today's required-line validation rather than inventing column-only cross-line disambiguation. |
sourceFile, allFiles, line, column, scope, typeName, preview |
simplify_name |
Remove redundant namespace qualifications from type (and similar) references when a using directive or the current namespace already makes the short name bind to the same symbol. Process a single file or all files in the solution (allFiles: true walks every C# file; optional sourceFile when true limits the walk). scope is file (default; every eligible qualified name) or location (the name at line / optional column; single-file only). column picks the name whose span covers that 1-based column when set with line (exclusive-end; today's FirstOrDefault among covering names); omitted keeps today's first/leftmost-name-on-line-by-SpanStart pick so indented names still simplify; column without line keeps today's required-line validation rather than inventing column-only cross-line disambiguation. Names that would become ambiguous or bind differently are skipped and reported. |
sourceFile, allFiles, scope, line, column, preview |
| Tool | Description | Key Parameters |
|---|---|---|
inline_method |
Inline a method by replacing call sites with the method body. Optionally remove the method (column picks the smallest method whose identifier or declaration span covers that column; omitted keeps today's methodName + optional line identifier start-line pick so a continuation-line identifier still matches when line is the identifier line of a split signature). Process a single method or all files in the solution. allFiles: true walks every C# file and inlines every eligible method; sourceFile is optional when true and limits the walk to that one file; cannot be combined with methodName, line, column, or callSiteLocation. Methods that are not inlineable (no body, virtual/override/abstract, recursive, unsupported control flow, no call sites, method-group / foreign-receiver / side-effect sites) and uneditable / source-generated documents are skipped. removeMethod and preview remain valid with allFiles. |
sourceFile, allFiles, methodName, line, column, callSiteLocation, removeMethod, preview |
inline_variable |
Inline a local variable by replacing all usages with its initializer value (column picks the declaration whose identifier or declaration span covers that column; omitted keeps today's variableName + optional line start-line pick so a continuation-line identifier still needs column when line is the type line of a split declaration). Process a single variable or all files in the solution. allFiles: true walks every C# file and inlines every eligible local; sourceFile is optional when true and limits the walk to that one file; cannot be combined with variableName, line, or column. Locals without an initializer, with side effects, reassignment, ref/out uses, not in a method, and uneditable / source-generated documents are skipped. preview remains valid with allFiles. |
sourceFile, allFiles, variableName, line, column, preview |
inline_constant |
Inline a const field by replacing references with a formatted literal. Optionally remove the constant (line picks the matching const field whose identifier or declaration span covers that 1-based line when several constants share the name — identifier preferred, then smallest covering declarator/field, including nested types; omitted keeps today's constantName + optional typeName path so two same-named constants still ask for typeName (SymbolAmbiguous); a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the matching const field whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest covering declarator/field; omitted keeps today's constantName + optional typeName + optional line pick; column without line keeps today's omitted-line path after the name/typeName filter rather than substituting each candidate's own start line or inventing FirstOrDefault; typeName stays an additive filter when supplied). Process a single constant or all files in the solution. allFiles: true walks every C# file and inlines every eligible const field; sourceFile is optional when true and limits the walk to that one file; cannot be combined with constantName, typeName, line, or column. Attribute uses, public-API constants when removeConstant would apply, uneditable documents, missing literals, and otherwise ineligible constants are skipped. removeConstant and preview remain valid with allFiles. |
sourceFile, allFiles, constantName, typeName, line, column, removeConstant, preview |
| Tool | Description | Key Parameters |
|---|---|---|
change_signature |
Add, remove, or reorder method parameters and update all call sites (column picks the smallest method whose identifier or declaration span covers that column; omitted keeps today's methodName and/or line start-line pick so a continuation-line identifier still needs column when line is the identifier line of a split signature). Optional allFiles applies the same parameters list to every eligible method across C# documents (sourceFile optional when true; cannot combine with methodName / line / column). |
sourceFile, methodName, parameters (array of changes), line, column, allFiles, preview |
add_parameter |
Add a named parameter to a method and update call sites, overrides, and interface implementations (column picks the smallest method whose identifier or declaration span covers that column; omitted keeps today's methodName + optional line start-line pick so a continuation-line identifier still needs column when line is the identifier line of a split signature). Process a single method or all files in the solution. allFiles: true walks every C# file and adds the same parameterName / parameterType (and optional defaultValue / position) to every eligible method under today's single-site validation; sourceFile is optional when true and limits the walk to that one file; cannot be combined with methodName, line, or column. Methods that already have the parameter, fail existing validation, or are in uneditable / source-generated documents are skipped. Linked multi-views are skipped (same contract as safe_delete). parameterName / parameterType remain required. defaultValue / position / updateOverrides / updateImplementations / preview remain valid with allFiles. Does not invent convert_anonymous_to_class / convert_tuple_to_struct / remove_parameter. |
sourceFile, allFiles, methodName, parameterName, parameterType, defaultValue, position, line, column, updateOverrides, updateImplementations, preview |
remove_parameter |
Remove a named parameter from a method and drop matching call-site arguments, updating overrides and interface implementations (column picks the smallest method whose identifier or declaration span covers that column; omitted keeps today's methodName + optional line start-line pick so a continuation-line identifier still needs column when line is the identifier line of a split signature). Process a single method or all files in the solution. allFiles: true walks every C# file and removes the same parameterName from every eligible method under today's single-site validation; sourceFile is optional when true and limits the walk to that one file; cannot be combined with methodName, line, or column. Methods that lack the parameter, fail existing validation, are uneditable contracts (overrides, interface implementations, extern, UnmanagedCallersOnly, ModuleInitializer, partials), or are in uneditable / source-generated documents are skipped. Linked multi-views are skipped (same contract as safe_delete / add_parameter). parameterName remains required. force / updateOverrides / updateImplementations / preview remain valid with allFiles. Does not invent convert_anonymous_to_class / convert_tuple_to_struct. |
sourceFile, allFiles, methodName, parameterName, line, column, force, updateOverrides, updateImplementations, preview |
reorder_parameters |
Reorder a method's parameters by a 0-based permutation and update positional call-site arguments, updating overrides and interface implementations (column picks the smallest method whose identifier or declaration span covers that column; omitted keeps today's methodName + optional line start-line pick so a continuation-line identifier still needs column when line is the identifier line of a split signature). Process a single method or all files in the solution. allFiles: true walks every C# file and applies the same newOrder to every eligible method under today's single-site validation; sourceFile is optional when true and limits the walk to that one file; cannot be combined with methodName, line, or column. Methods whose arity cannot accept newOrder, fail existing validation, are uneditable contracts (overrides, interface implementations, extern, UnmanagedCallersOnly, ModuleInitializer, partials, extension methods), or are in uneditable / source-generated documents are skipped. Linked multi-views are skipped (same contract as safe_delete / remove_parameter). newOrder remains required. updateOverrides / updateImplementations / preview remain valid with allFiles. Does not invent convert_anonymous_to_class / convert_tuple_to_struct. |
sourceFile, allFiles, methodName, newOrder, line, column, updateOverrides, updateImplementations, preview |
change_return_type |
Change a method's return type and update return statements when the conversion is safe, updating overrides and interface implementations (column picks the smallest method whose identifier or declaration span covers that column; omitted keeps today's methodName + optional line start-line pick so a continuation-line identifier still needs column when line is the identifier line of a split signature). Process a single method or all files in the solution. allFiles: true walks every C# file and changes the return type of every eligible method whose current return type can safely become newReturnType under today's single-site validation; sourceFile is optional when true and limits the walk to that one file; cannot be combined with methodName, line, or column. Methods that fail existing safety checks (SameLocation, async/Task-like, incompatible returns, uneditable contracts, overload collisions, iterators, unsupported call sites) and uneditable / source-generated documents are skipped. newReturnType remains required. updateOverrides / updateImplementations / convertReturnStatements / preview remain valid with allFiles. |
sourceFile, allFiles, methodName, newReturnType, line, column, updateOverrides, updateImplementations, convertReturnStatements, preview |
encapsulate_field |
Convert a field to a property with backing field (line picks the field whose identifier or declaration span covers that 1-based line when several fields share the name — identifier preferred, then smallest covering declarator/field, including nested types; omitted keeps today's fieldName first-match so two same-named fields still succeed; a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the field whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest covering declarator/field; omitted keeps today's fieldName + optional line pick so indented fields still encapsulate; column without line keeps today's FirstOrDefault after the fieldName filter rather than substituting each candidate's own start line; updateReferences: default true rewrites external references to the new property; false still encapsulates — private field + property — and does not redirect callers to the property; if the backing field is renamed for a case-only collision (name → _name), external identifiers follow the new field name; same-class references stay on the field; preview describes whether references will be updated and writes nothing). Process a single field or all files in the solution. allFiles: true walks every C# file and encapsulates every eligible field (same filter as single-site FindFieldDeclarator; locals excluded); optional sourceFile when true limits the walk via FilterAllFilesDocumentsBySourceFile; cannot be combined with fieldName, line, column, or propertyName (bulk cannot apply one propertyName). Const fields, fields whose derived property name already exists, and other per-field failures are skipped. |
sourceFile, allFiles, fieldName, line, column, propertyName, readOnly, updateReferences, preview |
| Tool | Description | Key Parameters |
|---|---|---|
generate_constructor |
Generate a constructor that initializes fields and/or properties of a type (line picks the type whose identifier or declaration span covers that 1-based line when several types share the name — identifier preferred, then smallest containing type, including nested types; omitted keeps today's typeName FirstOrDefault pick so two same-named types still succeed; a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest containing type; omitted keeps today's typeName + optional line pick so indented types still generate; column without line keeps today's first-match after the typeName filter rather than substituting each candidate's own start line; includeProperties: default true includes settable properties, false uses instance fields only unless members names a property; includeInheritedMembers: default false keeps this-type-only collection, true also collects accessible instance fields and, when includeProperties is true, settable properties declared on base types; replaceExisting: replace an existing constructor with the exact same signature instead of failing — optional-parameter / required-parameter ambiguity still fails; visibility: default public, also private / protected / internal / protected internal / private protected; structs/record structs reject the three protected forms; unsealed-record copy constructors must be public or protected (CS8878); copyConstructor: default false keeps today's one-parameter-per-member constructor, true generates a single same-type copy constructor that assigns each selected member from that parameter — derived records whose base is also a record include : base(other); classBaseCopy: default false keeps today's class copy-constructor shape, true (requires copyConstructor) emits : base((Base)other) on an ordinary class when the immediate base has an accessible Base(Base) copy constructor and does not reassign inherited members; callBase: default false keeps today's non-copy shape (no : base(...)), true emits : base(...) on an ordinary class or record class when an accessible immediate-base constructor's parameter types are a prefix of the generated constructor — conflicts with copyConstructor; record structs / structs ignore callBase). Process a single type or all files in the solution. allFiles: true walks every C# file and generates constructors for every eligible TypeDeclarationSyntax (class/struct/record/record struct, including nested); sourceFile is optional when true and limits the walk to that one file; cannot be combined with typeName, members, line, or column. Interface, static, no-members, ConstructorExists, uneditable, CS0666, CS8878, primary-constructor exact match, and otherwise ineligible types are skipped. |
sourceFile, allFiles, typeName, line, column, members, includeProperties, includeInheritedMembers, addNullChecks, replaceExisting, visibility, copyConstructor, classBaseCopy, callBase, preview |
generate_property |
Generate a property on a type: auto-property { get; set; }, init-only { get; init; }, or a backing-field form when a field is the target (line picks the type whose identifier or declaration span covers that 1-based line when several types share the name — identifier preferred, then smallest containing type, including nested types; omitted keeps today's typeName FirstOrDefault pick so two same-named types still succeed; a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest containing type; omitted keeps today's typeName + optional line pick so indented types still generate; column without line keeps today's first-match after the typeName filter rather than substituting each candidate's own start line; replaceExisting: default false keeps today's fail-on-clash; true removes the existing property of that name — including across partials — and inserts a freshly generated one; fields and methods of the same name are never removed; two same-named properties with no single target fail with NameCollision). Process a single type or all files in the solution. allFiles: true walks every C# file and generates the named property on every eligible type (sourceFile optional when true; cannot be combined with typeName, line, or column; propertyName / propertyType required unless fieldName; preview aggregates PendingChanges). |
sourceFile, typeName, line, column, propertyName, propertyType, fieldName, visibility, initOnly, replaceExisting, allFiles |
generate_method_stub |
Generate a method from an undefined call site, inferring the signature from usage (throwNotImplemented: default true emits throw new NotImplementedException();; false uses default-return / empty void bodies via SyntaxGenerationHelper.CreateDefaultReturnBody; async Task / Task<T> unwrap so the body compiles; ref / ref readonly returns still throw; replaceExisting: default false keeps today's fail-on-clash; true removes a compatible ordinary method — same name, type-parameter arity, parameter count, parameter types in order, and RefKind — including across partials, then inserts a freshly generated stub; constructors, operators, local functions, explicit interface implementations, and accessors are never replaced; two compatible ordinary methods with no single target fail with NameCollision). Process a single call site or all files in the solution. allFiles: true walks every C# file and generates stubs for distinct eligible undefined call sites (sourceFile optional when true; cannot be combined with line, column, or methodName; preview aggregates PendingChanges). |
sourceFile, line, column, methodName, returnType, visibility, generateAsync, throwNotImplemented, replaceExisting, allFiles |
generate_overrides |
Generate override methods, properties/indexers, and events for base class virtual/abstract members (line picks the type whose identifier or declaration span covers that 1-based line when several types share the name — identifier preferred, then smallest containing type, including nested types; omitted keeps today's typeName FirstOrDefault pick so two same-named types still succeed; a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest containing type; omitted keeps today's typeName + optional line pick so indented types still generate; column without line keeps today's first-match after the typeName filter rather than substituting each candidate's own start line; callBase: default true emits base.M(...) for non-abstract virtual methods and return base.Prop; / base.Prop = value; for non-abstract virtual properties and indexers (return base[i]; / base[i] = value;); abstract members still throw; events always use empty add/remove regardless of callBase; a cross-assembly protected internal method, property, indexer, or event is emitted as protected (CS0507), including a more-restricted accessor; internal / private protected members from another assembly are not generated; false uses default-return / empty bodies; replaceExisting: default false skips members this type already overrides; true also replaces those existing overrides — match methods by name + parameter types + RefKind, properties and events by name; two same-name existing overrides with no exact signature match fail with OverrideExists; new hiders / explicit interface implementations / non-override ordinary members are never replaced; preview describes generate vs replace and writes nothing). Process a single type or all files in the solution. allFiles: true walks every C# file and generates missing overrides for every eligible TypeDeclarationSyntax (class/struct/record/record struct/interface, including nested); sourceFile is optional when true and limits the walk to that one file; cannot be combined with typeName, members, line, or column. No-overridable, already-complete, OverrideExists, uneditable, and otherwise ineligible types are skipped. Bulk uses today's collect including Object ToString / Equals(object) / GetHashCode when missing. |
sourceFile, allFiles, typeName, line, column, members, callBase, replaceExisting, preview |
implement_interface |
Generate interface member implementations for a type (line picks the type whose identifier or declaration span covers that 1-based line when several types share the name — identifier preferred, then smallest containing type, including nested types; omitted keeps today's typeName FirstOrDefault pick so two same-named types still succeed; a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest containing type; omitted keeps today's typeName + optional line pick so indented types still generate; column without line keeps today's first-match after the typeName filter rather than substituting each candidate's own start line; indexers emit this[...] indexer declarations via CreateIndexerStub; ordinary properties stay on CreatePropertyStub; throwNotImplemented: default true emits throw new NotImplementedException();; false uses default-return / empty setter bodies; ref / ref readonly getters still throw; replaceExisting: default false keeps today's only-unimplemented members and MemberAlreadyImplemented when nothing is missing; true also replaces already-implemented interface members — methods by name + parameter types + RefKind, properties and events by name, indexers by Item / this[] / display forms; two same-name existing implementations with no exact signature match fail with NameCollision before any write; explicitImplementation still selects explicit vs ordinary public stubs; preview describes generate vs replace and writes nothing). Process a single type or all files in the solution. allFiles: true walks every C# file and implements missing members of already-declared interfaces for every eligible TypeDeclarationSyntax (class/struct/record/record struct/interface, including nested); sourceFile is optional when true and limits the walk to that one file; cannot be combined with typeName, interfaceName, members, line, or column. No declared interfaces, already-implemented, NameCollision, uneditable, and otherwise ineligible types are skipped. Bulk does not TypeResolver-hunt undeclared interfaces. |
sourceFile, allFiles, typeName, line, column, interfaceName, explicitImplementation, members, throwNotImplemented, replaceExisting, preview |
implement_abstract |
Generate implementation stubs for unimplemented abstract members inherited by a selected class — methods, properties, indexers, and events (line picks the type whose identifier or declaration span covers that 1-based line when several types share the name — identifier preferred, then smallest containing type, including nested types; omitted keeps today's typeName FirstOrDefault pick so two same-named types still succeed; a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest containing type; omitted keeps today's typeName + optional line pick so indented types still generate; column without line keeps today's first-match after the typeName filter rather than substituting each candidate's own start line; throwNotImplemented: default true emits throw new NotImplementedException();; false uses default-return / empty setter bodies; ref / ref readonly methods and getters still throw; events always use empty add/remove; a cross-assembly protected internal event is emitted as protected (CS0507); internal / private protected events from another assembly are not selected; replaceExisting: default false keeps today's only-unimplemented members and NoUnimplementedAbstractMembers when nothing is missing; true also replaces already-implemented abstract members — methods by name + parameter types + RefKind, properties and events by name, indexers by Item / this[] / display forms; two same-name existing implementations with no exact signature match fail with NameCollision before any write; new hiders / explicit interface implementations / non-override ordinary members are never replaced; preview describes generate vs replace and writes nothing). Process a single type or all files in the solution. allFiles: true walks every C# file and implements missing abstract members for every eligible TypeDeclarationSyntax (class/struct/record/record struct/interface, including nested); sourceFile is optional when true and limits the walk to that one file; cannot be combined with typeName, members, line, or column. Interface, static, struct, enum, delegate, no-unimplemented, uneditable, NameCollision, and otherwise ineligible types are skipped. |
sourceFile, allFiles, typeName, line, column, members, throwNotImplemented, replaceExisting, preview |
| Tool | Description | Key Parameters |
|---|---|---|
convert_to_async |
Convert a synchronous method to async/await pattern (column picks the method whose identifier or declaration span covers that column; omitted keeps today's MethodName + Line pick so a continuation-line identifier still needs column; renameToAsync: default true rewrites call-site identifiers to the Async name; updateCallers: default false keeps today's unaugmented callers — no await wrap and callers are not made async; true wraps already-async callers in await and skips synchronous callers that cannot legally await, reporting them; preview describes caller updates or that none will happen and writes nothing). Process a single method or all files in the solution. allFiles: true walks every C# file and converts every distinct eligible sync method; optional sourceFile when true limits the walk; cannot be combined with methodName, line, or column. |
sourceFile, allFiles, methodName, line, column, renameToAsync, updateCallers, preview |
convert_expression_body |
Toggle between expression body (=> expr;) and block body ({ return expr; }) (direction: ToExpressionBody / ToBlockBody; column picks the member whose identifier or declaration span covers that column on the given line; omitted keeps today's first-match-on-the-line pick; preview describes the rewrite and writes nothing). Process a single member or all files in the solution. allFiles: true walks every C# file and converts every eligible supported member; optional sourceFile when true limits the walk; cannot be combined with memberName, line, or column. |
sourceFile, allFiles, direction, memberName, line, column, preview |
convert_to_block_body |
Convert a selected expression-bodied member (=> expr) to a block body. Methods become { return expr; } or { expr; } as appropriate; properties and accessors that are expression-bodied are converted too (column picks the member whose identifier or declaration span covers that column on the given line; omitted keeps today's memberName and/or line pick — smallest containing node; preview describes the rewrite and writes nothing). Process a single member or all files in the solution. allFiles: true walks every C# file and converts every eligible expression-bodied member; sourceFile is optional when true; cannot be combined with memberName, line, or column. |
sourceFile, allFiles, memberName, line, column, preview |
convert_property |
Convert between auto-property and full property with backing field (direction: ToAutoProperty / ToFullProperty; column picks the smallest property whose identifier or declaration span covers that column on the given line; omitted keeps today's propertyName and/or line start-line pick so indented properties still convert; preview describes the rewrite and writes nothing). Process a single property or all files in the solution. allFiles: true walks every C# file and converts every distinct eligible property; optional sourceFile when true limits the walk; cannot be combined with propertyName, line, or column. |
sourceFile, allFiles, direction, propertyName, line, column, preview |
convert_foreach_linq |
Convert foreach loops with Add patterns to LINQ (preferQuerySyntax: default false keeps today's method syntax .Where().Select().ToList(); true emits query syntax (from … where … select) for filter / project / filter+project / ToList-after-query, preserving an explicitly typed foreach element (from string item in …) while var stays untyped; Any / All / FirstOrDefault / Count-only keep method syntax rather than inventing invalid query syntax; preview describes the rewrite and writes nothing). Process a single foreach or all files in the solution. allFiles: true walks every C# file and converts every distinct eligible foreach; optional sourceFile when true limits the walk; cannot be combined with line or column. column picks the foreach whose ForEachKeyword span covers that 1-based column when set with line (exclusive-end; today's FirstOrDefault among covering keywords); omitted keeps today's first-ForEachKeyword-on-line-by-SpanStart pick so indented foreachs still convert; column without line keeps today's required-line validation rather than inventing column-only cross-line disambiguation. |
sourceFile, allFiles, line, column, preferQuerySyntax, preview |
convert_anonymous_to_class |
Convert an anonymous type (new { ... }) to a named class or record, replacing same-shape anonymous creations in the solution (column picks the anonymous creation whose span covers that 1-based column when set with line — exclusive-end covering-span, today's unique covering match, else CannotConvert / SymbolAmbiguous; omitted keeps today's line pick so a single creation on the line still converts; preview describes the rewrite and writes nothing). |
sourceFile, line, newTypeName, column, asRecord, preview |
convert_tuple_to_struct |
Convert a tuple ((int X, int Y) / (1, 2) / ValueTuple) to a named struct, replacing same-shape tuple creations in the solution (column picks the tuple creation whose span covers that 1-based column when set with line — exclusive-end covering-span, today's unique covering match, else CannotConvert / SymbolAmbiguous; omitted keeps today's line pick so a single creation on the line still converts; preview describes the rewrite and writes nothing). |
sourceFile, line, newTypeName, column, preview |
convert_to_pattern_matching |
Convert if/is chains and switch statements to switch expressions (column picks the smallest switch or if whose span covers that column on the given line; omitted keeps today's first start-line switch-then-if pick so indented statements still convert; preview describes the rewrite and writes nothing). Process a single switch/if or all files in the solution. allFiles: true walks every C# file and converts every distinct eligible switch/if-chain; optional sourceFile when true limits the walk; cannot be combined with line or column. |
sourceFile, allFiles, line, column, preview |
convert_to_interpolated_string |
Convert string.Format() calls and concatenation to interpolated strings (column picks the Format invocation or concatenation whose span covers that column on the given line; omitted keeps today's first-match-on-the-line pick so indented expressions still convert; preview describes the rewrite and writes nothing). Process a single expression or all files in the solution. allFiles: true walks every C# file and converts every distinct convertible Format invocation and outer concatenation; optional sourceFile when true limits the walk; cannot be combined with line or column. |
sourceFile, allFiles, line, column, preview |
introduce_parameter |
Promote a local variable to a method parameter, updating all call sites (column picks the matching local whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest covering declarator, same exclusive-end coverage as encapsulate_field / SpanCoversColumn; omitted keeps today's start-line equality on the local declaration statement, then variableName FirstOrDefault so same-line multi-declarators still pick by name; a continuation-line identifier is eligible when column is set — do not require the declaration statement to start on line; do not force column 1 when omitted; do not rewrite line-only to covering-span; FileLinePositionSpan.EndLinePosition is exclusive so a column on an adjacent same-line declarator does not also match the previous one; if column is set and nothing covers that position, or the covering declarator is not variableName, SymbolNotFound — do not fall back to FirstOrDefault). Process a single local or all files in the solution. allFiles: true walks every C# file and promotes every eligible local; sourceFile is optional when true; cannot be combined with variableName, line, or column. |
sourceFile, allFiles, variableName, line, column, preview |
| Tool | Description | Key Parameters |
|---|---|---|
add_missing_usings |
Add missing using directives required to resolve unbound type references. Process a single file or all files in the solution (allFiles: true walks every C# file; optional sourceFile when true limits the walk; preview returns computed changes without applying). |
sourceFile, allFiles, preview |
remove_unused_usings |
Remove unused using directives. Process a single file or all files in the solution (allFiles: true walks every C# file; optional sourceFile when true limits the walk; preview returns computed changes without applying). |
sourceFile, allFiles, preview |
sort_usings |
Sort using directives alphabetically in a C# file. Process a single file or all files in the solution (allFiles: true walks every C# file; optional sourceFile when true limits the walk; systemFirst places System / System.* first by default; preview returns computed changes without applying). |
sourceFile, allFiles, systemFirst, preview |
| Tool | Description | Key Parameters |
|---|---|---|
diagnose |
Check the health of the Roslyn MCP server environment and workspace status. | solutionPath (optional), verbose |
These read-only tools let you explore and understand your codebase without making changes. Use them to discover symbols, trace references, and inspect type information before refactoring.
| Tool | Description | Key Parameters |
|---|---|---|
find_references |
Find all references to a symbol across the entire solution. Returns file locations, context snippets, and write/definition indicators. Optional includeDeclaration (default true) set to false returns usages only, excluding the symbol's own definition locations before maxResults is applied. Optional referenceFile restricts reported locations to those in that absolute .cs file (definition locations are kept only when they are in that file; applied before maxResults, so totalCount / truncated reflect the filtered set; nonexistent file → SourceFileNotFound); omitted keeps today's whole-solution behavior. Optional projectPath (absolute .csproj path of a project in the loaded solution) restricts reported locations (definition locations included) to documents in that project (every target framework of a multi-targeted project), combined with referenceFile / includeDeclaration and applied before maxResults (omit = whole solution; relative / non-.csproj → InvalidSourcePath; no matching project → SourceNotInWorkspace; peer of get_diagnostics / search_symbols). Optional namespaceFilter restricts reported locations (definition locations included) to reference sites whose containing namespace — that of the member / type / namespace declaration enclosing each location, not the target symbol's — equals it or is nested inside it (ordinal; e.g. App.Services matches App.Services.Orders, not App.ServicesExtra; whitespace trimmed; leading global:: accepted; global-namespace sites never match; same matching as search_symbols / find_implementations namespaceFilter), combined with referenceFile / projectPath / includeDeclaration and applied before maxResults (omit / blank / bare global:: = all namespaces; no match → empty success). Optional accessibilityFilter (public, internal, protected, private, protected internal, or private protected; case-insensitive; same values as search_symbols / get_document_outline / get_symbol_info / find_implementations / get_type_hierarchy / find_callers accessibilityFilter) keeps only locations whose reference site's enclosing symbol — the member / type enclosing each usage (same site notion as namespaceFilter, not the target symbol; lambdas and local functions are looked through to their declaring member; namespace-level sites never match) — has a DeclaredAccessibility equal to it exactly (implicit defaults count: a class member with no modifier is private; protected internal is not matched by protected or internal); definition locations are judged by the declared symbol itself (an internal method on a public type is internal), combined with referenceFile / projectPath / namespaceFilter / includeDeclaration and applied before maxResults (omit / blank = all accessibilities; invalid → InvalidVisibility; no match → empty success). Optional nameFilter (ordinal, case-insensitive substring; whitespace trimmed; same matching as get_document_outline / get_symbol_info / find_implementations / get_type_hierarchy nameFilter) keeps only locations whose reference site's enclosing symbol — the same site symbol accessibilityFilter judges (the member / type enclosing each usage, not the target symbol; definition locations judged by the declared symbol itself; namespace-level sites never match) — has a simple ISymbol.Name containing it (accessors read get_X / set_X, constructors .ctor), combined with the other filters and applied before maxResults (omit / blank = all names; no match → empty success). sourceFile still locates the target symbol. |
sourceFile, symbolName, line, column, maxResults, includeDeclaration, referenceFile, projectPath, namespaceFilter, accessibilityFilter, nameFilter |
go_to_definition |
Navigate to the source definition of a symbol. Supports partial classes with multiple definition locations. Optional maxResults caps the returned Definitions list (omit = no cap; peer of get_type_hierarchy / find_implementations); result includes Truncated when capped. Optional definitionFile restricts reported Definitions to locations in that absolute .cs file (e.g. one part of a partial type or partial method; applied before maxResults, so totalCount / truncated reflect the filtered set; a file with no definition part returns an empty success; metadata definitions are excluded; nonexistent file → SourceFileNotFound); omitted keeps today's behavior. Optional projectPath (absolute .csproj path of a project in the loaded solution) restricts reported Definitions to locations in documents of that project (every target framework of a multi-targeted project; metadata definitions are excluded), combined with definitionFile and applied before maxResults (omit = unchanged; relative / non-.csproj → InvalidSourcePath; no matching project → SourceNotInWorkspace; peer of get_diagnostics / search_symbols / find_references / find_callers / find_implementations / get_type_hierarchy). sourceFile still locates the symbol. |
sourceFile, symbolName, line, column, maxResults, definitionFile, projectPath |
get_symbol_info |
Get detailed metadata for any symbol: kind, accessibility, modifiers, base types, interfaces, members, parameters, return type, and XML documentation. Optional kindFilter (same values and case-insensitive parsing as search_symbols / get_document_outline kindFilter) keeps only Members of that kind on a type, applied before maxResults so totalCount / truncated reflect the filtered set (Local / Parameter / Namespace never match a type member; invalid value → InvalidSymbolKind). Optional accessibilityFilter (same values and parsing as search_symbols / get_document_outline accessibilityFilter: public, internal, protected, private, protected internal, private protected, case-insensitive) keeps only Members whose declared accessibility equals it exactly (implicit defaults count), combined with kindFilter and applied before maxResults (invalid value → InvalidVisibility). Optional nameFilter (same matching as get_document_outline nameFilter: ordinal, case-insensitive substring on the member's simple name; surrounding whitespace trimmed) keeps only Members whose name contains it, combined with kindFilter / accessibilityFilter and applied before maxResults; omit / blank = no name filter. Optional maxResults caps the returned Members list of a type (omit = no cap; peer of get_type_hierarchy / get_document_outline); result includes TotalCount (filtered member count for types, null otherwise) and Truncated when capped. Interfaces, Parameters and other fields are not filtered or capped, and kindFilter / accessibilityFilter / nameFilter / maxResults have no effect on non-type symbols. |
sourceFile, symbolName, line, column, maxResults, kindFilter, accessibilityFilter, nameFilter |
find_implementations |
Find all implementations of an interface or overrides of an abstract/virtual member. Optional implementationFile restricts reported implementations to those declared in that absolute .cs file (a partial type matches when any of its parts is in that file and is reported there; applied before maxResults, so totalCount / truncated reflect the filtered set; nonexistent file → SourceFileNotFound); omitted keeps today's whole-solution behavior. Optional projectPath (absolute .csproj path of a project in the loaded solution) restricts reported implementations to those declared in documents of that project (every target framework of a multi-targeted project; a partial type is reported at its part in that project), combined with implementationFile and applied before maxResults (omit = whole solution; relative / non-.csproj → InvalidSourcePath; no matching project → SourceNotInWorkspace; peer of get_diagnostics / search_symbols / find_references / find_callers). Optional transitive (default true = every implementing type) set to false on an interface reports only types that implement it directly (list it in their own base list; types inheriting the implementation from a base class or implementing it via a derived interface are dropped), with implementationFile / projectPath filtering and maxResults capping that direct set; no effect for member targets or non-interface types (peer of get_type_hierarchy transitive). Optional namespaceFilter keeps only implementations whose containing namespace (for member targets, that of the member's containing type) equals it or is nested inside it (same matching as search_symbols namespaceFilter: e.g. App.Services matches App.Services.Orders, not App.ServicesExtra; ordinal; leading global:: accepted; global-namespace implementations never match a named filter, while a bare global:: filters nothing), combined with implementationFile / projectPath / transitive and applied before maxResults (omit / blank = all namespaces). Optional accessibilityFilter (public, internal, protected, private, protected internal, or private protected; case-insensitive; same values as search_symbols / get_document_outline / get_symbol_info accessibilityFilter) keeps only implementations whose DeclaredAccessibility equals it exactly (implicit defaults count: a top-level type with no modifier is internal, a nested type with no modifier is private; for member targets the implementing member's accessibility is used; explicit interface implementations are private), combined with the other filters and applied before maxResults (omit / blank = all accessibilities; invalid → InvalidVisibility). Optional kindFilter (a single kind name — Class, Struct, Interface, Enum, Record, Delegate, Method, Property, Field, Event, Constant, Local, Parameter, Namespace; case-insensitive; same values and parsing as search_symbols / get_document_outline / get_symbol_info kindFilter) keeps only implementations whose reported Kind equals it (records are Record, not Class; e.g. Struct for the structs implementing an interface), combined with the other filters and applied before maxResults (omit / blank = all kinds; a kind no implementation has → empty success; invalid → InvalidSymbolKind). Optional nameFilter keeps only implementations whose reported Name contains it (ordinal, case-insensitive substring; surrounding whitespace trimmed; same matching as get_document_outline / get_symbol_info nameFilter; e.g. Sql for the Sql* implementers of a repository interface; for member targets the implementing member's own name is used, so it is mainly useful for type targets), combined with the other filters and applied before maxResults (omit / blank = all names; no match → empty success). sourceFile still locates the target symbol. |
sourceFile, symbolName, line, column, maxResults, implementationFile, projectPath, transitive, namespaceFilter, accessibilityFilter, kindFilter, nameFilter |
search_symbols |
Search for symbols by name pattern across the entire workspace or a specific file. Filter by kind (class, method, property, etc.). Optional sourceFile restricts results to symbols whose in-source declaration location is that file (peer of get_diagnostics; omit = whole solution). Optional caseSensitive (default false) set to true matches query case-sensitively (ordinal) before maxResults is applied. Optional exactMatch (default false) set to true requires the whole symbol name to equal query (honoring caseSensitive) instead of a substring match, before maxResults. Optional namespaceFilter restricts results to symbols whose containing namespace equals it or is nested inside it (e.g. App.Services matches App.Services.Orders, not App.ServicesExtra; ordinal; leading global:: accepted; global-namespace symbols never match a named filter, while a bare global:: is the root namespace and filters nothing), before maxResults. Optional projectPath (absolute .csproj path of a project in the loaded solution) compiles and searches only that project (every target framework of a multi-targeted project), so only symbols declared in its sources are returned, combined with the other filters and applied before maxResults (omit = whole solution; relative / non-.csproj → InvalidSourcePath; no matching project → SourceNotInWorkspace; peer of get_diagnostics). Optional accessibilityFilter (public, internal, protected, private, protected internal, or private protected; case-insensitive; either modifier order for the compound values) keeps only symbols whose declared accessibility is exactly that value, counting implicit defaults (a top-level type with no modifier is internal, a class member with no modifier is private, an interface member is public); protected internal is not matched by protected or internal, namespaces never match, combined with the other filters and applied before maxResults (omit / blank = any accessibility; any other value → InvalidVisibility). |
query, kindFilter, maxResults, sourceFile, caseSensitive, exactMatch, namespaceFilter, projectPath, accessibilityFilter |
These tools analyze your code without making changes. Use them to understand code quality, data flow, and control flow.
| Tool | Description | Key Parameters |
|---|---|---|
get_diagnostics |
Retrieve compiler diagnostics (errors, warnings, info) filtered by severity and optionally by file. Optional maxResults caps the returned list (omit = no cap; peer of search_symbols / find_references); result includes Truncated when capped. Optional diagnosticIds (e.g. ["CS0168"], case-insensitive) restricts results to those IDs before the cap (omit or empty = all IDs). Optional excludeDiagnosticIds (e.g. ["CS1591", "CS8019"], case-insensitive) drops those IDs before the cap and wins over diagnosticIds on overlap (omit or empty = exclude none). Optional projectPath (absolute .csproj path of a project in the loaded solution) compiles and scans only that project (every target framework of a multi-targeted project), combined with sourceFile and the ID / severity filters and applied before the cap (omit = whole solution; relative / non-.csproj → InvalidSourcePath; no matching project → SourceNotInWorkspace). Optional namespaceFilter restricts results to diagnostics whose diagnostic site — the member / type / namespace declaration enclosing the diagnostic location — lives in a namespace that equals it or is nested inside it (ordinal; e.g. App.Services matches App.Services.Orders, not App.ServicesExtra; whitespace trimmed; leading global:: accepted; global-namespace sites and diagnostics with no source location never match; same matching as find_references / find_callers namespaceFilter), combined with sourceFile / projectPath / the ID / severity filters and applied before the cap (omit / blank / bare global:: = all namespaces; no match → empty success). Optional accessibilityFilter (public, internal, protected, private, protected internal, or private protected; case-insensitive; same values as search_symbols / find_references / find_callers / get_document_outline / get_symbol_info / find_implementations / get_type_hierarchy accessibilityFilter) keeps only diagnostics whose diagnostic site — the nearest declared member when the diagnostic is attached to a declaration (e.g. CS0169 on a field identifier), otherwise the member / type enclosing the location (same site notion as namespaceFilter; lambdas and local functions are looked through to their declaring member; namespace-level sites never match) — has a DeclaredAccessibility equal to it exactly (implicit defaults count: a class member with no modifier is private; protected internal is not matched by protected or internal); diagnostics with no source location never match; combined with sourceFile / projectPath / namespaceFilter / the ID / severity filters and applied before the cap (omit / blank = all accessibilities; invalid → InvalidVisibility; no match → empty success). |
sourceFile, severityFilter, maxResults, diagnosticIds, excludeDiagnosticIds, projectPath, namespaceFilter, accessibilityFilter |
get_code_metrics |
Calculate code metrics: cyclomatic complexity, lines of code, maintainability index, class coupling, depth of inheritance. Optional column disambiguates same-named symbols the same way find_callers does when set with line; omitted keeps today's Line-only / file-level path (file-level when neither symbolName nor line is set); column without line keeps today's SymbolResolver omitted-line path. |
sourceFile, symbolName, line, column |
analyze_control_flow |
Analyze control flow for a code region: start/end point reachability, return statements, and exit points. Optional startColumn / endColumn trim the region (1-based; Roslyn Character = column - 1; exclusive-ish end as TextLine.End); omitted keeps today's whole-line span (start of startLine through end of endLine). Do not force column 1 when omitted. |
sourceFile, startLine, endLine, startColumn, endColumn |
analyze_data_flow |
Analyze data flow for a code region: variables read/written inside, data flowing in/out, captured variables. Optional startColumn / endColumn trim the region (1-based; Roslyn Character = column - 1; exclusive-ish end as TextLine.End); omitted keeps today's whole-line span (start of startLine through end of endLine). Do not force column 1 when omitted. |
sourceFile, startLine, endLine, startColumn, endColumn |
find_callers |
Find all callers of a symbol across the entire solution. Optional callerFile restricts reported call sites to callers located in that absolute .cs file (applied before maxResults, so totalCount / truncated reflect the filtered set; nonexistent file → SourceFileNotFound); omitted keeps today's whole-solution behavior. Optional projectPath (absolute .csproj path of a project in the loaded solution) restricts reported call sites to documents in that project (every target framework of a multi-targeted project), combined with callerFile and applied before maxResults (omit = whole solution; relative / non-.csproj → InvalidSourcePath; no matching project → SourceNotInWorkspace; peer of get_diagnostics / search_symbols / find_references). Optional namespaceFilter restricts reported call sites to those whose containing namespace — that of the member / type / namespace declaration enclosing each call site, not the target symbol's — equals it or is nested inside it (ordinal; e.g. App.Services matches App.Services.Orders, not App.ServicesExtra; whitespace trimmed; leading global:: accepted; global-namespace sites never match; same matching as search_symbols / find_implementations / find_references namespaceFilter), combined with callerFile / projectPath and applied before maxResults (omit / blank / bare global:: = all namespaces; no match → empty success). Optional accessibilityFilter (public, internal, protected, private, protected internal, or private protected; case-insensitive; same values as search_symbols / get_document_outline / get_symbol_info / find_implementations / get_type_hierarchy accessibilityFilter) keeps only call sites whose calling symbol's DeclaredAccessibility equals it exactly (implicit defaults count: a class member with no modifier is private; protected internal is not matched by protected or internal), combined with callerFile / projectPath / namespaceFilter and applied before maxResults (omit / blank = all accessibilities; invalid → InvalidVisibility). Optional nameFilter (ordinal, case-insensitive substring; whitespace trimmed; same matching as get_document_outline / get_symbol_info / find_implementations / get_type_hierarchy / find_references nameFilter) keeps only call sites whose calling symbol — the same CallingSymbol accessibilityFilter judges — has a simple ISymbol.Name containing it — exactly the reported callerName (a call inside a property accessor body reports the property itself, so it matches as Total, not get_Total), combined with the other filters and applied before maxResults (omit / blank = all names; no match → empty success). Optional kindFilter (a single kind name — Class, Struct, Interface, Enum, Record, Delegate, Method, Property, Field, Event, Constant, Local, Parameter, Namespace; case-insensitive; same values and parsing as search_symbols / get_document_outline / get_symbol_info / find_implementations / get_type_hierarchy kindFilter) keeps only call sites whose calling symbol — the same CallingSymbol accessibilityFilter / nameFilter judge — has that kind (methods, constructors, operators, local functions, and lambdas are Method; a call inside a property accessor body reports the property, so it is Property; a field initializer is Field, or Constant for a const), combined with the other filters and applied before maxResults (omit / blank = all kinds; a kind no calling symbol has → empty success; invalid → InvalidSymbolKind). sourceFile still locates the target symbol. |
sourceFile, symbolName, line, column, maxResults, callerFile, projectPath, namespaceFilter, accessibilityFilter, nameFilter, kindFilter |
get_type_hierarchy |
Retrieve the type hierarchy (base types and/or derived types) for a given type. Optional maxResults caps the returned DerivedTypes list (omit = no cap; peer of find_implementations / get_diagnostics); result includes Truncated when capped. BaseTypes and Interfaces are not capped. Optional derivedFile restricts reported DerivedTypes to those declared in that absolute .cs file (a partial type matches when any of its parts is in that file and is reported there; applied before maxResults, so totalCount / truncated reflect the filtered set; BaseTypes and Interfaces are not filtered; nonexistent file → SourceFileNotFound); omitted keeps today's whole-solution behavior. Optional projectPath (absolute .csproj path of a project in the loaded solution) restricts reported DerivedTypes to those declared in documents of that project (every target framework of a multi-targeted project; a partial type is reported at its part in that project; BaseTypes and Interfaces are not filtered), combined with derivedFile and applied before maxResults (omit = whole solution; relative / non-.csproj → InvalidSourcePath; no matching project → SourceNotInWorkspace; peer of get_diagnostics / search_symbols / find_references / find_callers / find_implementations). Optional transitive (default true = every descendant) set to false reports only direct subclasses (types whose immediate base type is the target), with derivedFile / projectPath / maxResults applied to that direct set (BaseTypes and Interfaces unaffected). Optional namespaceFilter keeps only derived types whose containing namespace equals it or is nested inside it (same matching as search_symbols / find_implementations namespaceFilter: e.g. App.Services matches App.Services.Orders, not App.ServicesExtra; ordinal; leading global:: accepted; global-namespace types never match a named filter, while a bare global:: filters nothing), combined with derivedFile / projectPath / transitive and applied before maxResults (omit / blank = all namespaces; BaseTypes and Interfaces are not filtered). Optional accessibilityFilter (same values and parsing as search_symbols / find_implementations accessibilityFilter: public, internal, protected, private, protected internal, private protected, case-insensitive) keeps only DerivedTypes whose declared accessibility equals it exactly (implicit defaults count: a top-level type with no modifier is internal, a nested type with no modifier is private; protected internal is not matched by protected or internal), combined with derivedFile / projectPath / transitive / namespaceFilter and applied before maxResults (omit / blank = all accessibilities; invalid value → InvalidVisibility; BaseTypes and Interfaces are not filtered). Optional kindFilter (a single kind name — Class, Struct, Interface, Enum, Record, Delegate, Method, Property, Field, Event, Constant, Local, Parameter, Namespace; case-insensitive; same values and parsing as search_symbols / get_document_outline / get_symbol_info / find_implementations kindFilter) keeps only DerivedTypes whose shared kind classification equals it (same as find_implementations Kind: records are Record, not Class, even though a record's DerivedTypes entry Kind reads Class; since classes derive only from classes and records only from records, one target's derived types are typically all Class or all Record), combined with derivedFile / projectPath / transitive / namespaceFilter / accessibilityFilter and applied before maxResults (omit / blank = all kinds; a kind no derived type has → empty success; invalid → InvalidSymbolKind; BaseTypes and Interfaces are not filtered). Optional nameFilter keeps only DerivedTypes whose simple name contains it (ordinal, case-insensitive substring; surrounding whitespace trimmed; same matching as get_document_outline / get_symbol_info / find_implementations nameFilter; e.g. Admin for the *Admin* subclasses of a controller base), combined with derivedFile / projectPath / transitive / namespaceFilter / accessibilityFilter / kindFilter and applied before maxResults (omit / blank = all names; no match → empty success; BaseTypes and Interfaces are not filtered). sourceFile still locates the target type. |
sourceFile, symbolName, line, column, direction, maxResults, derivedFile, projectPath, transitive, namespaceFilter, accessibilityFilter, kindFilter, nameFilter |
get_document_outline |
Get a hierarchical outline of all symbols in a file (namespaces, types, members). Optional maxDepth (>= 1) drops entries deeper than N (1 = top-level entries only; omit = no depth cap). Optional maxResults caps the returned outline tree via DFS pre-order, applied after maxDepth (omit = no cap; peer of get_diagnostics / search_symbols / find_references); result includes Truncated when either cap omitted entries. Optional kindFilter (same values and case-insensitive parsing as search_symbols kindFilter; constructors match Method, enum members match Constant) keeps only entries of that kind plus the namespaces/types that contain them, applied before maxDepth / maxResults so totalCount / truncated reflect the filtered tree; no match returns an empty outline; invalid value → InvalidSymbolKind. Optional nameFilter keeps only entries whose name contains it (ordinal, case-insensitive substring) plus the namespaces/types that contain them, with the same container semantics; combined with kindFilter an entry must satisfy both; applied before maxDepth / maxResults; no match returns an empty outline; omitted / blank = no name filter. Optional accessibilityFilter (same values and semantics as search_symbols accessibilityFilter: public, internal, protected, private, protected internal, private protected, case-insensitive) keeps only entries whose declared accessibility equals it exactly (implicit defaults count: a top-level type with no modifier is internal, a class member with no modifier is private, an interface / enum member is public; namespaces never match) plus the namespaces/types that contain them, with the same container semantics; combined with kindFilter / nameFilter an entry must satisfy all; applied before maxDepth / maxResults; invalid value → InvalidVisibility; omitted / blank = no accessibility filter. Optional namespaceFilter (same normalization and matching as search_symbols / get_type_hierarchy namespaceFilter) keeps only entries declared in that namespace or one nested inside it (type and member entries match on their containing namespace; namespace entries match on the namespace itself, so App.Services keeps the App.Services and App.Services.Orders entries, not App.ServicesExtra; ordinal; whitespace trimmed; leading global:: accepted; global-namespace declarations never match a named filter) plus the namespaces/types that contain them, with the same container semantics; combined with kindFilter / nameFilter / accessibilityFilter an entry must satisfy all; applied before maxDepth / maxResults; no match returns an empty outline; omitted / blank / bare global:: = no namespace filter. |
sourceFile, maxResults, maxDepth, kindFilter, nameFilter, accessibilityFilter, namespaceFilter |
These tools generate new code members for existing types.
| Tool | Description | Key Parameters |
|---|---|---|
generate_equals_hashcode |
Generate Equals() and GetHashCode() overrides for a type based on its fields/properties (line picks the type whose identifier or declaration span covers that 1-based line when several types share the name — identifier preferred, then smallest containing type, including nested types; omitted keeps today's typeName FirstOrDefault pick so two same-named types still succeed; a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest containing type; omitted keeps today's typeName + optional line pick so indented types still generate; column without line keeps today's first-match after the typeName filter rather than substituting each candidate's own start line; implementIEquatable: also add IEquatable<T> and typed Equals; generateOperators: also add == / !=; replaceExisting: replace existing equality members instead of failing; useHashCodeCombine: default true uses HashCode.Combine / builder, false uses unchecked prime-multiply; includeProperties: default true includes readable properties, false uses instance fields only unless fields names a property; callSuper: default false keeps member-only Equals/GetHashCode, true folds the immediate base type's equality into both methods; includeInheritedMembers: default false keeps this-type-only collection, true also collects accessible instance fields/properties declared on base types). Process a single type or all files in the solution. allFiles: true walks every C# file and generates Equals/GetHashCode for every eligible TypeDeclarationSyntax (class/struct/record/record struct/interface, including nested); sourceFile is optional when true and limits the walk to that one file; cannot be combined with typeName, fields, line, or column. Interface, no-members when callSuper is false, already-has-override / IEquatable / operators when not replacing, CallSuperOnObjectBase / CallSuperOnAbstractBase, uneditable, and otherwise ineligible types are skipped. |
sourceFile, allFiles, typeName, line, column, fields, includeProperties, implementIEquatable, generateOperators, replaceExisting, useHashCodeCombine, callSuper, includeInheritedMembers, preview |
generate_tostring |
Generate a ToString() override for a type (line picks the type whose identifier or declaration span covers that 1-based line when several types share the name — identifier preferred, then smallest containing type, including nested types; omitted keeps today's typeName FirstOrDefault pick so two same-named types still succeed; a continuation-line identifier is eligible — do not require the declaration to start on line; column picks the type whose identifier or declaration span covers that 1-based column when set with line — identifier preferred, then smallest containing type; omitted keeps today's typeName + optional line pick so indented types still generate; column without line keeps today's first-match after the typeName filter rather than substituting each candidate's own start line; format: interpolated or stringbuilder; includeProperties: default true includes readable properties, false uses instance fields only unless fields names a property; includeInheritedMembers: default false keeps this-type-only collection, true also collects accessible instance fields/properties declared on base types; replaceExisting: replace an existing parameterless ToString instead of failing; callSuper: default false keeps member-only ToString, true folds the immediate base type's ToString into the generated override). Process a single type or all files in the solution. allFiles: true walks every C# file and generates ToString for every eligible TypeDeclarationSyntax (class/struct/record/record struct/interface, including nested); sourceFile is optional when true and limits the walk to that one file; cannot be combined with typeName, fields, line, or column. Interface, no-members when callSuper is false, already-has-override when not replacing, sealed inherited parameterless ToString (cannot override), CallSuperOnObjectBase / CallSuperOnAbstractBase, uneditable, and otherwise ineligible types are skipped. |
sourceFile, allFiles, typeName, line, column, fields, includeProperties, format, includeInheritedMembers, replaceExisting, callSuper, preview |
format_document |
Format a C# file using Roslyn's built-in formatter. Process a single file or all files in the solution (allFiles: true walks every C# file; optional sourceFile when true limits the walk; preview returns computed changes without applying). |
sourceFile, allFiles, preview |
add_null_checks |
Add null-check statements (ArgumentNullException.ThrowIfNull or guard clauses) for method or constructor parameters (column picks the smallest method or constructor whose identifier or declaration span covers that column; omitted keeps today's methodName + optional line start-line pick so a continuation-line identifier still needs column when line is the identifier line of a split signature). Process a single method or all files in the solution. allFiles: true walks every C# file and adds checks to every eligible method or constructor with a block body; optional sourceFile when true limits the walk via FilterAllFilesDocumentsBySourceFile; cannot be combined with methodName, line, or column. Methods with no parameters needing checks, no body, an expression body, or every eligible parameter already guarded are skipped. |
sourceFile, allFiles, methodName, line, column, style, preview |
Every refactoring tool supports a preview parameter. When set to true, the tool computes and returns the changes that would be made without writing anything to disk. This lets you review diffs before committing to a refactoring.
Example (as a natural language prompt to Claude):
"Preview what would happen if I renamed OrderProcessor to OrderHandler in C:/path/to/MySolution.sln"
Claude will call rename_symbol with preview: true and show you the affected files and diffs.
If you see errors about the SDK not being found:
- Verify the SDK is installed:
dotnet --list-sdks - Make sure .NET 9.0 or later appears in the list
- If not, install it from https://dotnet.microsoft.com/download/dotnet/9.0
If MSBuild cannot be located or your solution fails to load:
- Make sure you can build the solution from the command line first:
dotnet build /path/to/MySolution.sln - On Windows, ensure Visual Studio Build Tools or a Visual Studio installation is available
- Check that
solutionPathis an absolute path to a valid.sln,.slnx, or.csprojfile
The diagnose tool is the first thing to try when something is not working. It reports:
- Whether Roslyn is loaded and its version
- Whether MSBuild was found and its version
- Whether the .NET SDK is available and its version
- Whether a given solution can be loaded, including project and document counts
Run it through Claude:
"Run the roslyn diagnose tool with verbose output for C:/path/to/MySolution.sln"
Or without a solution path to check just the environment:
"Run the roslyn diagnose tool"
In addition to the global tool, the project publishes libraries for building custom integrations:
# Core library -- refactoring operations and workspace management
dotnet add package RoslynMcp.Core
# Contracts library -- shared models and interfaces
dotnet add package RoslynMcp.ContractsContributions are welcome. See CONTRIBUTING.md for guidelines.
git clone https://github.com/JoshuaRamirez/RoslynMcpServer.git
cd RoslynMcpServer
dotnet build -c Release# All tests
dotnet test
# Specific test projects
dotnet test tests/RoslynMcp.Core.Tests
dotnet test tests/RoslynMcp.Server.Tests
dotnet test tests/RoslynMcp.Cli.TestsThis project is licensed under the MIT License. See the LICENSE file for details.
- Built with Roslyn -- the .NET Compiler Platform
- Implements the Model Context Protocol
- Issues: GitHub Issues
- Discussions: GitHub Discussions