内容
# SharpBridge
MCP(模型上下文协议)服务器,使 AI 代理能够交互式地调试 .NET 程序。支持 **多个同时调试会话** — 一次启动或附加到多个进程。基于 **.NET 10** 和 **SharpDbg**,通过 **调试适配器协议(DAP)** 构建。
## 工作原理
```
AI 代理(Claude/Copilot/...)←→ MCP ←→ SharpBridge ←→ DAP ←→ SharpDbg ←→ 您的 .NET 应用程序
```
SharpBridge 将 MCP 工具调用转换为 DAP 调试命令,使 AI 编程代理能够设置断点、逐步执行代码、检查变量并在运行时评估表达式。在内部,它使用 [SharpDbg](https://github.com/MattParkerDev/SharpDbg),一个基于 ICorDebug 的 .NET 调试适配器 — 与 Visual Studio 使用的相同的基于 COM 的调试 API。
## 功能
- **多会话**:同时调试多个进程 — 每个进程都有自己的 DAP 连接、断点和状态
- **启动** .NET 程序进行调试,或 **附加** 到正在运行的进程(按 PID 或进程名称)
- **智能附加**:按名称自动检测单个或多个进程实例
- **会话管理**:`debug_select` 切换默认会话,`debug_list` 查看所有活动会话
- **22 个 MCP 工具**:会话管理、断点(自动捕获)、异常断点、执行控制、状态检查和快照捕获
- **智能检查**:`variables_get` 支持作用域选择(局部变量/参数/全部)、自动展开深度和按名称有针对性的展开 — 一次调用取代多次往返
- **异常断点**:`exception_breakpoints` 列出可用的筛选器并配置哪些异常会导致中断
- **自动捕获**:带有 `action="capture"` 的断点自动捕获变量并继续(按 `captureScope`/`captureDepth`),累积快照。`capture_state` / `get_captures` / `clear_captures` 管理状态快照
- **单个 STDIO 传输** — 零配置 MCP 集成
## 快速入门
### 先决条件
- [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet/10.0)(用于构建/运行要调试的 .NET 应用程序)
- 支持的 AI 编程代理(Claude Desktop、Claude Code、Cursor、GitHub Copilot 等)
### 选项 1:从 NuGet 安装(推荐)
```bash
dotnet tool install -g SharpBridge
```
然后将以下内容添加到您的 MCP 配置中(请参阅 [客户端特定路径](#配置您的mcp客户端)):
```json
{
"mcpServers": {
"sharpbridge": {
"command": "sharpbridge"
}
}
}
```
### 选项 2:从源代码构建
```bash
git clone https://github.com/gang2k-coder/SharpBridge.git
cd SharpBridge
dotnet build
```
从源代码构建时,请使用以下 MCP 配置:
```json
{
"mcpServers": {
"sharpbridge": {
"command": "dotnet",
"args": ["run", "--project", "/path/to/SharpBridge/SharpBridge"]
}
}
}
```
### 配置您的 MCP 客户端
将 SharpBridge 添加到您的 MCP 客户端的配置文件中:
<details>
<summary><b>Claude Code</b></summary>
在项目根目录中创建或编辑 `.mcp.json`:
```json
{
"mcpServers": {
"sharpbridge": {
"command": "sharpbridge"
}
}
}
```
</details>
<details>
<summary><b>Claude Desktop</b></summary>
编辑 `claude_desktop_config.json`:
- **Windows**:`%APPDATA%\Claude\claude_desktop_config.json`
- **macOS**:`~/Library/Application Support/Claude/claude_desktop_config.json`
```json
{
"mcpServers": {
"sharpbridge": {
"command": "sharpbridge"
}
}
}
```
</details>
<details>
<summary><b>Cursor</b></summary>
编辑 `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"sharpbridge": {
"command": "sharpbridge"
}
}
}
```
保存后重启 Cursor。
</details>
<details>
<summary><b>VS Code / GitHub Copilot</b></summary>
在工作区中创建 `.vscode/mcp.json`:
```json
{
"servers": {
"sharpbridge": {
"command": "sharpbridge"
}
}
}
```
</details>
### 验证安装
启动一个调试程序(任何 .NET 应用程序),然后询问您的 AI 代理:
> 附加到进程 XYZ 并在 Program.cs:10 处设置断点
如果代理可以通过 SharpBridge 列出工具(`debug_attach`、`breakpoint_set` 等),则表示您已设置完成。
### 基本工作流程
与 AI 代理的典型调试会话:
```
1. debug_launch(或 debug_attach)— 开始调试
2. breakpoint_set — 在感兴趣的行上设置断点
3. debug_continue — 运行直到断点被命中
4. variables_get — 检查程序状态
5. debug_step — 单步执行代码
6. debug_disconnect — 完成后清理
```
## 项目结构
```
SharpBridge/
├── SharpBridge.sln
├── SharpBridge/ # MCP 服务器
│ ├── Program.cs # 服务器引导 + 依赖注入
│ ├── Services/
│ │ ├── DebugSession.cs # 每个进程的 DAP 客户端 + 状态机
│ │ └── DebugSessionManager.cs # 多会话管理器 + 进程查找
│ └── Tools/
│ ├── SessionTools.cs # debug_launch、attach、disconnect、state、select、list
│ ├── BreakpointTools.cs # breakpoint_set、remove、list
│ ├── ExecutionTools.cs # debug_continue、step、pause
│ └── InspectionTools.cs # threads、stacktrace、variables(作用域 + 深度 + 展开)、evaluate、exception
├── SharpBridge.Tests/ # 集成测试(attach)
├── SharpBridge.LaunchTest/ # 集成测试(launch)
└── TestDebuggee/ # 用于测试的简单 .NET 应用程序
```
## 架构
### 多会话设计
```
MCP 请求(带有可选的 sessionId)
│
▼
DebugSessionManager(DI 单例)
├── ConcurrentDictionary<int, DebugSession> (pid → 会话)
├── CurrentSessionId(debug_select)
└── Resolve(sessionId) → 路由到正确的会话
│
▼
DebugSession(每个进程一个)
├── 自己的 DebugAdapterHost + 流(SharpDbg 内存中)
├── ProcessId、ProcessName、IsAttached
├── 状态机(NotStarted → Running/Stopped → Exited)
└── 断点、TCS 基事件协调
```
### DAP 通信
每个 `DebugSession` 都在后台线程上运行一个 `DebugProtocolHost`,该线程通过内存流(而非 stdin/stdout)从 SharpDbg 读取 DAP 消息。对于异步操作(continue/step/pause),在发送 DAP 命令之前,通过 `Interlocked.Exchange` 交换 `TaskCompletionSource<StoppedEvent>`;`StoppedEvent` 回调完成 TCS,解除等待调用者的阻塞。
### 会话生命周期
- **按 PID 附加**:检查现有会话(幂等),验证进程是否存在于操作系统中,创建会话
- **按名称附加**:解析单个实例,如果找到多个实例则报告模糊性
- **启动**:创建会话 → 启动程序 → 从 SharpDbg 日志中提取 PID → 在管理器中注册
- **断开/退出**:会话自动从管理器中移除;退出的/终止的调试程序自动清理
- **错误恢复**:DAP 读取器错误触发清理回调到管理器
## 已知问题
- **启动 PID 提取**:PID 通过正则表达式从 SharpDbg 日志输出中提取(`Process created suspended with PID: (\d+)`)。这依赖于 SharpDbg 的日志格式,而日志格式不是稳定的 API。如果 SharpDbg 更改其日志格式,启动将失败,显示“无法确定 PID。”长期解决方案:如果 SharpDbg 添加 PID 支持,则使用 DAP `ProcessEvent`,或自行管理进程创建。
- **异常筛选器支持不完整**:SharpDbg 广告 `"all"` 和 `"user-unhandled"` 异常断点筛选器,但无论筛选器选择如何,都硬编码 `breakOnAllExceptions = true`。两个筛选器当前表现相同(在每个异常上中断)。按异常类型配置(`ExceptionOptions`)不受 SharpDbg 支持。`exception_breakpoints` 正确适用于停止异常,但细粒度筛选需要 SharpDbg 的未来改进。
- **函数断点尚未由 SharpDbg 实现**:`HandleSetFunctionBreakpointsRequest` 返回一个空响应,并附有注释“尚未完全实现”。在 SharpDbg 添加此功能之前,无法在函数名称上中断。
- **Goto/GotoTargets 尚未由 SharpDbg 实现**:`HandleGotoRequest` 和 `HandleGotoTargetsRequest` 处理程序存在于 SharpDbg 中,但其功能尚不清楚。未通过 SharpBridge 暴露。
- **内存读取/写入, 反汇编**:SharpDbg 不实现 `ReadMemoryRequest`、`WriteMemoryRequest` 或 `DisassembleRequest`。这些需要 SharpDbg 的更改。
## 许可证
MIT