mcp代码图
 
MCP服务器,为编码代理提供代码库的心理图 IDE中类似渐进式披露的可折叠代码段,但用于 法学硕士。
第一次运行使用树形图解析每个源文件,并构建一个 实体图(类、函数、接口等)及其 关系(导入、扩展、实现)。它存储在本地 SQLite数据库(.codemap/graph.db)因此,后续会话从 索引立即生效,无需重新解析。
它揭示了三种工具。 map 构建大局——每个文件、类、, 并在选定的细节级别上运行,从快速大纲到完整 带有文档字符串和依赖边的签名。 query 放大 源代码、成员和关系的单个实体,没有 读取单独的文件。 reindex 编辑后保持新鲜, 通过git diff自动检测变化。
支持的语言:\
为什么
了解后端目录的典型探索(44个文件,~420个实体):
无代码图 -Glob/Read/Grep或Explore子代理:
| 步骤 | 工具调用 | 消耗的字符 |
|---|---|---|
| Glob查找文件 | 1 | ~500 |
| 读取models.py(572行) | 1 | ~15K |
| 读取world_service.py(628行) | 1 | ~18K |
| 读取ws.py(570行) | 1 | ~15K |
| 读取events.py(299行) | 1 | ~8K |
| 读取4-5个API路由文件 | 4-5 | ~ 60K |
| 支持跨文件导入/使用 | 3-5 | ~10K |
| 总计 | ~ 12-15个电话 | ~125K+ |
这很乐观——Explore子代理通常会进行15-25次工具调用 在多个转弯处,每个转弯都有自己的开销,但仍然会错过一些东西。
带代码图 -一两个电话:
| 级别 | 工具调用 | 消耗的字符 |
|---|---|---|
names (快速定位) | 1 | ~6K |
signatures (工作知识) | 1 | ~25K |
那是 代币数量减少5-6倍, 工具调用减少12-20倍,并完成 覆盖率-每个文件中的每个实体,而不仅仅是代理猜测要读取的实体。
设置
克劳德代码
# npx
claude mcp add codemap -- npx mcp-codemap
# docker
claude mcp add codemap -- docker run --rm -i -v .:/project:z ghcr.io/breca/mcp-codemap通过以下方式自动检测项目目录 MCP根。要明确设置它,请执行以下操作:
npx mcp-codemap serve -p /path/to/your/project第一次运行会自动为项目建立索引。索引存储在 .codemap/graph.db 在项目目录中。后续电话 map 或 query 通过以下方式自动检测更改的文件 git diff 并刷新索引 在返回结果之前,不需要手动重新索引。
其他客户
将MCP服务器配置添加到客户端的配置文件中:
| 客户端 | 配置文件 |
|---|---|
| 克劳德代码 | .mcp.json 在项目根中 |
| 光标 | .cursor/mcp.json 在项目根中 |
| 粉碎 | .crush.json 在项目根中 |
| 继续 | .continue/config.yaml |
| OpenCode | opencode.json 在项目根中 |
.mcp.json (克劳德代码,光标):
{
"mcpServers": {
"codemap": {
"command": "npx",
"args": ["mcp-codemap"]
}
}
}{
"mcpServers": {
"codemap": {
"command": "docker",
"args": ["run", "--rm", "-i", "-v", ".:/project:z", "ghcr.io/breca/mcp-codemap"]
}
}
}Crush / OpenCode / Continue configs
.crush.json:
{
"mcp": {
"codemap": {
"type": "stdio",
"command": "npx",
"args": ["mcp-codemap"]
}
}
}{
"mcp": {
"codemap": {
"type": "stdio",
"command": "docker",
"args": ["run", "--rm", "-i", "-v", ".:/project:z", "ghcr.io/breca/mcp-codemap"]
}
}
}opencode.json:
{
"mcp": {
"codemap": {
"type": "local",
"command": ["npx", "mcp-codemap"]
}
}
}{
"mcp": {
"codemap": {
"type": "local",
"command": ["docker", "run", "--rm", "-i", "-v", ".:/project:z", "ghcr.io/breca/mcp-codemap"]
}
}
}.scontinue/config.yaml:
mcpServers:
- name: codemap
command: npx
args:
- mcp-codemapmcpServers:
- name: codemap
command: docker
args:
- run
- --rm
- -i
- -v
- .:/project:z
- ghcr.io/breca/mcp-codemap工具
响应结构:
| 元素 | 含义 | ||
|---|---|---|---|
| 标题行 | `PROJECT: \ | \ | ` -项目总结 |
=== dir/ [N files, M entities] === | 具有聚合计数的目录部分 | ||
C/F/M/I/P/E | 种类前缀:类、函数、方法、接口、属性、枚举 | ||
:10-342 | 线路范围(起止) | ||
exp | 出口/公共符号 | ||
> imports: | 此文件导入的文件(解析路径) | ||
> used-by: | 从该文件导入的文件 |
map -结构概述
以紧凑的文本映射返回文件、实体、签名和关系。
map(scope?, detail?, max_depth?)detail 控制输出密度(默认值: "signatures"):
| 级别 | 内容 | 相对大小 |
|---|---|---|
"outline" | 文件+实体计数 | ~1% |
"names" | 顶级实体上的实体名称、种类、行范围+文档字符串 | ~8% |
"signatures" | 完整签名、文档字符串、导入/使用 | ~25% |
"full" | 签名+跨文件关系 | ~40% |
scope 将输出限制为目录或文件前缀(例如。, "src/api").
典型工作流程:
map(detail="names") # orient on the whole project
map(scope="src/api", detail="signatures") # drill into a module
map(detail="full") # inspect dependency graph例子: map(scope="src/tools", detail="names")
PROJECT: 53 files | 642 entities | csharp/go/java/javascript/kotlin/php/python/ruby/rust/typescript
INDEXED: just now
C=class F=function M=method I=interface P=property E=enum V=variable T=type N=namespace
=== src/tools/ [5 files, 13 entities] ===
src/tools/describe-entity.ts
I DescribeEntityParams :6-9
"Parameters for the describe-entity tool."
F describeEntity :12-27
"Generate or retrieve a natural-language description for a named entity."
F formatDescribeResult :29-37
src/tools/get-context.ts
I GetContextParams :5-9
"Parameters for the map tool: optional scope, depth limit, and detail level."
F getContext :12-18
"Build and return the compact text map of the codebase."
src/tools/query.ts
I QueryParams :6-8
"Parameters for the query tool: entity name or qualified name."
F queryEntity :11-104
"Deep-dive on a single entity: signature, source, callers, callees, and members."
src/tools/reindex.ts
I ReindexParams :6-9
"Parameters for the reindex tool: optional file paths and force flag."
F reindex :12-52
"Re-index changed files; auto-detects via git diff when no paths given."
src/tools/update-context.ts
I UpdateContextParams :6-10
"Parameters for the update-context tool."
F updateContext :13-55
"Incrementally update the index; falls back to full rescan if requested."细节级别
outline -包含实体计数的文件列表:
PROJECT: 53 files | 642 entities | csharp/go/java/javascript/kotlin/php/python/ruby/rust/typescript
INDEXED: just now
C=class F=function M=method I=interface P=property E=enum V=variable T=type N=namespace
=== src/parser/languages/ [11 files, 162 entities] ===
src/parser/languages/base.ts (10 entities)
src/parser/languages/python.ts (12 entities)
src/parser/languages/typescript.ts (10 entities)names -在顶级实体上添加带有种类前缀、行范围和文档字符串的实体名称:
src/parser/languages/base.ts
I ExtractedEntity :4-17
"A code entity (class, function, variable, etc.) extracted from a parse tree."
I FileParseResult :29-33
"Complete extraction output for a single source file."
I LanguageExtractor :45-50
"Contract for language-specific extractors that turn parse trees into entities."
F getDocComment :53-68
"Extract a JSDoc-style comment immediately preceding a node."
F getSignature :82-140
"Build a human-readable signature string from a class, function, or interface node."signatures -添加完整签名、文档字符串、导出标记和依赖关系信息:
src/parser/languages/python.ts
C class PythonExtractor implements LanguageExtractor :11-343 exp
"Extracts classes, functions, and imports from Python source files."
P language :12-12
P extensions :13-13
M extract(tree: Parser.Tree, sourceCode: string, filePath: string): FileParseResult :15-23
M walkNode(
node: Parser.SyntaxNode,
sourceCode: string,
filePath: string,
entities: ExtractedEntity[],
...
): void :25-97
M extractEntity(...): ExtractedEntity | null :99-171
> imports: src/parser/languages/base.ts
src/parser/languages/typescript.ts
C class TypeScriptExtractor implements LanguageExtractor :15-352 exp
"Extracts classes, functions, interfaces, and relationships from TypeScript/TSX files."
...
> imports: src/parser/languages/base.ts
> used-by: src/parser/languages/javascript.tsfull -添加跨文件关系部分:
=== RELATIONSHIPS ===
src/parser/languages/javascript.ts -> src/parser/languages/typescript.ts [extends: TypeScriptExtractor]
src/parser/languages/python.ts -> src/parser/languages/base.ts [implements: LanguageExtractor]
src/parser/languages/typescript.ts -> src/parser/languages/base.ts [implements: LanguageExtractor]query -深入探究一个实体
返回单个对象的签名、源代码、调用者、被调用者和成员 类、函数或方法。接受简单名称或限定名称。
query(entity)query(entity="UserService") # find by name
query(entity="UserService.createUser") # find by qualified name输出包括实际的源代码,因此代理不需要单独的 读取文件以查看实现。
输出示例
class PythonExtractor [exported]
src/parser/languages/python.ts:10-342
SIGNATURE: class PythonExtractor implements LanguageExtractor
MEMBERS:
property language :11-11
property extensions :12-12
method extract(tree, sourceCode, filePath): FileParseResult :14-22
method walkNode(...): void :24-96
method extractEntity(...): ExtractedEntity | null :98-170
method extractDocstring(...): string | null :172-187
DEPENDS ON:
imports ExtractedEntity (src/parser/languages/base.ts:3)
imports FileParseResult (src/parser/languages/base.ts:26)
implements LanguageExtractor (src/parser/languages/base.ts:40)
USED BY:
imports ScanResult (src/parser/pipeline.ts:15)
SOURCE:
10 | export class PythonExtractor implements LanguageExtractor {
11 | language = 'python';
12 | extensions = ['.py'];
...响应结构:
| 第节 | 内容 |
|---|---|
| 标题 | 实体类型、名称、导出状态、文件位置 |
SIGNATURE | 完整类型签名 |
MEMBERS | 带有签名和行范围的属性和方法 |
DEPENDS ON | 此实体导入、扩展或实现(具有源位置) |
USED BY | 依赖此实体的实体 |
SOURCE | 带有行号的完整源代码 |
reindex -编辑后刷新
注: map 和 query 返回前自动刷新索引 结果显示,只有强制进行完全重新扫描时才需要显式重新索引。
重新索引更改的文件。调用时通过git diff自动检测更改 没有争论。
reindex(paths?, force?)reindex() # auto-detect via git diff
reindex(paths=["src/foo.ts"]) # specific files
reindex(force=true) # full rescan, ignore cache输出示例
Git diff update (30 changed files)
Processed: 18
Skipped (unchanged): 11
Errors: 1
src/broken.js: TypeError: Cannot read properties of undefined配置
地点a config.json 在 .codemap/ 要覆盖默认值的目录:
{
"excludePatterns": [
"**/node_modules/**",
"**/dist/**",
"**/build/**",
"**/.git/**",
"**/vendor/**",
"**/__pycache__/**",
"**/target/**",
"**/*.min.js",
"**/*.bundle.js",
"**/*.generated.*",
"**/.codemap/**"
],
"maxFileSize": 1000000
}| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
excludePatterns | string[] | 请参阅上文 | 要跳过的文件/目录的全局模式 |
includePatterns | string[] | ["**/*.{ts,tsx,js,...,c,h,cpp,hpp,...}"] | 要包含的文件的全局模式(仅限非git repos) |
languages | string[] | [] (全部支持) | 将解析限制为特定语言 |
maxFileSize | number | 1000000 | 跳过大于此值(字节)的文件 |
updateGitignore | boolean | true | 自动添加 .codemap/ 到 .gitignore 在init上 |
在git repos中,文件发现使用 git ls-files 和尊重 .gitignore 自动- includePatterns 仅在非git repos中用作 退路。在这两种情况下,排除模式都充当辅助过滤器。
命令行界面
同一个二进制文件可以作为独立的CLI使用:
# npx
npx mcp-codemap map [-s scope] [--detail level] # print the map
npx mcp-codemap query # inspect an entity
npx mcp-codemap reindex [paths...] # re-index
npx mcp-codemap stats # show project stats
npx mcp-codemap web [--port 3333] # interactive web UI
npx mcp-codemap install-hooks # git hooks for auto re-indexing
npx mcp-codemap uninstall-hooks # remove installed git hooks
# docker (mount your project at /project)
docker run --rm -v .:/project:z ghcr.io/breca/mcp-codemap map -p /project
docker run --rm -v .:/project:z ghcr.io/breca/mcp-codemap stats -p /project
docker run --rm -v .:/project:z ghcr.io/breca/mcp-codemap query -p /project
docker run --rm -v .:/project:z -p 3333:3333 ghcr.io/breca/mcp-codemap web -p /projectWeb用户界面
codemap web 在浏览器中启动交互式图形浏览器-a 索引中每个实体和关系的可视化。
codemap web [--port 3333]特征:
- 图形画布 -呈现为颜色编码节点的实体(红色=类,
蓝色=函数,紫色=接口,绿色=枚举),按种类大小排列,带 它们之间的边缘。平移、缩放和拖动节点以进行探索。
- 布局模式 -通过右上角工具栏在五种布局之间切换:
力 (默认), 集群式 (按文件分组), 径向 (大部分连接在中心), 列 (按目录),以及 层级 (从上到下的依赖深度)。过渡是动态的。
- 侧边栏 -带有种类过滤器的可搜索文件树。键入路径前缀
在排除输入中隐藏不相关的目录(例如。, tests).
- 详图面板 -单击任何节点或文件打开右侧面板
显示其签名、文件位置、docstring、成员和 输入/输出边缘。单击链接的实体以浏览图形。
设计决策
仅包括路径解析关系(导入、扩展、实现) 在输出中。基于名称的“调用”边被排除在外,因为全局名称查找 产生太多误报(get, split等匹配无关 符号)。看 约束.md 了解详情。
