关于 CodeMap
CodeMap 是基于 Roslyn 的 MCP 服务,面向 C#、VB.NET 和 F# 代码库。它为 AI Agent 建立持久化语义索引,让 Agent 按符号、调用图和架构事实查询代码,而不必逐个读取源文件。README 报告的平均 token 节省超过 90%。
主要功能
- 01基于 Roslyn 的符号索引
- 02调用图与引用查询
- 03类型继承层次分析
- 04架构事实提取(端点、配置键、DI 注册等)
- 05支持 DLL 边界的 NuGet 与 SDK 符号解析
- 06提供 28 个 MCP 工具
适用场景
- 01Agent 查找某个方法的所有调用位置
- 02在大型 .NET 解决方案中追踪功能的完整调用链
- 03查看 HTTP 端点、数据库表或配置键的使用情况
- 04比较两个提交之间的语义变化
MCP 相关
CodeMap 作为 MCP 服务运行,向 MCP 客户端暴露 28 个工具,包括符号搜索、引用查询、调用图和架构事实等。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
CodeMap——让你的 AI Agent 化身语义之龙
别再给 AI Agent 喂原始源文件了。给它一个语义索引。
CodeMap 是一款由 Roslyn 驱动的 MCP 服务,让 AI Agent 能够通过符号、调用图和架构事实来浏览 C#、VB.NET 和 F# 代码库,而不是粗暴地逐行阅读成千上万行源代码。一次工具调用,精准作答,不再淹没上下文。
**平均可节省 90% 以上的令牌:**相比直接读取文件。
通过 Claude Code 安装或手动安装
最快的安装方法是将下面的提示词粘贴到 Claude Code shell 中。Claude 会检查你的环境、安装工具并将其注册为 MCP 服务——无需手动操作。
运行
dotnet --version检查是否已安装 .NET 10 SDK。如果显示的版本低于 10.0,请进行安装:Windows 上运行winget install Microsoft.DotNet.SDK.10,macOS/Linux 上从 https://dotnet.microsoft.com/download/dotnet/10.0 下载。完成后运行dotnet --version验证。确认已安装 .NET 10 后,安装 CodeMap:如果尚未安装codemap-mcp,运行dotnet tool install --global codemap-mcp;否则运行dotnet tool update --global codemap-mcp获取最新版本。运行codemap-mcp --version,确认可以访问该二进制文件。最后,运行claude mcp add codemap-mcp codemap-mcp --scope user,将其注册为 Claude Code 的全局 MCP 服务,并确认它出现在claude mcp list的输出中。
或手动安装:
# Install .NET 10 SDK if needed (Windows)
winget install Microsoft.DotNet.SDK.10
dotnet tool install --global codemap-mcp
codemap-mcp --version
claude mcp add codemap-mcp codemap-mcp --scope user
需要 .NET 10(LTS)。如果你正在处理 C# 或 VB.NET 代码库,几乎肯定已经安装了它——运行 dotnet --version 检查。
升级到 v2.10.0
无需重新索引,也不改变索引格式。你可能会注意到:
- **
index_cleanup和index_remove_repo需要repo_path。**它们会删除数据,因此不再默认使用唯一注册的仓库。清理操作现在会保护每个 CodeMap 进程中所有工作区的基线;正在使用的基线绝不会被部分删除(会在skipped_in_use中报告)。 - Blazor 组件、MVC 视图和 Razor Pages 中的引用已恢复(自 v2.5.2 起缺失)。
对服务或模型调用
graph_callers/refs_find时,现在会包含.razor/.cshtml文件中的用法。 下次构建基线时(任何新提交),这些引用就会出现。 - **闲置内存会被释放。**索引完成后,闲置的服务会释放大部分构建时占用的内存 (nopCommerce:2.5 分钟后从 2.9 GB 降至 1.1 GB,13 分钟后降至 0.2 GB)。
config.json新增两个键:log_level和shared_cache_dir。shared_cache_dir现在可以正常工作(之前从未读取);budget_overrides已移除(之前不起作用)。未知键会在日志中产生一条警告。 相对路径形式的shared_cache_dir会导致启动停止,CODEMAP_CACHE_DIR使用相对路径时也一样。- 以字符串形式发送的布尔参数(
"include_code": "false")现在可以正常工作,不再返回INTERNAL_ERROR。
详情:CHANGELOG [2.10.0]。
升级到 v2.9.0:新的工具名称
现在工具名称使用下划线(symbols_search,而非带点的形式),因为 LLM API 不允许工具名称中包含点。Claude Code 用户不会看到任何变化:Claude Code 已经显示为 mcp__codemap__symbols_search。旧的带点名称至少在 v2.11.0 之前仍可使用,供仍发送这些名称的客户端和脚本调用。每次此类调用都会附上一条注明新工具名称的提示。如果项目的 CLAUDE.md 中包含 CodeMap 区块,请从 docs/CLAUDE-INSERT.MD 重新获取该区块。
从 v1.x 升级
v2.0.0 使用全新的二进制存储引擎(内存映射段,而非 SQLite)。旧的 .db 基线不会迁移——请为每个仓库运行一次 index_ensure_baseline 进行重建。旧的 ~/.codemap/baselines/ 文件夹不再使用,可以删除。SQLite 引擎已在 v2.1.0 中移除。
问题所在
不使用 CodeMap 在 C# 代码库中工作的 AI Agent 会这样做:
Agent: I need to find who calls OrderService.SubmitAsync.
→ Read OrderService.cs (3,600 tokens)
→ Read Controllers/... (3,600 tokens)
→ Grep across src/ (another 3,600 tokens)
→ Maybe find it. Maybe not.
使用 CodeMap 后:
refs_find { symbol_id: "M:MyApp.Services.OrderService.SubmitAsync", kind: "Call" }
→ 220 tokens. Exact file, line, and excerpt for every call site. Done.
对于 Agent 每个会话中要执行数十次的任务,Token 数量减少了 93.9%。在真实的生产代码库(10 万行以上)中,节省幅度为 95–99% 以上。
功能介绍
CodeMap 使用 Roslyn(为 Visual Studio 提供支持的同一编译器),从解决方案文件构建持久化语义索引。支持 .sln(所有 Visual Studio 版本)和 .slnx(VS 2022 17.12+ / .NET SDK 9+)解决方案格式;省略 solution_path 时会自动发现(优先选择 .slnx)。较短的提交 SHA 会自动扩展。索引包含:
- 每个符号(类、方法、属性、接口、记录)
- 每个调用关系和引用(谁在何处调用什么)
- 类型层次结构(继承链、接口实现)
- 从代码中提取的架构事实:HTTP 端点、配置键、数据库表、DI 注册、中间件管道、重试策略、异常抛出位置、结构化日志模板
所有这些都通过 28 个 MCP 工具开放,任何兼容 MCP 的 AI Agent 都可以调用。从 v1.3 开始,CodeMap 还可以遍历 DLL 边界——首次访问时延迟解析 NuGet 和 SDK 符号,并可选用 ICSharpCode.Decompiler 重建源代码和生成跨 DLL 调用图。
支持的语言: C#、VB.NET 和 F#。混合语言解决方案(包含 C#、VB.NET 和 F# 项目的 .sln / .slnx)会在一次处理中完成索引。所有 28 个 MCP 工具对任何语言的符号都能以相同方式工作。C# 和 VB.NET 使用 Roslyn 的 MSBuildWorkspace;F# 使用 FSharp.Compiler.Service(MSBuildWorkspace 不支持 .fsproj)。F# 架构事实提取器(端点、DI、配置)尚未实现——符号搜索、调用图、引用和类型层次结构均可正常使用。
Blazor / Razor(v2.5.0+): .razor 组件通过 Razor 源生成器建立索引。派生自 ComponentBase 的类会显示在 symbols_search 中。@page 路由会以 PAGE HTTP 方法显示在 surfaces_list_endpoints 中。[Inject] 和 [Parameter] 属性会生成专属的 RazorInject / RazorParameter 事实。从 v2.10.0 开始,组件、MVC 视图和 Razor Pages 中编写的代码会纳入引用图:对服务方法调用 graph_callers,会显示调用它的组件或视图。生成器自身的脚手架代码(标签助手相关逻辑)不会纳入索引。
多目标项目(v2.5.1+): <TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks> 之前会为每个 TFM 分别提取一次(造成 3 倍重复)。CodeMap 现在会选择排名最高的 TFM,仅执行一次提取,并在 ProjectDiagnostic.TargetFrameworks 中列出该组中的所有 TFM。对于大量使用多目标框架的 Blazor 库,符号数量会减少 60–80%。
支持接口感知的 graph_callers(v2.6.0+): 在通过 DI 分派的代码库中(大多数生产环境中的 .NET 项目),对具体方法调用 graph_callers 会悄悄漏报,因为实际调用点会通过已注册的接口解析。CodeMap 现在会在查询时检测接口实现,并显示 interface_implementation_hint,其中列出接口成员以及经由这些成员路由的额外调用方估计数量。传入 follow_interface: true,即可将这些调用方合并到结果中(按 from_symbol 去重)。无需更改基线格式,也无需重新索引。支持隐式和显式接口实现。
索引性能与正确性(v2.5.2): 通过跳过自动生成的树(*.g.cs、*.Designer.cs、包含 <auto-generated> 的文件、obj/ 下的路径)、短路类型位置标识符分类(typeof / 泛型参数 / 基类列表 / 特性),并行处理跨项目的 Pass-2 引用和事实提取,大幅缩短索引耗时。在包含 9 个仓库的 Blazor 语料库上验证:Blazorise 从 408 s 降至 95 s(−77 %),ant-design-blazor 从 47 s 降至 25 s(−47 %),OrchardCore(单目标哨兵项目)从 131 s 降至 96 s(−27 %);一个包含 78 个 csproj 的分布式数据库项目(ByTech.Bedrock)在 27 s 内完成索引,Pass-2 并行加速达到 11.2×。此外,还修复了 5 个查询正确性问题:symbols_search 按类型浏览现在会遵循 namespace / file_path / project_name 筛选条件;工作区模式的命名空间筛选不区分大小写(与已提交模式一致);refs_find 缓存键现在包含 resolution_state;工作区按类型浏览现在会包含覆盖新增的符号;codemap_guide 的决策表不再列出 surfaces_list_di_registrations(它从未注册为工具)。
转变
为 Agent 提供 CodeMap 后,会发生以下变化:
| 不使用 CodeMap | 使用 CodeMap |
|---|---|
grep -rn "OrderService" src/ | symbols_search { query: "OrderService" } |
| 阅读 5 个文件来理解一个方法 | symbols_get_context — 一次调用获取卡片、源码和所有被调方 |
| 手动跨文件追踪调用链 | graph_trace_feature — 一次调用获取完整的注释树 |
| 希望 grep 能找到正确的接口实现 | types_hierarchy — 即时查看基类、接口和派生类型 |
| 阅读整个文件来查找配置用法 | surfaces_list_config_keys — 索引所有 IConfiguration 访问 |
| 通过阅读已更改文件来比较两个提交 | index_diff — 语义差异,只显示架构变更,并能识别重命名 |
Agent 不再阅读你的代码库,而是开始理解它。
代表性功能:graph_trace_feature
最强大的工具,用一次调用取代 5–10 次手动调用:
graph_trace_feature {
"repo_path": "/path/to/repo",
"entry_point": "M:MyApp.Controllers.OrdersController.Create",
"depth": 3
}
返回带注释的调用树,并在每个节点标注架构事实:
OrdersController.Create [POST /api/orders]
→ OrderService.SubmitAsync
→ [Config: App:MaxRetries]
→ [DI: IOrderService → OrderService | Scoped]
→ Repository<Order>.SaveAsync
→ [DB: orders | DbSet<Order>]
→ [Retry: WaitAndRetryAsync(3) | Polly]
一次查询,完整呈现功能流。触及的每个配置键、写入的每张表、应用的每项重试策略,都会从索引中自动提取并呈现。
Token 节省基准测试
在一个真实的 .NET 解决方案上,通过 24 个典型 Agent 任务测得:
| 任务 | 原始 Token 数 | CodeMap | 节省比例 |
|---|---|---|---|
| 按名称查找类 | 3,609 | 248 | 93% |
| 获取方法源码和事实 | 3,609 | 336 | 91% |
| 查找所有调用方(refs_find) | 3,609 | 220 | 94% |
| 调用方链深度 = 2 | 3,609 | 287 | 92% |
| 类型层次结构 | 3,609 | 200 | 94% |
| 列出所有 HTTP 端点 | 3,609 | 360 | 90% |
| 列出所有数据库表 | 3,609 | 169 | 95% |
| 工作区陈旧状态检查 | 3,609 | 62 | 98% |
| 基线构建(缓存命中) | ~30s Roslyn | ~2ms 拉取 | ∞ |
| 平均值 | 90.4% |
原始 Token 数 = 阅读所有源文件。在生产代码库(10 万行以上)中,节省比例可达 95–99% 以上。
亲自运行:
dotnet test --filter "Category=Benchmark" -v normal
六大类别中的 28 个工具
发现
| 工具 | 功能 |
|---|---|
symbols_search | 按名称(前缀匹配、OR)、类型、命名空间或文件路径搜索 |
code_search_text | 在源文件中进行正则表达式/子字符串搜索——返回文件:行号:摘录 |
symbols_get_card | 完整的符号元数据、架构事实和源代码 |
symbols_get_context | 卡片、源代码以及所有被调用项的源代码——一次调用即可深入理解 |
symbols_get_definition_span | 仅原始源代码,不含额外开销 |
code_get_span | 按行范围读取任意源代码摘录 |
导航
| 工具 | 功能 |
|---|---|
refs_find | 查找符号的所有引用,并分类(调用、读取、写入、实现……) |
graph_callers | 限定深度的调用者图——是谁触发了它? |
graph_callees | 限定深度的被调用项图——它协调了什么? |
graph_trace_feature | 完整的带注释功能流程,每个节点都附有事实 |
types_hierarchy | 基类型、已实现的接口和所有派生类型 |
架构
| 工具 | 功能 |
|---|---|
codemap_summarize | 完整的代码库概览:端点、DI、配置、数据库、中间件、日志记录 |
codemap_export | 可移植的上下文转储(markdown/JSON,3 个详细级别),适用于任何大模型 |
codemap_guide | 快速入门指南:会话设置、决策表和 Agent 使用规则 |
index_diff | 提交之间的语义差异:新增/删除/重命名的符号、API 变更 |
surfaces_list_endpoints | 所有 HTTP 路由(控制器和 minimal API),附处理程序及文件:行号 |
surfaces_list_config_keys | 每个 IConfiguration 访问及其使用模式 |
surfaces_list_db_tables | EF Core 实体、[Table] 特性和原始 SQL 表引用 |
工作区
| 工具 | 功能 |
|---|---|
workspace_create | 为正在进行的编辑创建隔离的覆盖层 |
workspace_reset | 清除覆盖层,恢复至基线 |
workspace_list | 列出所有活动工作区及其过时状态、SemanticLevel 和事实数量 |
workspace_delete | 删除工作区 |
index_refresh_overlay | 增量重新索引已更改文件(约 63ms) |
索引管理
| 工具 | 功能 |
|---|---|
index_ensure_baseline | 构建语义索引(幂等、支持缓存、自动发现解决方案) |
index_list_baselines | 列出所有缓存的基线及其大小、存放时间和提交 |
index_cleanup | 移除过时的基线(默认试运行;必须提供 repo_path;绝不移除 HEAD 或任何工作区的基线) |
index_remove_repo | 移除某个仓库的所有基线和工作区(默认试运行;必须提供 repo_path;若另一进程正打开该仓库的工作区,则拒绝操作) |
仓库
| 工具 | 功能 |
|---|---|
repo_status | Git 状态,以及当前 HEAD 是否存在基线 |
工作区模式——查看自己的编辑内容
CodeMap 通过覆盖索引跟踪未提交的更改。每个 Agent 会话都有自己的隔离工作区:
1. index_ensure_baseline → index HEAD once
2. workspace_create → agent gets isolated overlay
3. Edit files on disk
4. index_refresh_overlay → re-indexes only changed files (~63ms)
5. Query with workspace_id → results include your in-progress code
三种一致性模式:
- 已提交 — 仅基线索引(默认,无需工作区)
- 工作区 — 基线与未提交的编辑内容合并
- 临时 — 工作区与虚拟文件内容(未保存的缓冲区内容)
多 Agent 主管支持
并行运行多个 Agent?目前支持以下功能:
- 每个工作区相互隔离:使用不同
workspace_id的 Agent 永远无法看到彼此的编辑 workspace_list会显示所有工作区:IsStale、SemanticLevel、事实数量- 当工作区的基础提交与 HEAD 不一致时,会触发过期检测
- 主管可以检查、清理或重新配置任意 Agent 的工作区
须知(根据多 Agent 基准测试测得,docs/CODEMAP-MULTI-AGENT-SCALING-FINDINGS.md):
- 每个 Agent 运行一个 CodeMap 进程。 每个 MCP 客户端或子 Agent 都会启动自己的服务,因此内存占用会随 Agent 数量增长:在小型和中型解决方案中,每个进程约占 0.3–0.5 GB;在大型解决方案中,每个进程约占 2.5–4 GB。每个进程首次都会自行构建相同的基线,并发构建会相互拖慢。计划通过共享主机解决此问题(ADR-048)。
- 工作区无法跨进程共享。 如果另一个 CodeMap 进程占用了该
workspace_id,调用会返回WORKSPACE_IN_USE(可重试):重试,或为每个 Agent 分配自己的 ID。 - 使用新 worktree 的 Agent 必须先还原。 新克隆或通过
git worktree add添加的 worktree 没有还原输出;请在运行index_ensure_baseline前执行dotnet restore,否则索引不完整(报告为semantic_level: partial,L-12)。 - 跨 Agent 清理是安全的(v2.10.0)。
index_cleanup绝不会删除任何 Agent 工作区正在使用的基线(无论在哪个进程中),也不会删除其他进程已打开的基线。只要有其他进程在该仓库中打开了工作区,index_remove_repo就会拒绝操作(WORKSPACE_IN_USE)。 - 空闲进程会释放内存(v2.10.0)。 索引完成两分钟后,服务会压缩堆;10 分钟内没有刷新覆盖层时,还会丢弃缓存的 Roslyn 解决方案(下次刷新时会重新打开)。这会降低每个进程的空闲内存开销;在共享主机上线之前,每个进程的内存开销仍会累加。
构建失败时的自我修复
文件无法编译时,CodeMap 不会丢弃引用,而是将其存储为带有语法提示的未解析边。编译恢复成功后(修复完成后),解析工作线程会自动将其升级为完全解析的语义边。
refs_find 会同时返回两者。如果需要确定性结果,可使用 resolution_state: "resolved" 进行筛选。
DLL 边界导航
CodeMap 会在 Agent 首次访问时惰性解析 DLL 符号——DLL
边界处的 NOT_FOUND 会触发自动提取,而不是让查询陷入死胡同。
两个层级,均为永久保存(缓存于基线数据库):
| 层级 | 触发条件 | 可获取内容 | 耗时 |
|---|---|---|---|
| 1 — 元数据存根 | 任何 NOT_FOUND 查询 | 方法签名、XML 文档、类型层次结构 | ~1–5ms(一次) |
| 2 — 反编译源代码 | symbols_get_card 中的 include_code: true | 通过 ICSharpCode.Decompiler 重构的完整 C# 源代码 | ~10–200ms(一次) |
完成第 2 层后,会提取跨 DLL 调用图边,因此 graph_callees 和
graph_trace_feature 可以无缝遍历 DLL 代码内部及其调用链。
symbols_get_card 响应中的 source 判别值:
"source_code"— 符号来自你自己的源代码"metadata_stub"— 仅第 1 层(无法反编译)"decompiled"— 第 2 层,源代码已重构并可用
遇到之前未见过的 DLL 类型时,graph_trace_feature 会应用
max_lazy_resolutions_per_query 预算(默认值为 20),以限制反编译延迟。
共享基线缓存
只需索引一次,即可在各处复用——跨设备、CI、Docker 容器:
export CODEMAP_CACHE_DIR=/shared/codemap-cache
或者,在 config.json 中(参见 Observability):{ "shared_cache_dir": "/shared/codemap-cache" }。
index_ensure_baseline会优先从缓存读取(约 2ms,而 Roslyn 构建约需 30s)- 每次构建新的基线后自动推送,但如果此机器上的基线已降级,则不会推送(例如未还原的检出,或加载失败的源生成器),因为其他机器会因此获得不完整的索引
- 自动修复:检测到损坏的缓存条目后会将其覆盖
- 优先级:
CODEMAP_CACHE_DIR(设置后始终优先;留空 = 禁用)>config.json中的shared_cache_dir> 禁用。两者均未设置时,所有缓存操作均为空操作 - 必须是绝对路径或以
~/开头;相对路径会导致服务在启动时停止(退出代码 2),因为它会相对于客户端的工作目录解析
v2 存储引擎 — 查询速度提升 10 倍
v2.0.0 用自定义二进制存储引擎取代 SQLite,采用内存映射分段文件。Roslyn 提取流水线未变,只有磁盘上的格式进行了更新。
查询速度提升(在真实仓库中对 15 种查询类型进行测量):
| 查询 | v1(SQLite) | v2(mmap) | 提升倍数 |
|---|---|---|---|
graph_trace_feature | 13.2ms | 0.5ms | 26x |
codemap_summarize | 18.9ms | 0.9ms | 21x |
surfaces_list_db_tables | 5.7ms | 0.2ms | 28x |
surfaces_list_config_keys | 3.6ms | 0.2ms | 18x |
types_hierarchy | 8.7ms | 1.0ms | 9x |
symbols_get_context | 28.7ms | 5.3ms | 5x |
symbols_get_card | 7.8ms | 2.7ms | 3x |
索引速度提升(Roslyn 编译占据主要耗时,但 I/O 更快):
| 仓库 | v1 | v2 | 提升倍数 |
|---|---|---|---|
| eShopOnWeb(278 个文件) | 16.2s | 5.8s | 2.8x |
| Bitwarden(4,466 个文件) | ~170s | ~110s | 1.5x |
| dotnet/roslyn(18,799 个文件) | 138.2s | 96.8s | 1.4x |
变更内容:
- 基线以连续打包的二进制分段存储(符号、边、文件、事实),并使用 mmap 读取——无需承担 SQL 解析开销
- 自定义搜索索引,支持分词全文搜索(CamelCase 拆分、签名/文档索引)
- 使用 WAL 支持工作区变更(隔离模型不变)
- 无原生 DLL 依赖(不再需要
e_sqlite3.dll)
已在 9 个以上的仓库中验证,包括 dotnet/roslyn(174K 个符号、768K 个引用)、dotnet/fsharp(通过 FCS 获得 157K 个符号)和 Bitwarden。未发现功能缺陷。完整数据请参见 docs/ENGINE-COMPARISON-RESULTS.MD。
已验证自托管
CodeMap 为自身包含 18 个项目的解决方案建立索引(5,576 个符号、20,960 个引用)。 所有 28 个工具均已针对真实世界的架构复杂性进行验证。自托管过程发现并修复了跨项目引用缺陷、CamelCase FTS 边缘情况、overlay StringId 解析问题,以及多行 SQL 提取缺漏。本 README 中的每个工具都经过了实现它的代码库验证。
安装
.NET 全局工具 — NuGet(推荐)
请参见上方的 通过 Claude Code 安装或手动安装 部分,了解一键粘贴的 Claude Code 提示词和手动操作步骤。
NuGet 包: nuget.org/packages/codemap-mcp
Docker
docker build -t codemap-mcp .
docker run -i \
-v /path/to/your/repo:/repo:ro \
-v /path/to/cache:/cache \
codemap-mcp
必须使用
-i——MCP 使用 stdio 传输。若不使用,容器会立即收到 EOF。
使用 .NET SDK 基础映像(约 800MB),因为 MSBuildWorkspace 在运行时需要 MSBuild 来执行 index_ensure_baseline。挂载缓存卷(-v /path/to/cache:/cache),以避免每次启动容器时都重新构建索引。
连接到 AI Agent
Claude Code(Claude Desktop / claude.ai)
添加到 claude_desktop_config.json:
{
"mcpServers": {
"codemap": {
"command": "codemap-mcp"
}
}
}
任何兼容 MCP 的客户端
CodeMap 通过 stdin/stdout(JSON-RPC 2.0)使用标准 MCP。任何 MCP 客户端均可使用。
CLAUDE.md 集成
将 docs/CLAUDE-INSERT.MD 中的指令块放入项目的 CLAUDE.md,即可为在该项目上工作的任何 Claude Agent 启用自动 CodeMap 使用。该指令块包含会话启动流程、工具替换决策表,以及让 Agent 保持语义模式的“grep 前刷新”规则。
提示:编写 XML 文档注释 — CodeMap 会使用它们
CodeMap 会为所有类、方法和接口编制 /// <summary> XML 文档注释索引。它们会出现在 symbols_get_card、symbols_get_context 和 symbols_search 的结果中,让 Agent 无需阅读实现代码也能了解意图和上下文。
启用 CodeMap 编写 C# 代码时,务必添加 XML 文档注释。
这不只是代码风格问题,还会直接提升所有下游查询的效果。使用 graph_trace_feature 的 Agent 会看到带注释的调用树,读起来就像规范。codemap_export 会在可移植上下文中包含文档注释,供其他大模型使用。
完整的 Agent 工作流指南请参阅 docs/CODEMAP-AGENT-GUIDE.MD。
架构
Your Git repo CodeMap Server
│ │
│ repo_path │
├─────────────────────────►│ GitService (repo identity, HEAD SHA)
│ │ │
│ solution.sln/.slnx │ ▼
├─────────────────────────►│ RoslynCompiler (MSBuildWorkspace for C#/VB, FCS for F#)
│ │ │
│ │ ▼
│ │ Extractors (Symbols + Refs + TypeRelations + Facts)
│ │ │
│ │ ▼
│ │ CustomSymbolStore (v2 binary segments, mmap'd)
│ │ │ ↕
│ │ │ SharedCache (file-based, optional)
│ │ ▼
│ your uncommitted edits │ ▼
├─────────────────────────►│ OverlayStore (WAL-backed incremental overlay)
│ │ │
│ │ ▼
│ │ MergedQueryEngine (baseline + overlay, transparent merge)
│ │ │
│ MCP tool call │ ▼
├─────────────────────────►│ McpServer (stdio JSON-RPC 2.0, 28 tools)
│ │ │
│ JSON response │ ▼
│◄─────────────────────────│ ResponseEnvelope (answer + evidence + timing + token savings)
层依赖(在构建时强制执行——违反规则会导致构建错误):
CodeMap.Core ← zero dependencies (domain types + interfaces)
CodeMap.Git ← Core (LibGit2Sharp)
CodeMap.Roslyn ← Core (Roslyn 5.x + MSBuildWorkspace)
CodeMap.Storage.Engine ← Core (v2 binary segments, sole engine since v2.1.0)
CodeMap.Query ← Core + Storage.Engine (query engine + cache + overlay merge)
CodeMap.Mcp ← Core + Query (MCP tool handlers)
CodeMap.Daemon ← ALL (DI composition root, the executable)
可观测性
每个响应都包含:
- 各阶段耗时 —
cache_lookup_ms、db_query_ms、ranking_ms(v2 中低于 1 毫秒) - Token 节省量 — 相比直接读取原始文件节省的 token 数量和避免的成本
- 语义级别 —
Full/Partial/SyntaxOnly(索引质量信号,见下文) - 覆盖层修订版本 — 为查询提供响应的工作区修订版本
- 工作区 ID — 提供响应的工作区上下文(提交模式下为 null)
当级别不是 Full 时,index_ensure_baseline 的 project_diagnostics 会按项目说明原因:
compiled: false:项目无法编译,因此按语法进行索引。missing_restore_output:尚未还原此检出内容(新克隆或 git worktree),导致包无法解析,有时框架也无法解析。运行dotnet restore,然后重建基线(L-12)。generator_load_failures:来自较新 .NET SDK 的源生成器无法加载,因此其生成的代码(例如 Razor 组件)缺失(L-11)。
之后针对该基线的每次查询都会报告相同的级别(适用于 v2.8.2 或更高版本构建的基线;较旧版本不会记录这些字段)。
结构化日志位于 ~/.codemap/logs/codemap-{date}.log(每日轮换,JSON 行格式)。
累计节省量位于 ~/.codemap/_savings.json(重启后仍会保留)。
配置位于 ~/.codemap/config.json,启动时读取一次。该文件包含两个键:
{ "log_level": "Information", "shared_cache_dir": "/shared/codemap-cache" }
log_level:Trace、Debug、Information(默认值)、Warning或Error。shared_cache_dir:共享基线缓存,仅当未设置CODEMAP_CACHE_DIR时使用。
任何其他键(拼写错误的键,或从未生效且已在 v2.10.0 中移除的 budget_overrides)都会被忽略,并在日志中记录一条警告。
数据目录(CODEMAP_HOME)
以上所有内容都位于同一个数据根目录下,默认为 ~/.codemap。设置 CODEMAP_HOME 可更改其位置(包括配置、日志、存储和 _savings.json),例如为每次测试运行、CI 作业或沙盒单独设置。它必须是绝对路径或以 ~/ 开头;相对路径会导致服务在启动时停止(退出代码 2)。
基线以二进制分段文件的形式存储在 <data root>/store/<repoId>/baselines/<commitSha>/ 中。
覆盖层位于 <data root>/store/<repoId>/overlays/<workspaceId>/ 中。使用 index_list_baselines 查看,并使用 index_cleanup 回收空间。
已知限制与覆盖缺口
CodeMap 并非在所有情况下都能像 grep 一样找到匹配项。最
常见的原因记录在 docs/KNOWN-LIMITATIONS.md 中。
需要注意的主要事项:
- 多目标条件符号。 仅在
#if NET8_0下定义的类型不可见——提取只针对最高 TFM 运行(L-01)。 - 旧版 MVC
MapControllerRoute——按约定路由的操作不会出现在surfaces_list_endpoints中。只会提取特性路由、 minimal API 和 Blazor@page(L-02)。 - F# 事实提取器尚未接入——F# 目前只能获取符号/引用/层次结构;尚不会从
.fsproj中提取端点/DI/配置/数据库表(L-05)。 - 尚未还原的检出内容——全新克隆或 git 工作树没有
obj/project.assets.json,而 CodeMap 不会执行还原,因此无法解析包引用(有时连框架本身也无法解析)。系统会报告此情况 (missing_restore_output、semantic_level: partial);请在运行index_ensure_baseline前执行dotnet restore(L-12)。 - .NET SDK 版本高于 CodeMap 使用的 Roslyn 版本——该 SDK 的源生成器
(例如 Razor)可能无法加载,导致缺少其输出。系统会报告为
generator_load_failures;请更新 CodeMap(L-11)。 - 全新克隆且未执行构建——在执行一次
dotnet build前,Razor 源生成器输出可能不可见(L-08)。 - 仅在 Razor 标记中使用的内容——
@onclick="Save"和类似<Greeting />的组件标签尚不会生成引用;Razor 引用指向生成的obj/…_razor.g.cs行,而不是.razor文件(L-15)。
当 symbols_search 没有返回编辑器中可见的代码时,先查看 KNOWN-LIMITATIONS,再考虑使用 grep。
文档
| 文档 | 内容 |
|---|---|
docs/CLAUDE-INSERT.MD | 可复制粘贴到 CLAUDE.md 的代码块——配置 Agent 使用 CodeMap |
docs/CODEMAP-AGENT-GUIDE.MD | 完整的 Agent 操作指南:启动、刷新、查询模式和常见错误 |
docs/KNOWN-LIMITATIONS.md | 覆盖缺口和有意不实现的功能——grep 能找到而 CodeMap 找不到的内容 |
docs/DEVELOPER-GUIDE.MD | 如何添加工具、提取器和存储方法 |
docs/ARCHITECTURE-WALKTHROUGH.MD | 请求跟踪、数据模型和决策日志 |
docs/API-SCHEMA.MD | 每个类型定义和 MCP 工具契约 |
docs/SYSTEM-ARCHITECTURE.MD | 组件设计、数据库架构和查询模型 |
构建与测试
# Build (zero warnings enforced)
dotnet build -warnaserror
# Test per project: `dotnet test` at the solution root starts every test runner at once and can run out of memory
dotnet run --project tests/CodeMap.Core.Tests # likewise Roslyn, Query, Mcp, Storage.Engine, Daemon, Git
# Integration tests: restore the test fixtures once per checkout first (MSBuildWorkspace doesn't restore)
dotnet restore testdata/SampleSolution/SampleSolution.sln # likewise SampleVbSolution, SampleBlazorSolution, SampleFSharpSolution
dotnet run --project tests/CodeMap.Integration.Tests # includes Category=Concurrency (spawns real servers, ~1 min)
# Linux test rig (Docker; see docs/DEVELOPER-GUIDE.MD)
.\tests\docker\run-linux-tests.ps1 integration
# Token savings benchmark
dotnet test --filter "Category=Benchmark" -v normal
# Performance microbenchmarks (BenchmarkDotNet)
cd tests/CodeMap.Benchmarks && dotnet run -c Release
性能参考
在代码库上运行 CodeMap 时的预期表现。所有 v2 引擎数据(自 v2.0.0 起为默认引擎)。
不同代码库规模的索引时间
| 代码库 | 文件数 | 符号数 | 引用数 | 索引时间 |
|---|---|---|---|---|
| CodeMap(可自托管) | 585 | 6,800 | 29,200 | ~24s |
| eShopOnWeb | 278 | — | — | ~6s |
| dotnet/fsharp | 994 | 157,000 | 58,000 | ~131s |
| Bitwarden | 4,466 | — | — | ~110s |
| dotnet/roslyn | 18,799 | 174,000 | 768,000 | ~97s |
在同一提交上再次运行会立即返回(already_existed: true)。增量叠加刷新(编辑文件后)耗时 ~63ms。
查询响应时间(v2 引擎)
| 查询 | 冷启动(首次命中,无 L1 缓存) | 热启动(L1 缓存) |
|---|---|---|
symbols_search | 1–10ms | <1ms |
symbols_get_card | 2–10ms | <1ms |
symbols_get_context | 5–30ms | 1–5ms |
refs_find | 5–20ms | <1ms |
graph_callers / callees | 10–50ms | 1–5ms |
graph_trace_feature | 10–100ms | 1–10ms |
types_hierarchy | 1–5ms | <1ms |
codemap_summarize | 50–200ms | 5–20ms |
surfaces.list_* | 1–10ms | <1ms |
index_diff | 100–500ms | — |
冷启动耗时会随代码仓库大小增长(符号越多,BFS/连接操作越多)。热启动耗时在各种代码仓库大小下几乎不变——L1 缓存最多容纳 10,000 个条目,并采用 LRU 淘汰策略。
内存占用(v2 引擎)
| 代码仓库大小 | 磁盘基准占用 | 常驻内存(mmap) |
|---|---|---|
| 小型(<1K 个符号) | ~1–5 MB | ~5–20 MB |
| 中型(10K 个符号) | ~20–50 MB | ~30–80 MB |
| 大型(100K+ 个符号) | ~200–500 MB | ~300–600 MB |
mmap 页面由操作系统按需加载——常驻内存与已执行的查询量成正比,而不是与索引总大小成正比。
空闲时的进程内存(v2.10.0+)
服务进程也会持有 Roslyn 用于构建索引的内存。从 v2.10.0 起,空闲时会释放这部分内存:索引完成两分钟后执行一次压缩 GC;缓存的解决方案若 10 分钟内未刷新,也会被丢弃。以下为单个空闲服务测得的专用内存
(PHASE-21-12,docs/benchmarks/phase-21-12/):
| 代码仓库 | v2.9.0,空闲 | v2.10.0,空闲 2.5 分钟 | v2.10.0,空闲 13 分钟 |
|---|---|---|---|
| eShopOnWeb | 363 MB | 218 MB | — |
| Bitwarden server | 723 MB | 342 MB | 352 MB |
| nopCommerce | 2,922 MB | 1,116 MB | 204 MB |
每个服务都会将 MEMORY_SNAPSHOT 行(工作集、专用字节数、GC 堆)记录到 ~/.codemap/logs。
28 个 MCP 工具。节省 90% 以上的令牌。Roslyn 级别的语义分析。C#、VB.NET、F#、Blazor/Razor。DLL 边界导航。自动发现 .sln + .slnx。v2.10.0 — 面向多个 Agent 的安全破坏性工具、释放空闲内存、Razor 组件和视图引用、准确的 config.json。已在 dotnet/roslyn(174K 个符号)、dotnet/fsharp(157K 个符号)以及包含 Blazorise、MudBlazor、ant-design-blazor 和 OrchardCore 的 9 个代码仓库 Blazor 集合上验证。你的 Agent 值得拥有比 grep 更好的工具。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。