关于 SharpLens
SharpLens 是面向 C# 和 .NET 编码 Agent 的 MCP 服务,使用 Microsoft Roslyn 对已加载的解决方案进行语义分析。其工具覆盖代码导航、诊断、影响分析、重构和代码生成,并支持在修改前预览。
主要功能
- 01基于 Roslyn 的语义符号导航
- 02编译器与分析器诊断
- 03变更影响、调用图和未使用代码分析
- 04支持预览的重构与批量操作
- 05代码生成和项目健康概览
适用场景
- 01在解决方案中追踪引用和实现
- 02查找诊断、未使用代码或依赖循环
- 03评估修改方法或 API 的影响
- 04预览并应用 C# 文件重构
MCP 相关
SharpLens 将 C# 和 .NET 解决方案的分析、导航、重构及代码生成操作作为 MCP 工具提供。客户端加载解决方案后,Agent 需在外部文件编辑后同步文档,以免查询返回过时结果。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
SharpLensMcp
一个 Model Context Protocol(MCP)服务,使用 Microsoft Roslyn 为 .NET/C# 提供 92 个经过 AI 优化的工具,用于语义代码分析、导航、重构和代码生成。
专为 AI 编码 Agent 打造,可提供仅凭阅读源文件无法推断的、精确到编译器级别的代码理解能力。
安装
通过 NuGet(推荐)
dotnet tool install -g SharpLensMcp
然后运行:
sharplens
通过 npm
npx -y sharplens-mcp
从源代码构建
dotnet build -c Release
dotnet publish -c Release -o ./publish
配置 Claude Code
- 安装工具(任选一种):
dotnet tool install -g SharpLensMcp
# or
npx -y sharplens-mcp
- 在项目根目录创建
.mcp.json:
{
"mcpServers": {
"sharplens": {
"type": "stdio",
"command": "npx",
"args": ["-y", "sharplens-mcp"],
"env": {
"DOTNET_SOLUTION_PATH": "/path/to/your/Solution.sln (or .slnx)"
}
}
}
}
-
重启 Claude Code,加载 MCP 服务
-
验证:让 Claude 对 Roslyn 服务运行健康检查
为什么要与 Claude Code 搭配使用?
Claude Code 原生支持 LSP,可进行基本导航(转到定义、查找引用)。SharpLensMcp 则增加了深度语义分析:
| 能力 | 原生 LSP | SharpLensMcp |
|---|---|---|
| 转到定义 | ✅ | ✅ |
| 查找引用 | ✅ | ✅ |
| 查找缺少 CancellationToken 的异步方法 | ❌ | ✅ |
| 影响分析(会造成什么问题?) | ❌ | ✅ |
| 检测死代码 | ❌ | ✅ |
| 复杂度指标 | ❌ | ✅ |
| 带预览的安全重构 | ❌ | ✅ |
| 批量操作 | ❌ | ✅ |
配置
| 环境变量 | 描述 | 默认值 |
|---|---|---|
DOTNET_SOLUTION_PATH | .sln、.slnx 或 .slnf 文件(或恰好包含一个此类文件的目录)的路径,用于在启动时自动加载;加载会与请求循环并行运行,因此 initialize 会立即响应 | 无(必须调用 load_solution) |
SHARPLENS_ABSOLUTE_PATHS | 使用绝对路径而非相对路径 | false(相对路径可节省令牌) |
SHARPLENS_LOG_LEVEL | 日志详细程度:Trace、Debug、Information、Warning、Error | Information |
SHARPLENS_TIMEOUT_SECONDS | 长时间运行操作的超时时间 | 30 |
SHARPLENS_MAX_DIAGNOSTICS | 返回的诊断信息上限 | 100 |
SHARPLENS_ENABLE_SEMANTIC_CACHE | 缓存文件路径到文档的查找结果 | true(设为 false 可禁用) |
这些变量在 1.6.0 之前使用的 ROSLYN_* 名称仍会作为备用名称读取;如果两种名称都已设置,则优先使用 SHARPLENS_*。布尔值不区分大小写。无法解析或低于最小值的数字会回退到默认值,超过最大值的数字则会被限制在最大值;每种情况都会向 stderr 记录警告。
多目标框架项目
面向多个目标框架构建的项目,对于所有工具而言都视为一个项目:每个结果仅报告一次;如果结果仅适用于部分框架,则会附带 targetFrameworks 列表。projectName 可接受纯名称(MyLib)以匹配所有框架,也可接受带框架限定的名称(MyLib(net8.0))以匹配单个框架。
如果未设置 DOTNET_SOLUTION_PATH,则必须先调用 load_solution 工具,才能使用其他工具。
从 1.5.x 工具名称迁移
工具名称不再带有 roslyn: 前缀——冒号不符合 MCP 工具名称模式(^[a-zA-Z0-9_-]{1,64}$),部分客户端会强制执行此模式。每个工具都保留原名称,只去掉前缀:
| 1.5.x 名称 | 1.6.0 名称 |
|---|---|
roslyn:load_solution | load_solution |
roslyn:get_diagnostics | get_diagnostics |
roslyn:rename_symbol | rename_symbol |
| ...所有工具均遵循相同规则... | 去掉 roslyn: 前缀 |
tools/list 仅发布新名称。旧的带前缀名称仍会作为别名接受一个版本周期,并将在下一个版本中移除。
AI Agent 配置提示
AI 模型可能会倾向于使用其原生工具(Grep、Read、LSP),而不是 MCP 服务工具,即使 SharpLensMcp 能提供更强的功能。
为确保工具使用达到最佳效果:
-
Claude Code:添加到项目的
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 -
其他 MCP 客户端:在 Agent 的系统提示词中配置工具优先级
Roslyn 的语义分析比基于文本的搜索更准确,尤其适用于重载方法、分部类和继承层次结构。
Agent 职责:文档同步
**重要:**SharpLensMcp 会在内存中维护解决方案的表示,以便快速查询。通过 Edit/Write 工具在外部修改文件时,Agent 负责同步这些更改。
何时调用 sync_documents:
| 操作 | 是否调用 sync_documents? |
|---|---|
| 使用 Edit 工具修改了 .cs 文件 | ✅ 是 |
| 使用 Write 工具创建了新的 .cs 文件 | ✅ 是 |
| 删除了 .cs 文件 | ✅ 是 |
| 使用 SharpLensMcp 重构工具(重命名、提取等) | ❌ 否(自动更新) |
| 修改了 .csproj 文件 | ❌ 否(改用 load_solution) |
用法:
# After editing specific files
sync_documents(filePaths: ["src/MyClass.cs", "src/MyService.cs"])
# After bulk changes - sync all documents
sync_documents()
完整同步还会纳入项目编译项所包含的新 .cs 文件。SharpLensMcp 的应用工具只会写入编辑所更改的文件,保留每个文件的编码和换行符;如果目标文件自读取后在磁盘上发生了更改,工具会拒绝操作并返回 STALE_DOCUMENT——请运行 sync_documents,然后重试。如果文件的编码无法还原其字节内容,工具也会拒绝写入并返回 UNSUPPORTED_ENCODING(例如,在系统回退代码页为 UTF-8 的系统上,如 Linux,一个没有 BOM 且不是有效 UTF-8 的文件);请先将其另存为 UTF-8。
为什么采用这种设计?
这与 LSP(语言服务器协议)的工作方式一致——客户端(编辑器)通知服务端发生了更改。这种方法:
- 消除竞态条件(由 Agent 控制时机)
- 避免文件监视器的复杂性和平台差异
- 比重新加载整个解决方案更快
- 让 Agent 能明确控制工作区状态
**如果不同步:**查询可能会返回过时数据(旧的方法签名、缺失的新文件等)
功能
- 92 种语义分析工具 - 导航、重构、代码生成、诊断、发现、审计/质量
- 针对 AI 优化的描述 - 清晰的 USAGE/OUTPUT/WORKFLOW 模式
- 结构化响应 - 统一的
success/error/data格式,并包含suggestedNextTools - 从零开始的坐标 - 提供清晰警告,避免出现偏移一位的错误
- 预览模式 - 应用前预览,确保安全重构
- 批量操作 - 一次调用完成多项查询,降低上下文占用
工具类别
导航与发现(24 个工具)
| 工具 | 描述 |
|---|---|
get_symbol_info | 指定位置的语义信息 |
go_to_definition | 跳转到符号定义 |
find_references | 查找所有引用;每个引用均分类为读取/写入/调用/转换/typeof/nameof/特性;可选 kind 筛选器 |
find_implementations | 查找接口/抽象成员的实现 |
find_callers | 影响分析——谁调用了此成员? |
get_call_graph | 多跳调用方/被调用方关系图,带深度限制和循环检测 |
find_path_between | 查找两个方法之间的可达性和连接调用路径;跟踪分派,支持屏障和检查点 |
get_type_hierarchy | 继承链 |
search_symbols | Glob 模式搜索(*Handler、Get*) |
semantic_query | 多条件筛选搜索(async、public 等) |
get_type_members | 按类型名称查找所有成员 |
get_type_members_batch | 一次调用查询多个类型 |
get_method_signature | 按名称查找详细签名 |
get_derived_types | 查找所有子类 |
get_base_types | 完整继承链 |
get_attributes | 列出符号上的特性 |
get_containing_member | 查找指定位置的外层符号 |
get_method_overloads | 查找方法的所有重载 |
find_attribute_usages | 按特性查找类型/成员 |
get_external_type_info | 检查 NuGet/BCL/外部程序集类型——成员及 XML 文档 |
resolve_stack_trace | 将粘贴的堆栈跟踪映射到文件/行/符号,并还原名称改编 |
get_extension_methods | 查找适用于某类型的扩展方法——传统扩展方法和 C# 14 块 |
get_documentation | 获取符号的完整 XML 文档,并展开 <inheritdoc> |
get_super_method | 导航到成员实现的基类成员/接口成员 |
分析(17 个工具)
| 工具 | 描述 |
|---|---|
get_diagnostics | 编译器错误/警告及已配置的分析器发现项(StyleCop、Roslynator、NetAnalyzers);与 CI 结果一致 |
diff_api_surface | 对比 git 引用,报告公共 API 破坏性变更 |
get_exception_flow | 方法可能抛出的异常,以及捕获位置 |
find_similar_code | 结构相似性搜索(基于令牌分片指纹) |
remove_unused_code | 计算死代码移除项和新增的未使用 using(仅生成) |
find_dead_branches | 查找每个方法中的不可达基本块(使用真实 CFG,而非启发式方法) |
add_missing_imports | 计算可修复 CS0246/CS0103 的 using(仅生成) |
analyze_data_flow | 变量赋值与使用情况 |
analyze_control_flow | 分支与可达性 |
analyze_change_impact | 更改后会有哪些内容受到影响? |
check_type_compatibility | A 是否可以赋值给 B? |
get_outgoing_calls | 此方法会调用什么? |
find_unused_code | 检测死代码 |
validate_code | 不写入文件的编译检查 |
get_complexity_metrics | 圈复杂度、嵌套层级、LOC、认知复杂度 |
find_circular_dependencies | 检测项目和命名空间循环依赖 |
get_missing_members | 查找未实现的接口/抽象成员 |
重构(16 个工具)
| 工具 | 描述 |
|---|---|
rename_symbol | 在整个解决方案中安全重命名 |
change_signature | 添加、删除或重新排列参数 |
extract_method | 通过数据流分析提取方法 |
extract_interface | 从类生成接口 |
generate_constructor | 根据字段和属性生成构造函数 |
move_type_to_file | 计算将类型移入独立文件的内容(仅生成) |
split_type | 为选定成员计算分部类拆分方案(仅生成) |
organize_usings | 排序并移除未使用的 using |
organize_usings_batch | 批量整理多个文件中的 using |
format_document_batch | 批量格式化项目中的文件 |
get_code_actions_at_position | 获取指定位置的所有 Roslyn 重构 |
apply_code_action_by_title | 按标题应用任意重构 |
implement_missing_members | 生成接口存根 |
encapsulate_field | 将字段转换为属性 |
inline_variable | 内联临时变量 |
extract_variable | 将表达式提取为变量 |
代码生成(3 个工具)
| 工具 | 描述 |
|---|---|
add_null_checks | 生成 ArgumentNullException 防护代码 |
generate_equality_members | 生成 Equals/GetHashCode/运算符 |
generate_test_stub | 为方法生成可编译的测试骨架(自动检测测试框架) |
复合工具(7 个工具)
| 工具 | 描述 |
|---|---|
get_type_overview | 一次调用获取完整类型信息 |
analyze_method | 签名、调用方、发出的调用和位置 |
get_file_overview | 文件摘要及诊断信息 |
get_method_source | 按名称获取源代码 |
get_method_source_batch | 一次调用获取多个方法的源代码 |
get_instantiation_options | 如何创建某个类型 |
get_project_health | 综合审查仪表板:每个项目的诊断、未使用项、耦合度和覆盖率 |
审查与质量(10 个工具)
| 工具 | 描述 |
|---|---|
find_god_objects | 通过传出耦合、传入耦合和成员数量阈值检测过度耦合的类型 |
find_untested_code | 查找没有测试覆盖的公共 API;可检测 xUnit、NUnit、MSTest、TUnit、Reqnroll 和 SpecFlow 测试,并识别其配置、测试夹具和步骤绑定 |
find_tests | 查找覆盖某个符号的测试——与 find_untested_code 相反 |
find_type_instantiations | 查找类型的构造位置(new T) |
find_pattern_usages | 查找类型出现在 is/as/模式匹配中的位置 |
find_throw_sites | 查找抛出某异常类型的位置(可选包含派生类型) |
find_catch_blocks | 查找捕获某异常类型的位置(可选通过基类子句匹配) |
find_async_issues | 检测 async void、异步操作阻塞和未转发的 CancellationToken |
check_architecture | 基于类型图强制执行命名空间/项目依赖规则 |
find_naming_violations | 根据 .editorconfig 规则进行命名审查,并采用常规默认规则 |
发现(3 个工具)
| 工具 | 描述 |
|---|---|
get_di_registrations | 扫描 DI 服务注册 |
find_reflection_usage | 检测反射/动态用法 |
find_interceptors | 展示 [InterceptsLocation] 调用重定向,包括生成的代码 |
基础设施(12 个工具)
| 工具 | 描述 |
|---|---|
health_check | 服务器状态 + 加载完整性(partial 标志、已声明与已加载的项目、loadFailures、loadWarnings、lastLoadFailure)——检查但不重新加载 |
find_unused_dependencies | 编译器永远不需要的 PackageReferences/ProjectReferences |
fix_all | 为某个诊断 ID 的每个实例计算修复方案(仅生成) |
load_solution | 加载 .sln/.slnx/.slnf;分别报告部分加载(partial + loadFailures:被丢弃的项目、还原失败、加载时未包含引用的项目)和 MSBuild 警告(loadWarnings) |
sync_documents | 将文件变更同步到已加载的解决方案 |
get_project_structure | 解决方案结构 |
dependency_graph | 项目依赖关系 |
get_code_fixes | 针对某个诊断的可用修复 |
apply_code_fix | 应用指定的代码修复 |
get_nuget_dependencies | 按项目列出 NuGet 包 |
get_source_generators | 列出活动的源生成器 |
get_generated_code | 查看生成的源代码 |
其他 MCP 客户端
对于 Claude Code 以外的 MCP 客户端,请将以下内容添加到配置中:
{
"mcpServers": {
"sharplens": {
"command": "sharplens",
"args": [],
"env": {
"DOTNET_SOLUTION_PATH": "/path/to/your/Solution.sln (or .slnx)"
}
}
}
}
用法
- 加载解决方案:调用
load_solution,并提供.sln或.slnx文件的路径(或设置DOTNET_SOLUTION_PATH) - 分析代码:使用 92 个工具中的任意一个进行导航、分析、重构和审计
- 安全重构:应用变更前,通过
preview: true预览变更
架构
MCP Client (AI Agent)
| stdin/stdout (JSON-RPC 2.0)
v
SharpLensMcp
- Protocol handling
- 92 AI-optimized tools
|
v
Microsoft.CodeAnalysis (Roslyn)
- MSBuildWorkspace
- SemanticModel
- SymbolFinder
要求
- .NET 8.0 SDK 或更高版本——适用于 .NET 8、9、10 及未来版本。可分析任何 .NET 8+ 项目/解决方案。
- 与 MCP 兼容的 AI Agent
常见问题
为什么该工具以 net8.0 为目标框架——它能分析我的 .NET 9 / .NET 10 项目吗?
可以。net8.0 是该工具自身的最低运行时要求——它所基于的 Roslyn 5.x 包需要此版本——而不是它能够分析的版本上限。RollForward 允许已安装的工具在更新的 .NET 运行时上运行,而 MSBuildWorkspace 会从每个项目的 csproj 加载其实际目标框架,因此一次安装即可分析面向 .NET 8、9、10 及更高版本的解决方案。
开发
添加新工具
- 在对应的
src/RoslynService.*.cs部分类中添加方法(Navigation、Analysis、Refactoring、CallAnalysis 等),并通过共享响应封装返回:
public async Task<object> YourToolAsync(string param1, int? param2 = null,
CancellationToken cancellationToken = default)
{
EnsureSolutionLoaded();
// Your logic...
return CreateSuccessResponse(
data: new { /* results */ },
suggestedNextTools: new[] { "next_tool_hint" }
);
}
-
在
src/ToolRegistry.cs中注册一个ToolDefinition——包括名称、描述、输入架构、ReadOnly标志(修改型工具设置ReadOnly: false,并接收destructiveHint注解),以及通过JsonRpcParameters绑定参数并调用方法的处理程序。注册表负责tools/list和分派;无需编辑单独的 switch。两项测试确保注册信息准确无误:ToolsListGoldenTests按字节锁定已发布的架构(有意更改架构时需重新捕获 golden),ToolSchemaParityTests则断言处理程序读取的每个参数都已在架构中声明。 -
构建并发布:
dotnet build -c Release
dotnet publish -c Release -o ./publish
- 添加两个层级的测试——针对确定性 fixture 测试
RoslynService方法的单元测试,以及通过 MCP 分派器进行的 wire 测试(位于tests/SharpLensMcp.Tests/Mcp/),其中包含精确值锁定和错误路径测试。这是必需项;请参阅测试。
测试
每项测试都必须符合 tests/SharpLensMcp.Tests/TESTING.md 中的 测试章程(C1–C9)——这是长期有效的契约。核心规则如下:
- 锁定精确值(C1):断言具体名称 / 数量 / 子字符串 / 错误代码 /
(line, column)——绝不能只用NotBeNull/> 0/ 仅检查类型作为唯一断言。 - 每个工具都覆盖两个层级(C4):针对
Fixtures/*.csfixture 的单元测试,以及会解包content[0].text的调度器(wire)测试,另加一条错误路径。 - 使用正确的大小写(C3):进程内 Newtonsoft 会生成 PascalCase 的
error.Code/meta.TotalCount;MCP wire 会生成 camelCase。应读取测试路径实际产生的大小写形式。 - 保证确定性(C7):测试套件通过
xunit.runner.json串行运行;fixture 修改器始终恢复原状;超时测试使用强制取消接缝,而非依赖计时竞争。 - 进程外主干测试(C6):
StdioIntegrationTests通过真实二进制对每个类别的一个工具锁定具体值,并通过 stdio 管道运行tools/list黄金测试。 - 提交前检查关卡(C9):构建通过且测试全绿是必要条件,但还不够——重新阅读每项变更过的测试,并确认错误答案会导致测试失败。
运行测试套件:
dotnet test -c Release
关键文件
| 文件 | 用途 |
|---|---|
src/RoslynService.cs + src/RoslynService.*.cs partials | 按关注点拆分到约 30 个 partial 中的工具实现(Navigation、Analysis、Refactoring、Inspection、Validation、TypeDiscovery、Discovery、ExternalApi、Quality、Metrics、CodeActions、CodeGeneration、Compound、CallAnalysis、ExceptionFlow、StackTrace、ApiSurface、SimilarCode,……)——每个文件的名称都能预示其内容 |
src/McpServer.cs | MCP 协议机制:JSON-RPC 解析循环、initialize 协商、每次调用的超时、带内错误与协议错误的映射 |
src/ToolRegistry.cs + src/ToolDefinition.cs | 工具接口:每个工具对应一条 ToolDefinition 记录(名称、架构、ReadOnly 标志、处理程序)。决定 tools/list 的顺序和调度查找 |
src/JsonRpcParameters.cs + JsonRpcInvalidParamsException.cs | 类型化 JSON-RPC 参数访问器,以及它们引发的 -32602 Invalid params 异常 |
src/*Data.cs / *Entry.cs records、ConstructorMember.cs、SignatureChange.cs | 审计组合、构造函数生成器和签名变更解析器所用的类型化记录(每个文件一种类型) |
许可证
MIT - 详见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。