SharpLensMcp
A Model Context Protocol (MCP) server providing 91 AI-optimized tools for .NET/C# semantic code analysis, navigation, refactoring, and code generation using Microsoft Roslyn.
Built for AI coding agents - provides compiler-accurate code understanding that AI cannot infer from reading source files alone.
Installation
Via NuGet (Recommended)
dotnet tool install -g SharpLensMcpThen run with:
sharplensVia npm
npx -y sharplens-mcpBuild from Source
dotnet build -c Release
dotnet publish -c Release -o ./publishClaude Code Setup
- Install the tool (pick one):
dotnet tool install -g SharpLensMcp
# or
npx -y sharplens-mcp- Create
.mcp.jsonin your project root:
{
"mcpServers": {
"sharplens": {
"type": "stdio",
"command": "npx",
"args": ["-y", "sharplens-mcp"],
"env": {
"DOTNET_SOLUTION_PATH": "/path/to/your/Solution.sln (or .slnx)"
}
}
}
}-
Restart Claude Code to load the MCP server
-
Verify by asking Claude to run a health check on the Roslyn server
Why Use This with Claude Code?
Claude Code has native LSP support for basic navigation (go-to-definition, find references). SharpLensMcp adds deep semantic analysis:
| Capability | Native LSP | SharpLensMcp |
|---|---|---|
| Go to definition | ✅ | ✅ |
| Find references | ✅ | ✅ |
| Find async methods missing CancellationToken | ❌ | ✅ |
| Impact analysis (what breaks?) | ❌ | ✅ |
| Dead code detection | ❌ | ✅ |
| Complexity metrics | ❌ | ✅ |
| Safe refactoring with preview | ❌ | ✅ |
| Batch operations | ❌ | ✅ |
Configuration
| Environment Variable | Description | Default |
|---|---|---|
DOTNET_SOLUTION_PATH | Path to .sln or .slnx file to auto-load on startup | None (must call load_solution) |
SHARPLENS_ABSOLUTE_PATHS | Use absolute paths instead of relative | false (relative paths save tokens) |
SHARPLENS_LOG_LEVEL | Logging verbosity: Trace, Debug, Information, Warning, Error | Information |
SHARPLENS_TIMEOUT_SECONDS | Timeout for long-running operations | 30 |
SHARPLENS_MAX_DIAGNOSTICS | Maximum diagnostics to return | 100 |
SHARPLENS_ENABLE_SEMANTIC_CACHE | Enable semantic model caching | true (set to false to disable) |
The pre-1.6.0 ROSLYN_* spellings of the last four variables are still read as a fallback for one release; the SHARPLENS_* spelling wins when both are set.
If DOTNET_SOLUTION_PATH is not set, you must call the load_solution tool before using other tools.
Migrating from 1.5.x tool names
Tool names no longer carry the roslyn: prefix — the colon violates the MCP tool-name pattern (^[a-zA-Z0-9_-]{1,64}$), which some clients enforce. Every tool keeps its name minus the prefix:
| 1.5.x name | 1.6.0 name |
|---|---|
roslyn:load_solution | load_solution |
roslyn:get_diagnostics | get_diagnostics |
roslyn:rename_symbol | rename_symbol |
| ...same rule for all 91 tools... | drop the roslyn: prefix |
tools/list publishes only the new names. Calls using the old prefixed names are still accepted as aliases for one release and will be removed in the following one.
AI Agent Configuration Tips
AI models may have trained bias toward using their native tools (Grep, Read, LSP) instead of MCP server tools, even when SharpLensMcp provides better capabilities.
To ensure optimal tool usage:
-
Claude Code: Add to your project's
CLAUDE.md:For C# code analysis, prefer SharpLensMcp tools over native tools: - Use `search_symbols` instead of Grep for finding symbols - Use `get_method_source` instead of Read for viewing methods - Use `find_references` for semantic (not text) references -
Other MCP clients: Configure tool priority in your agent's system prompt
The semantic analysis from Roslyn is more accurate than text-based search, especially for overloaded methods, partial classes, and inheritance hierarchies.
Agent Responsibility: Document Synchronization
Important: SharpLensMcp maintains an in-memory representation of your solution for fast queries. When files are modified externally (via Edit/Write tools), the agent is responsible for synchronizing changes.
When to call sync_documents:
| Action | Call sync_documents? |
|---|---|
| Used Edit tool to modify .cs files | ✅ Yes |
| Used Write tool to create new .cs files | ✅ Yes |
| Deleted .cs files | ✅ Yes |
| Used SharpLensMcp refactoring tools (rename, extract, etc.) | ❌ No (auto-updated) |
| Modified .csproj files | ❌ No (use load_solution instead) |
Usage:
# After editing specific files
sync_documents(filePaths: ["src/MyClass.cs", "src/MyService.cs"])
# After bulk changes - sync all documents
sync_documents()Why this design?
This mirrors how LSP (Language Server Protocol) works - the client (editor) notifies the server of changes. This approach:
- Eliminates race conditions (agent controls timing)
- Avoids file watcher complexity and platform quirks
- Is faster than full solution reload
- Gives agents explicit control over workspace state
If you don't sync: Queries may return stale data (old method signatures, missing new files, etc.)
Features
- 91 Semantic Analysis Tools - Navigation, refactoring, code generation, diagnostics, discovery, audit/quality
- AI-Optimized Descriptions - Clear USAGE/OUTPUT/WORKFLOW patterns
- Structured Responses - Consistent
success/error/dataformat withsuggestedNextTools - Zero-Based Coordinates - Clear warnings to prevent off-by-one errors
- Preview Mode - Safe refactoring with preview before apply
- Batch Operations - Multiple lookups in one call to reduce context usage
Tool Categories
Navigation & Discovery (23 tools)
| Tool | Description |
|---|---|
get_symbol_info | Semantic info at position |
go_to_definition | Jump to symbol definition |
find_references | All references; each classified read/write/invocation/cast/typeof/nameof/attribute; optional kind filter |
find_implementations | Interface/abstract implementations |
find_callers | Impact analysis - who calls this? |
get_call_graph | Multi-hop callers/callees graph with depth bound + cycle detection |
get_type_hierarchy | Inheritance chain |
search_symbols | Glob pattern search (*Handler, Get*) |
semantic_query | Multi-filter search (async, public, etc.) |
get_type_members | All members by type name |
get_type_members_batch | Multiple types in one call |
get_method_signature | Detailed signature by name |
get_derived_types | Find all subclasses |
get_base_types | Full inheritance chain |
get_attributes | List attributes on a symbol |
get_containing_member | Enclosing symbol at position |
get_method_overloads | All overloads of a method |
find_attribute_usages | Find types/members by attribute |
get_external_type_info | Inspect NuGet/BCL/external assembly types — members + XML docs |
resolve_stack_trace | Map a pasted stack trace to file/line/symbol, mangling undone |
get_extension_methods | Extensions applying to a type — classic and C# 14 blocks |
get_documentation | Full XML docs for a symbol with <inheritdoc> expanded |
get_super_method | Navigate to the base member / interface members a member implements |
Analysis (17 tools)
| Tool | Description |
|---|---|
get_diagnostics | Compiler errors/warnings + configured analyzer findings (StyleCop, Roslynator, NetAnalyzers); matches CI |
diff_api_surface | Public-API breaking-change report vs a git ref |
get_exception_flow | Which exceptions can escape a method, and where they're caught |
find_similar_code | Structural similarity search (token-shingle fingerprints) |
remove_unused_code | Compute dead-code removals + newly unused usings (generation-only) |
find_dead_branches | Unreachable basic blocks per method (real CFG, not heuristics) |
add_missing_imports | Compute the usings that fix CS0246/CS0103 (generation-only) |
analyze_data_flow | Variable assignments and usage |
analyze_control_flow | Branching/reachability |
analyze_change_impact | What breaks if changed? |
check_type_compatibility | Can A assign to B? |
get_outgoing_calls | What does this method call? |
find_unused_code | Dead code detection |
validate_code | Compile check without writing |
get_complexity_metrics | Cyclomatic, nesting, LOC, cognitive |
find_circular_dependencies | Project and namespace cycle detection |
get_missing_members | Unimplemented interface/abstract members |
Refactoring (16 tools)
| Tool | Description |
|---|---|
rename_symbol | Safe rename across solution |
change_signature | Add/remove/reorder parameters |
extract_method | Extract with data flow analysis |
extract_interface | Generate interface from class |
generate_constructor | From fields/properties |
move_type_to_file | Compute the contents to move a type into its own file (generation-only) |
split_type | Compute a partial-class split for selected members (generation-only) |
organize_usings | Sort and remove unused |
organize_usings_batch | Batch organize multiple files |
format_document_batch | Batch format files in project |
get_code_actions_at_position | All Roslyn refactorings at position |
apply_code_action_by_title | Apply any refactoring by title |
implement_missing_members | Generate interface stubs |
encapsulate_field | Field to property |
inline_variable | Inline temp variable |
extract_variable | Extract expression to variable |
Code Generation (3 tools)
| Tool | Description |
|---|---|
add_null_checks | Generate ArgumentNullException guards |
generate_equality_members | Equals/GetHashCode/operators |
generate_test_stub | Compilable test skeleton for a method (framework auto-detected) |
Compound Tools (7 tools)
| Tool | Description |
|---|---|
get_type_overview | Full type info in one call |
analyze_method | Signature + callers + outgoing calls + location |
get_file_overview | File summary with diagnostics |
get_method_source | Source code by name |
get_method_source_batch | Multiple method sources in one call |
get_instantiation_options | How to create a type |
get_project_health | Composite audit dashboard: diagnostics + unused + coupling + coverage per project |
Audit & Quality (10 tools)
| Tool | Description |
|---|---|
find_god_objects | Detect over-coupled types via efferent + afferent coupling + member-count thresholds |
find_untested_code | Find public surface not reached by any [Fact]/[Theory]/[Test]/[TestMethod] |
find_tests | Which tests cover a symbol — the inverse of find_untested_code |
find_type_instantiations | Where a type is constructed (new T) |
find_pattern_usages | Where a type appears in is/as/pattern matches |
find_throw_sites | Where an exception type is thrown (optionally derived) |
find_catch_blocks | Where an exception type is caught (optionally via a base clause) |
find_async_issues | async void / blocking-on-async / unforwarded CancellationToken |
check_architecture | Enforce namespace/project dependency rules over the type graph |
find_naming_violations | Naming audit honoring .editorconfig rules, with conventional default |
…