内容
# RoselineMCP
> **Roslyn 代码智能,用于 AI 编程代理,基于 MCP。** 为 Claude、Cursor 和 Copilot 提供 C# 解决方案的语义视图 - 符号、引用、调用图、手术编辑 - 以便它们通过*结构*而不是重新阅读源代码来进行导航。 **[实测 81% 更少的 tokens →](https://atypical-consulting.github.io/RoselineMCP/benchmark)**
<!-- Badges: Row 1 — Identity -->
[](https://github.com/Atypical-Consulting/RoselineMCP)
[](https://opensource.org/licenses/MIT)
[](https://dotnet.microsoft.com/)
[](https://github.com/Atypical-Consulting/RoselineMCP)
[](https://github.com/Atypical-Consulting/RoselineMCP)
<!-- Badges: Row 2 — Activity -->
[](https://github.com/Atypical-Consulting/RoselineMCP/releases/)
[](https://github.com/Atypical-Consulting/RoselineMCP/issues)
[](https://github.com/Atypical-Consulting/RoselineMCP/pulls)
[](https://github.com/Atypical-Consulting/RoselineMCP/commits/main)
<!-- Badges: Row 3 — Quality -->
[](https://github.com/Atypical-Consulting/RoselineMCP/actions/workflows/ci.yml)
<!-- Badges: Row 4 — Distribution -->
[](https://www.nuget.org/packages/RoselineMCP/)
[](https://hub.docker.com/r/phmatray/roseline-mcp)
<!-- Badges: Row 5 — Docs & result -->
[](https://atypical-consulting.github.io/RoselineMCP/)
[](https://atypical-consulting.github.io/RoselineMCP/benchmark)
**📖 [文档,工具参考和基准测试 →](https://atypical-consulting.github.io/RoselineMCP/)**
---
## 目录
- [为什么选择 RoselineMCP](#为什么选择RoselineMCP)
- [快速开始](#快速开始)
- [功能](#功能)
- [技术栈](#技术栈)
- [开始使用](#开始使用)
- [MCP 客户端兼容性](#MCP客户端兼容性)
- [可用工具](#可用工具)
- [工具注释](#工具注释)
- [工具兼容性政策](#工具兼容性政策)
- [架构](#架构)
- [项目结构](#项目结构)
- [安全](#安全)
- [文档](#文档)
- [路线图](#路线图)
- [贡献](#贡献)
- [许可证](#许可证)
- [致谢](#致谢)
## 为什么选择 RoselineMCP
您的编码代理不应该阅读一个 700 行的文件来更改一个方法。源代码主导了代理的 token 预算,因此最便宜的改进是停止向它提供整个文件。
RoselineMCP 将 [Roslyn](https://github.com/dotnet/roslyn) 编译器平台封装为 MCP 服务器。不是将源代码转储到模型中,而是它精确地回答*结构*问题 - 这个符号在哪里使用,实现这个接口的是什么,调用这个方法的是什么,文件的结构是什么 - 并且进行**手术编辑**:成员级差异,而不是整个文件重写。
在 RoselineMCP 自己的源代码中,只读导航工具返回了 **平均 81%(中位数 74%)更少的 tokens**,而不是读取相应的文件 - [诚实地测量,包括弱情况](https://atypical-consulting.github.io/RoselineMCP/benchmark)。
> 在 `Program.cs` 上执行 `search_symbols`:**1,154 tokens → 125**(-89%)。代理获取文件的结构;您可以跳过墙。
## 快速开始
任何支持 `dnx`(.NET 等效于 `npx`)的 MCP 客户端都可以在运行时启动它 - 无需安装步骤。需要 .NET 10 SDK。
```jsonc
// claude_desktop_config.json · .vscode/mcp.json · ~/.cursor/mcp.json
{
"mcpServers": {
"roseline": { "command": "dnx", "args": ["RoselineMCP", "--yes"] }
}
}
```
然后要求您的代理执行 *"查找 `OrderService.Checkout` 的所有调用者"* 或 *"将整个解决方案中的 `Foo` 重命名为 `Bar`"。* 优先使用固定的 NuGet 安装或 Docker?请参阅 [开始使用](#开始使用)。
## 功能
- [x] **Token 高效的代码导航** -- 通过 Roslyn 而不是整个文件提供符号、引用、调用图、类型层次结构和文件大纲。实测 **81% pooled / 74% 中位数** token 减少 - [查看基准测试](https://atypical-consulting.github.io/RoselineMCP/benchmark)。
- [x] **手术代码编辑** -- 替换/添加/删除成员或在整个解决方案中重命名符号,发出统一的差异而不是整个文件重写。默认情况下预览。
- [x] **全面分析和自动修复** -- 整个解决方案的诊断(Roslyn + Roslynator)带有自动修复和可审查的补丁。
- [x] **默认只读** -- 六个导航工具和诊断/补丁工具从不触摸磁盘;三个写入工具需要显式的 `previewOnly: false`。
- [x] **与您的客户端配合使用** -- Claude Desktop、VS Code(Copilot / MCP)、Cursor。通过 `dnx`、NuGet 全局工具或 Docker 安装。
- [x] **诚实、可复制的基准测试** -- 在您自己的解决方案上运行:`dotnet run --project RoselineMCP.TokenBenchmark -c Release`。
## 技术栈
| 层 | 技术 |
|-------|-----------|
| 运行时 | .NET 10.0 |
| 编译器平台 | Roslyn(Microsoft.CodeAnalysis)5.3.0 |
| 分析器 | Roslynator 4.15.0 |
| MCP SDK | ModelContextProtocol 1.4.0 |
| 差异引擎 | DiffPlex 1.9.0 |
| 构建系统 | MSBuild 18.7.1 |
| 主机 | Microsoft.Extensions.Hosting 10.0.9 |
> 上述版本与 [`RoselineMCP/RoselineMCP.csproj`](RoselineMCP/RoselineMCP.csproj) 保持同步 - 如果此表格与实际版本不符,该文件是真实来源。
## 开始使用
### 要求
- **NuGet 全局工具**:.NET 10.0 SDK 或更高版本
- **Docker**:Docker Desktop 或 Docker Engine
- **从源代码构建**:.NET 10.0 SDK + MSBuild(随 Visual Studio 或 .NET SDK 捆绑)
- **MCP 客户端**:Claude Desktop 或任何 MCP 兼容的客户端
### 安装
**选项 1 -- `dnx`(无需安装步骤)** *(推荐)*
RoselineMCP 提供了 [MCP 服务器注册清单](.mcp/server.json),因此任何理解 `dnx` 启动器(.NET 等效于 `npx` - 在运行时解析并运行 NuGet 包装的工具)的 MCP 客户端都可以直接启动它。需要 .NET 10.0 SDK。
```json
{
"mcpServers": {
"roseline": {
"command": "dnx",
"args": ["RoselineMCP", "--yes"]
}
}
}
```
将此内容添加到您的 Claude Desktop 或 VS Code MCP 配置中(有关每个客户端的确切文件位置,请参见下文 [MCP 客户端兼容性](#MCP客户端兼容性))。`dnx` 在首次使用时下载并缓存工具,因此无需全局预安装。
---
**选项 2 -- NuGet 全局工具** *(离线/固定版本安装)*
需要 .NET 10.0 SDK 或更高版本。
```bash
dotnet tool install -g RoselineMCP
```
安装后,`roseline-mcp` 命令可在全局范围内使用。
#### Claude Desktop 配置(NuGet 全局工具)
将以下内容添加到您的 Claude Desktop 配置文件(`claude_desktop_config.json`):
```json
{
"mcpServers": {
"roseline": {
"command": "roseline-mcp"
}
}
}
```
> **配置文件位置:**
> - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
> - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
---
**选项 3 -- Docker**
无需 SDK。适用于已安装 Docker 的任何平台。
```bash
docker run -i --rm phmatray/roseline-mcp:latest
```
#### Claude Desktop 配置(Docker)
```json
{
"mcpServers": {
"roseline": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"phmatray/roseline-mcp:latest"
]
}
}
}
```
> **注意:** `-i` 标志对于 stdio 传输是必需的。`--rm` 标志在会话结束时删除容器。
---
**选项 4 -- 从源代码构建**
```bash
git clone https://github.com/Atypical-Consulting/RoselineMCP.git
cd RoselineMCP
dotnet build
dotnet test
```
#### Claude Desktop 配置(从源代码构建)
```json
{
"mcpServers": {
"roseline": {
"command": "dotnet",
"args": ["run", "--project", "/path/to/RoselineMCP/RoselineMCP.csproj"]
}
}
}
```
## MCP 客户端兼容性
RoselineMCP 支持纯 stdio MCP,因此它应该与任何兼容的 MCP 客户端一起使用。下面提供的代码片段**已记录,但未在每个情况下独立验证** - 我们已确认协议级行为(stdio 传输、工具发现、JSON 响应)正确,但我们尚未亲自测试每个客户端的配置 UI/文件端到端。如果其中一个客户端无法按写入内容正常工作,请打开一个问题。
<details>
<summary><strong>Claude Desktop</strong></summary>
编辑 `claude_desktop_config.json`(有关文件位置,请参见上面的 [开始使用](#开始使用))并在 `mcpServers` 下添加一个 `roseline` 条目,使用上述四种安装选项中的任意一个。
</details>
<details>
<summary><strong>VS Code(GitHub Copilot / MCP 扩展)</strong></summary>
在您的工作区或用户 `mcp.json` 中添加一个条目(命令面板 → “MCP: 打开用户配置”或 `.vscode/mcp.json` 在工作区):
```json
{
"servers": {
"roseline": {
"command": "dnx",
"args": ["RoselineMCP", "--yes"]
}
}
}
```
如果您改为使用 NuGet 全局工具,请替换 `"command": "roseline-mcp"`(无 `args`)。
</details>
<details>
<summary><strong>Cursor</strong></summary>
在 `~/.cursor/mcp.json`(全局)或 `.cursor/mcp.json`(项目本地)中添加一个 `roseline` 条目,使用与上述 VS Code 代码段相同的 `command`/`args` 形状。
</details>
## 可用工具
### 1. 分析解决方案
分析整个 C# 解决方案的诊断信息。只读 - 永远不会修改磁盘上的文件。
`pathOrGit` 也接受一个 `http(s)://` Git URL,该 URL 被浅克隆到临时目录,分析后被删除。
```typescript
analyzeSolution({
pathOrGit: "/path/to/solution.sln",
include: "Core", // 可选:仅包含项目名称中包含此子字符串的项目
exclude: "Test", // 可选:跳过项目名称中包含此子字符串的项目
severity: "warning", // 可选:最低严重性(Error|Warning|Info|Hidden)
maxDiagnostics: 100 // 可选:要返回的最大诊断信息数量(默认:100)
})
```
**返回:** 解决方案文件名、项目计数、`diagnosticSummary`(按严重性分组的计数)和 `topDiagnostics` 数组,每个诊断信息包含项目/文件/行/列/ ID/严重性/消息。
### 2. 列出诊断信息
获取特定项目的详细诊断信息。只读 - 永远不会修改磁盘上的文件。
```typescript
listDiagnostics({
project: "MyProject.csproj",
ids: ["CS0168", "CS0219"], // 可选:按诊断 ID 过滤
files: ["Controller.cs"], // 可选:按诊断文件的路径子字符串匹配(不区分大小写;不是 glob 模式)
max: 50 // 可选:最大结果数
})
```
**返回:** 项目名称、`totalDiagnostics` 计数、筛选后的 `diagnostics` 列表、`stats`(按 ID 和严重性分组的计数)和 `suggestedFixableIds` - 代码修复提供者实际注册的诊断 ID。
### 3. 应用修复
应用指定诊断的自动代码修复。**默认预览模式**:`previewOnly` 默认值为 `true`,因此调用此工具时不会写入磁盘 - 您必须显式传递 `previewOnly: false` 以应用更改。
```typescript
applyFixes({
project: "MyProject.csproj",
ids: ["CS0168", "RCS1001"], // 要修复的诊断 ID
previewOnly: false // 可选(默认:true)。设置为 false 以写入磁盘上的更改。
})
```
**返回:** 项目名称、`fixedCount`、`fixersApplied`(实际修复的诊断 ID)、`changedFiles`、统一的差异 `patch`、`notes`(跳过/失败的 ID 和状态消息)和 `previewOnly` 回声,指示是否写入了任何内容。
### 4. 创建补丁
在两个文本版本之间生成统一的差异。只读 - 纯粹在提供的字符串上运行,永远不会触摸文件系统。
```typescript
createPatch({
before: "原始代码",
after: "修改后的代码",
fileName: "Example.cs", // 可选:用于在差异中显示
ignoreWhitespace: false, // 可选:忽略仅空白差异
ignoreCase: false // 可选:忽略大小写差异
})
```
**返回:** 统一的差异 `patch`、`hasChanges`、`linesAdded`、`linesRemoved` 和用于差异标题的 `fileName`/`summary`。
### 代码导航工具(只读)
这些工具返回**精确的结构信息,而不是整个文件**,因此 AI 代理可以在代码库中定位,同时比直接读取源代码花费的 token 数量少得多。所有这些工具都是只读的,作用于一个 `project`(名称、目录或 `.csproj` 路径);当项目属于解决方案时,将加载整个解决方案,以便引用/重命名跨项目。完整的请求/响应格式在 [docs/API.md](docs/API.md) 中。
> **线路上的工具名称为 `snake_case`。** 下面的章节标题使用友好的 PascalCase/`camelCase` 以提高可读性,但 `tools/list` 返回的实际 MCP 工具名称(以及 `tools/call` 期望的名称)为:`search_symbols`、`get_symbol_info`、`find_references`、`find_implementations`、`get_call_graph`、`get_type_hierarchy`、`edit_member`、`rename_symbol`(与现有的 `analyze_solution` / `list_diagnostics` / `apply_fixes` / `create_patch` 匹配)。
#### 5. 搜索符号
按通配符/子字符串名称模式查找符号,或大纲单个文件。
```typescript
searchSymbols({
project: "MyApp.Core",
query: "*Service", // 子字符串,或带 * 和 ? 的通配符 - 省略以大纲文件
file: "UserService.cs", // 可选:限制为一个文件,或省略查询时大纲
kinds: ["class", "method"], // 可选:按类型过滤(也接受"type" / "member")
max: 50 // 可选:(默认:50)
})
```
**返回:** `symbols`(名称、fullName、kind、signature、accessibility、file、line、containingType)、`totalFound`、`truncated`。
#### 6. 获取符号信息
符号的紧凑“转到定义”:符号的声明元数据和(可选)其源代码。
```typescript
getSymbolInfo({
project: "MyApp.Core",
symbol: "Acme.Users.UserService.GetUser", // 简单或完全限定的名称
includeSource: true // 可选(默认:true)
})
```
**返回:** 名称、fullName、kind、accessibility、modifiers、signature、baseTypes、interfaces、documentation、definitionFile/Line 和(可选)源代码。
#### 7. 查找引用
解决方案中每个符号的使用位置,以位置 + 一行代码片段形式呈现。
```typescript
findReferences({ project: "MyApp.Core", symbol: "GetUser", includeDefinition: false, max: 100 })
```
**返回:** `references`(file、line、column、snippet)、`totalReferences`、`truncated`。
#### 8. 查找实现
接口/成员的实现,方法的重写或类的派生类型。
```typescript
findImplementations({ project: "MyApp.Core", symbol: "IRepository", max: 100 })
```
**返回:** `implementations`(符号摘要)、`totalFound`、`truncated`。
#### 9. 获取调用图
具有循环检测的深度有界的调用者和/或被调用者图。
```typescript
getCallGraph({
project: "MyApp.Core",
method: "Handle",
direction: "callers", // "callers"(默认)| "callees" | "both"
depth: 1, // 1-3(默认:1)
max: 50 // 可选:每个方向展开的节点数
})
```
**返回:** `callers`/`callees` 节点树(fullName、signature、file、line、truncated、children)。
#### 10. 获取类型层次结构
类型的基类链、实现的接口和/或派生类型。
```typescript
getTypeHierarchy({ project: "MyApp.Core", type: "SqlRepository", direction: "both" }) // "base" | "derived" | "both"
```
**返回:** `baseTypes`、`interfaces`、`derivedTypes`(作为符号摘要)。
### 代码编辑工具(默认预览)
对代码进行外科手术编辑,发出成员级更改而不是整个文件重写。像 `ApplyFixes` 一样,**两者都默认为预览模式**(`previewOnly: true`)- 除非您显式传递 `previewOnly: false`,否则不会写入磁盘。
#### 11. 编辑成员
替换、添加或删除单个类型成员;返回统一的差异。
```typescript
editMember({
project: "MyApp.Core",
symbol: "Acme.UserService.GetUser", // 成员(替换/删除),或容器类型(添加)
operation: "replace", // "replace" | "add" | "delete"
newSource: "public User GetUser(int id) => _repo.Find(id);", // 替换/添加所需
previewOnly: false // 可选(默认:true)。设置为 false 以写入磁盘。
})
```
**返回:** 操作、目标、`changedFiles`、`patch`、`previewOnly`、`applied`、`notes`。
#### 12. 重命名符号
重命名符号并更新整个解决方案中的所有引用(Roslyn 重命名);返回统一的差异。
```typescript
renameSymbol({ project: "MyApp.Core", symbol: "GetUser", newName: "GetUserById", previewOnly: false })
```
**返回:** `symbol`, `newName`, `changedFiles`, `patch`, `previewOnly`, `applied`, `notes`.
## 工具注解
RoselineMCP 的 SDK(`ModelContextProtocol` 1.4.0)支持标准的 MCP 工具注解(`readOnlyHint`、`destructiveHint`、`idempotentHint`),每个工具通过 `[McpServerTool(ReadOnly = ..., Destructive = ..., Idempotent = ...)]` 声明:
| 工具 | readOnlyHint | destructiveHint | idempotentHint | 备注 |
|------|:---:|:---:|:---:|-------|
| `AnalyzeSolution` | ✅ true | ❌ false | ✅ true | 绝不写入磁盘。 |
| `ListDiagnostics` | ✅ true | ❌ false | ✅ true | 绝不写入磁盘。 |
| `ApplyFixes` | ❌ false | ⚠️ true | ❌ false | `destructiveHint` 是一个静态的、最坏情况的注解:它是 `true`,因为该工具 *可以* 在传递 `previewOnly: false` 时写入文件,即使默认调用(`previewOnly` 未设置,即 `true`)不写入任何内容。SDK 的注解模型无法表达“仅针对特定参数值具有破坏性”—请参见源码中的 `ApplyFixesTool.ApplyFixes` 文档注释。 |
| `CreatePatch` | ✅ true | ❌ false | ✅ true | 纯粹在提供的两个字符串上运行;绝不触及文件系统。 |
| `SearchSymbols` | ✅ true | ❌ false | ✅ true | 绝不写入磁盘。 |
| `GetSymbolInfo` | ✅ true | ❌ false | ✅ true | 绝不写入磁盘。 |
| `FindReferences` | ✅ true | ❌ false | ✅ true | 绝不写入磁盘。 |
| `FindImplementations` | ✅ true | ❌ false | ✅ true | 绝不写入磁盘。 |
| `GetCallGraph` | ✅ true | ❌ false | ✅ true | 绝不写入磁盘。 |
| `GetTypeHierarchy` | ✅ true | ❌ false | ✅ true | 绝不写入磁盘。 |
| `EditMember` | ❌ false | ⚠️ true | ❌ false | 与 `ApplyFixes` 相同的最坏情况 `destructiveHint` 理由:仅当传递 `previewOnly: false` 时写入文件;默认调用不写入任何内容。 |
| `RenameSymbol` | ❌ false | ⚠️ true | ❌ false | 与 `ApplyFixes` 相同的最坏情况 `destructiveHint` 理由:仅当传递 `previewOnly: false` 时写入文件;默认调用不写入任何内容。 |
这些注解是每个工具的静态元数据,供 MCP 客户端显示(例如,在调用破坏性工具之前警告用户);它们描述了工具的最坏情况行为,而不是任何特定调用的结果。请参见下面的[工具兼容性策略](#工具兼容性策略),了解围绕工具名称和参数的稳定性保证。
## 工具兼容性策略
- **工具名称和必需参数在主版本号内稳定。** 编写针对 `1.x` 版本的 `AnalyzeSolution(pathOrGit, ...)` 的 MCP 客户端集成将继续适用于所有 `1.x` 版本。
- **可以在小版本号中添加可选参数**(例如,`CreatePatch` 获得了可选的、具有默认值的 `ignoreWhitespace`/`ignoreCase` 参数,而不破坏现有调用者)。
- **重命名或删除参数、更改参数的必需/可选状态或更改工具名称是破坏性更改。** 破坏性更改在专用“Breaking Changes”标题下注明,仅在主版本号中发布。
- 响应 *形状*(JSON 字段名称/类型)在 [`docs/API.md`](docs/API.md) 中记录,并遵循相同的策略:附加字段是非破坏性的,重命名/删除字段是破坏性的。
## 支持的分析器
RoselineMCP 支持:
- **Roslyn 分析器** -- 内置的 C# 编译器诊断
- **Roslynator** -- 500 多个 C# 分析器、重构和修复
- **自定义分析器** -- 任何 Roslyn 基础的分析器,由您的解决方案引用(加载并运行方式与 Roslynator 相同;此存储库的 `.csproj` 中没有内置的 StyleCop.Analyzers 引用 — 如果您想使用 SA* 诊断,请将其添加到您分析的解决方案中)
## 示例
### 分析解决方案
```bash
# 与 MCP 客户端一起使用
mcp call analyzeSolution '{
"pathOrGit": "/Users/dev/MyProject/MyProject.sln",
"severity": "warning",
"maxDiagnostics": 50
}'
```
响应:
```json
{
"solution": "MyProject.sln",
"projects": 5,
"diagnosticSummary": {
"error": 2,
"warning": 15,
"info": 28
},
"topDiagnostics": [
{
"id": "CS0168",
"severity": "warning",
"message": "变量 'ex' 已声明但从未使用",
"file": "Program.cs",
"line": 42
}
]
}
```
### 应用修复
```bash
mcp call applyFixes '{
"project": "MyProject.Core.csproj",
"ids": ["CS0168", "RCS1001"],
"previewOnly": true
}'
```
响应包括一个统一的差异补丁,显示将应用的所有更改。
## 配置
### 环境变量
- `ROSELINE_LOG_LEVEL`: 设置日志级别(Debug、Information、Warning、Error)
- `ASPNETCORE_ENVIRONMENT`: 设置环境(Development、Production)
### appsettings.json
配置日志记录和其他设置:
```json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"RoselineMCP": "Debug"
}
},
"RoselineMCP": {
"DefaultTimeout": 120000,
"EnableDiagnosticLogging": false
}
}
```
- `RoselineMCP:DefaultTimeout`: 适用于每个工具调用的时钟超时(毫秒),除了调用者自己的取消之外。`0` 禁用它。
- `RoselineMCP:EnableDiagnosticLogging`: 工具调用的本地、仅限光纤跟踪 — 请参见[调试日志](#调试日志)。默认情况下禁用;在 `appsettings.Development.json` 中启用。
## 架构
RoselineMCP 使用 **stdio 传输** — 这是一个刻意的设计决定。服务器作为 MCP 客户端(Claude Desktop、AI 代理)启动的本地进程运行,通过 stdin/stdout 进行通信,并在客户端断开连接时退出。这使其非常适合作为 NuGet 全局工具(`dotnet tool install -g RoselineMCP`)或 Docker 镜像分发 — 无需绑定端口,无需 HTTP 服务器,无需管理的基础设施。
```
┌─────────────────────┐
│ MCP 客户端 │
│ (Claude Desktop, │
│ AI 助手) │
└────────┬────────────┘
│ MCP 协议(stdio)
▼
┌─────────────────────┐
│ RoselineMCP │
│ MCP 服务器 │
│ │
│ ┌───────────────┐ │
│ │ 工具层 │ │
│ │ (分析、 │ │
│ │ 修复、补丁) │ │
│ └───────┬───────┘ │
│ ▼ │
│ ┌───────────────┐ │
│ │ 服务层 │ │
│ │ (工作区、 │ │
│ │ 诊断) │ │
│ └───────┬───────┘ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Roslyn + │ │
│ │ Roslynator │ │
│ │ 分析器 │ │
│ └───────────────┘ │
└─────────────────────┘
│
▼
┌─────────────────────┐
│ C# 源代码 │
│ (.sln / .csproj) │
└─────────────────────┘
```
## 项目结构
```
RoselineMCP/
├── RoselineMCP/
│ ├── 接口/ # 服务接口
│ ├── 服务/ # 核心业务逻辑
│ ├── 工具/ # MCP 工具实现
│ ├── 模型/ # 数据传输对象
│ └── Program.cs # 应用程序入口点
├── RoselineMCP.Tests/ # 单元测试
├── .github/workflows/ # CI/CD 管道
├── Dockerfile # 容器构建
└── RoselineMCP.sln # 解决方案文件
```
## 性能
- **工作区隔离** -- 每个操作都会创建一个全新的 `MSBuildWorkspace`;在调用之间不会缓存或重用任何内容(请参见[架构](#架构))
- **顺序项目分析** -- 解决方案中的项目一次分析一个,而不是并发分析,以保持 MSBuild 工作区状态的一致性
- **结果上限** -- `maxDiagnostics`/`max` 限制了每个调用返回的诊断数量,与找到的诊断数量无关
## 安全
- **默认只读** -- `AnalyzeSolution`、`ListDiagnostics`、`CreatePatch` 和所有六个代码导航工具(`SearchSymbols`、`GetSymbolInfo`、`FindReferences`、`FindImplementations`、`GetCallGraph`、`GetTypeHierarchy`) 绝不写入磁盘。三个具有写入能力的工具 — `ApplyFixes`、`EditMember` 和 `RenameSymbol` — 每个工具默认 `previewOnly: true`;写入需要调用者显式传递 `previewOnly: false`。
- **真实的、只读的 Git 克隆** -- `pathOrGit` 接受 `http(s)://` Git URL,这些 URL 被浅克隆到临时目录中,并在操作完成后删除。没有其他 URL 方案被视为 Git 远程仓库。
- **MSBuild 不是沙盒** -- 通过 `MSBuildWorkspace` 加载 `.sln`/`.csproj` 是设计时 MSBuild 评估,可以执行项目中嵌入的生成逻辑(`<Exec>` 任务、自定义 `UsingTask` 程序集、导入的 `.targets`/`.props`)。分析完全不受信任的存储库或 URL 存在真正的代码执行风险。请在指向不受信任的输入之前阅读 [**SECURITY.md**](SECURITY.md) 以获取完整的说明和操作员建议。
- **没有专用的路径遍历沙盒** -- 路径通过简单的存在检查解析,而不是针对允许的根目录规范化;将 `pathOrGit`/`project`/`branch` 视为受信任的操作员输入。
## 故障排除
### 常见问题
1. **MSBuild 未找到**:确保已安装 .NET SDK 并在 PATH 中
2. **解决方案无法加载**:检查缺少的 NuGet 包,运行 `dotnet restore`
3. **未找到诊断**:验证目标项目中是否安装了分析器
4. **权限被拒绝**:确保对解决方案文件具有读取权限
### 调试日志记录
启用详细日志记录:
```bash
ROSELINE_LOG_LEVEL=Debug dotnet run --project RoselineMCP/RoselineMCP.csproj
```
### 跟踪各个工具调用
每个工具调用都有一个调用相关的关联 ID(GUID)。它的生成成本很低,因此始终会创建它,但在需要时才会显示出来:它包含在每个 JSON 错误响应(`correlationId`)中,并通过 `ILogger.BeginScope` 附加到该调用的日志行中,因此用户报告故障时可以提供一个 ID,该 ID 可以追溯到完整的服务器端日志条目 — 而无需 grep 时间戳。
对于更深入的、按需跟踪的工具调用(启动/停止、持续时间、成功/失败)作为 `System.Diagnostics.Activity` 跨度,设置 `RoselineMCP:EnableDiagnosticLogging` 为 `true`(在 `appsettings.Development.json` 中已经为 `true`):
```bash
ROSELINE_RoselineMCP__EnableDiagnosticLogging=true dotnet run --project RoselineMCP/RoselineMCP.csproj
```
这使用内置的 `ActivitySource`/`Activity` API 而不是 OpenTelemetry SDK,因此它不会添加额外的依赖项。跨度仅通过现有的 `ILogger` 管道记录,该管道已经路由到 stderr — 绝不会输出到 stdout(MCP JSON-RPC 通道)— 并且永远不会通过网络发送;当关闭该标志(默认值)时,跨度几乎不会产生任何成本。
## 路线图
- [ ] 额外的分析器规则集(SonarAnalyzer、FxCop)
- [ ] 带有置信度评分的自动修复建议
- [ ] 用于自动化分析管道的 CI/CD 集成
- [ ] 单个会话中的多解决方案支持
- [ ] 增量分析(仅更改的文件)
- [ ] 通过 MCP 自定义分析器规则配置
> 想要贡献吗?选择任何路线图项目并打开一个 PR!
## 文档
- **[文档站点](https://atypical-consulting.github.io/RoselineMCP/)** -- 概述、工具参考和[代币节省基准测试](https://atypical-consulting.github.io/RoselineMCP/benchmark)(从 `website/` 构建并部署到 GitHub Pages)
- [docs/API.md](docs/API.md) -- 每个 MCP 工具、服务接口、模型和错误响应合约的完整请求/响应参考
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) -- 分层架构、数据流和设计模式
- [PROMPTS.md](PROMPTS.md) -- 每个工具的示例提示和端到端工作流
- [CHANGELOG.md](CHANGELOG.md) -- 发布历史和破坏性更改
- [SECURITY.md](SECURITY.md) -- 漏洞报告和 MSBuild 代码执行注意事项
- [CONTRIBUTING.md](CONTRIBUTING.md) -- 开发设置和 PR 流程
## 贡献
欢迎贡献!请先阅读 [CONTRIBUTING.md](CONTRIBUTING.md)。
1. 复刻仓库
2. 创建功能分支(`git checkout -b feature/amazing-feature`)
3. 使用[约定提交](https://www.conventionalcommits.org/) 提交(`git commit -m 'feat: add amazing feature'`)
4. 将更改推送到分支(`git push origin feature/amazing-feature`)
5. 打开拉取请求
## 许可证
[MIT](LICENSE) © 2026 [Atypical Consulting SRL](https://atypical.garry-ai.cloud)
## 致谢
- 构建于 [Roslyn](https://github.com/dotnet/roslyn) -- .NET 编译器平台
- 由 [Roslynator](https://github.com/JosefPihrt/Roslynator) 提供支持 -- C# 分析器和重构
- 使用 [DiffPlex](https://github.com/mmanela/diffplex) -- 差异生成库
- 实现 [Model Context Protocol](https://modelcontextprotocol.io) -- AI 助手集成协议
---
由 [Atypical Consulting](https://atypical.garry-ai.cloud) 悉心打造 -- 有偏见的、生产级别的开源。
[](https://github.com/Atypical-Consulting/RoselineMCP/graphs/contributors)
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器