@jokeran/java-repo-skimmer
v0.3.4
Published
Java repository skimmer MCP server with symbol search and call graph tools.
Maintainers
Readme
Java Repo Skimmer MCP
面向多仓 Java 后端联查场景的本地 MCP 服务。它会先索引一个或多个 Java Git 仓库,然后让大模型低 token、低延迟查询定义、调用关系、影响面和代码片段。
当前版本:0.3.4
特性
stdio + MCP(JSON-RPC),无需部署服务器。- 核心分析服务使用 Java 实现,兼容 Java 8。
- 支持本地源码启动,也支持 npm wrapper 发布为
npx @jokeran/java-repo-skimmer@latest。 - 支持多仓索引、增量刷新、repo-local SQLite 缓存、缓存清理和索引健康解释。
heuristic模式适合日常快速定位,precise模式使用 JavaParser/SymbolSolver 做更准确的调用边。precise模式会自动尝试加载本机 Maven 缓存中的第三方 jar;失败会降级,不要求用户安装 Maven。- 支持显式开启/关闭 watcher;默认无后台监听,watcher 仅在当前 MCP 进程内生效。
- macOS 下 watcher 默认带 30 秒轮询兜底,避免
WatchService漏事件导致索引过期。 - 支持低内存模式,可通过环境变量收缩索引 worker 并在结果中回显当前模式。
- 内置 Spring 感知工具,可直接提取接口路由、参数分类、Bean 定义和依赖关系。
- 无变更热增量索引支持
fast_reuse快速复用旧索引,避免每次都重新扫描解析全仓。 java_search_text已接入 repo-local SQLite FTS5,适合搜索 SQL、常量、字段名和中文业务词。
安装与使用
方式一:本地源码方式
适合开发和本机试用。
cd "/path/to/java-repo-skimmer"
./scripts/install.shMCP 配置:
{
"mcpServers": {
"java-repo-skimmer": {
"command": "/path/to/java-repo-skimmer/scripts/run.sh"
}
}
}方式二:npm wrapper 方式
适合发布给用户。发布到 npm 后,用户不需要 clone 仓库,也不需要自己构建。
{
"mcpServers": {
"java-repo-skimmer": {
"command": "npx",
"args": [
"-y",
"@jokeran/java-repo-skimmer@latest"
]
}
}
}如果客户端要求 command 使用绝对路径,可以把 npx 改为本机 npx 的完整路径。
依赖说明
| 场景 | 需要 Java | 需要 Maven | 需要 Node |
|---|---:|---:|---:|
| 本地源码运行 scripts/run.sh | 是 | 否 | 否 |
| 本地源码构建 scripts/build.sh | 是,含 javac | 否,有则优先 | 否 |
| npm wrapper 运行 | 是 | 否 | 是,用于 npx 启动 wrapper |
| npm 发包前生成 fat jar | 是 | 是 | 是 |
说明:npm wrapper 只负责下载和启动,真正的索引和查询仍由 Java 进程执行,运行期核心性能不会因为外层是 Node 而下降。
验证
./scripts/build.sh
./scripts/test.sh
./scripts/smoke.sh如需放宽 smoke 等待时间,可设置:
SMOKE_TIMEOUT_MS=60000 ./scripts/smoke.sh- 有 Maven 时,
test.sh会执行 JUnit。 - 没有 Maven 时,
test.sh会回退到脚本构建和 MCP smoke。 smoke.sh会验证 MCP 握手、工具列表、索引、查询、代码片段、状态解释和缓存清理。
发布前建议在带 Maven 的环境额外执行:
mvn test
npm run prepare:npm
npm pack --dry-run --ignore-scripts
npm publish --dry-run索引工作流
日常增量刷新:
cd "/path/to/workspace-root"
/path/to/java-repo-skimmer/scripts/reindex-fast.sh关键链路或大改动后全量精确刷新:
cd "/path/to/workspace-root"
/path/to/java-repo-skimmer/scripts/reindex-precise.sh脚本会自动判断目标目录:
- 目标目录本身是包含 Java 文件的 Git 仓库时,索引当前仓库。
- 目标目录不是 Git 仓库时,只检查一级子目录,并索引其中包含 Java 文件的 Git 仓库。
MCP 工具 java_index_repos 也支持同样逻辑:传 rootPath 自动发现一级子 Git 仓库,或显式传 repoPaths。
precisionMode=precise 会按顺序尝试:解析 repo 内 pom.xml、从 ~/.m2/repository 匹配已有 jar、必要时用约 5 秒短超时尝试 ./mvnw 或 mvn dependency:build-classpath。Maven 不存在、VPN/私服不可用或命令超时不会阻断索引,只会在结果中通过 precise_dependency_resolution、dependency_warnings、version_conflicts 等字段提示。
如果机器内存紧张,可在启动 MCP 前设置:
JAVA_REPO_SKIMMER_LOW_MEMORY=true ./scripts/run.sh低内存模式会降低索引 worker,并在 java_index_repos 结果中返回 low_memory_mode=true。
如需自动刷新索引,可显式调用 java_watch_repos。watcher 默认只监听当前进程内已开启的 repo,修改 .java、pom.xml、build.gradle(.kts)、settings.gradle(.kts) 后会自动触发 heuristic 增量索引。macOS 默认每 30 秒做一次轻量轮询兜底。
索引完成后,默认缓存会写入每个 Git 仓库自己的本地目录:
<repo-root>/.agent/java-repo-skimmer/index.db建议在业务项目 .gitignore 中加入:
.agent/Batch 6 当前状态
preciseStrategy=auto 的 Batch 6 主线能力已经完成:
- 能区分 API 签名变化和 body-only 变化
- 能基于
file_dependencies反查受影响调用方 - 能对调用方执行 selective precise 重算
- pending 文件不会继续保留陈旧 precise call edges
- 删除文件时会保留变化证据,但不会把已删除文件误算进执行名单
MCP 工具
当前提供 19 个工具:
| 工具 | 用途 | 关键入参 |
|---|---|---|
| java_index_repos | 索引一个或多个 Java 仓库 | repoPaths?, rootPath?, force?, precisionMode? |
| java_find_symbol | 查 class/interface/enum/method/field | query, repoPaths?, types?, limit?, fuzzy?, includeRelatedSameName? |
| java_get_call_graph | 查 callers/callees/both 调用关系 | symbolName, direction?, repoPaths?, exactMatch?, precisionMode? |
| java_project_overview | 查看索引统计 | repoPaths? |
| java_trace_symbol | 聚合定义和调用点 | symbolName, repoPaths?, exactMatch?, precisionMode? |
| java_get_file_outline | 查看文件类、方法、字段轮廓 | repoPath, filePath |
| java_get_code_slice | 按符号或行号读取代码片段 | repoPath, filePath, symbolName?, startLine?, endLine? |
| java_search_text | 搜索业务词、SQL、常量、字段名,默认走 FTS5 | query, repoPaths?, caseSensitive? |
| java_list_endpoints | 提取 Spring MVC 路由表 | repoPaths?, limit? |
| java_trace_spring_bean | 提取 Spring Bean 定义和依赖 | beanName?, repoPaths?, limit? |
| java_method_impact_analysis | 分析方法副作用和风险标记 | symbolName, repoPaths?, exactMatch? |
| java_watch_repos | 显式开启 repo watcher 自动刷新 | repoPaths?, rootPath? |
| java_stop_watcher | 停止指定 repo 或全部 watcher | repoPaths? |
| java_watcher_status | 查看当前进程内 watcher 状态 | repoPaths? |
| java_index_health | 查看索引错误和健康度 | repoPaths?, maxErrorsPerRepo? |
| java_list_indexed_repos | 轻量列出已索引仓库 | repoPaths? |
| java_explain_index_status | 解释索引是否可用或 mixed | repoPaths? |
| java_clear_index | 清理指定仓库或全部缓存 | repoPaths? |
| java_compact_index | 删除不存在仓库缓存并回收 SQLite 空间 | repoPaths?, removeMissingRepos?, vacuum? |
java_index_repos 在 precisionMode=precise 时还支持:
preciseStrategy=full:全量 precise。preciseStrategy=auto:只对 API 签名变化文件及其反向依赖调用方执行 selective precise。
preciseStrategy=auto 的结果会额外返回这些字段:
api_changed_filesbody_changed_filesdependent_precise_filesselective_precise_target_filesselective_precise_pending_filesfile_dependency_count
推荐使用方法
日常建议按下面这套顺序使用:
- 初次进入工作区或切分支后,先执行
java_index_repos- 日常默认:
force=false,precisionMode=heuristic - 大改动后复核:
force=false,precisionMode=precise,preciseStrategy=auto
- 日常默认:
- 用
java_find_symbol、java_search_text、java_get_file_outline快速定位入口 - 用
java_get_code_slice读取关键方法,不要一开始全量读大文件 - 影响面判断优先用:
java_trace_symboljava_get_call_graphjava_method_impact_analysis
- Spring 项目补充用:
java_list_endpointsjava_trace_spring_bean
- 想确认当前索引是否适合做 Batch 6 级别判断时,先看:
java_project_overviewjava_explain_index_status
推荐索引参数:
- 日常快速定位:
precisionMode=heuristic - 关键链路复核:
precisionMode=precise,preciseStrategy=auto - 全仓强制精确重建:
precisionMode=precise,preciseStrategy=full,force=true
推荐提示词
实现需求:
请使用 java-repo-skimmer MCP 辅助开发,不要全量读取仓库。
rootPath=/path/to/workspace-root
先调用 java_index_repos,force=false,precisionMode=heuristic。
再用 java_find_symbol / java_search_text 定位入口。
用 java_get_code_slice 读取关键方法。
用 java_trace_symbol / java_get_call_graph 分析影响面。
如果是 Spring 项目,用 java_list_endpoints 查看接口路由,用 java_trace_spring_bean 查看 Bean 依赖。
改动高风险方法前,用 java_method_impact_analysis 查看字段读写、异常、事务和同步标记。
必要时用 precisionMode=precise 复核关键链路。查询逻辑:
请使用 java-repo-skimmer MCP 梳理 XXX 逻辑。
先索引 rootPath,再查入口、定义和调用链。
输出按“入口 -> 参数 -> 服务调用 -> DAO/SQL -> 返回值 -> 风险”组织,并给出 repo_path、file_path、line。缓存与调试
默认缓存文件:
<repo-root>/.agent/java-repo-skimmer/index.dbSQLite 开启 WAL 后,旁边可能出现 index.db-wal 和 index.db-shm,这是正常的运行时辅助文件。
如果 index.db 损坏,服务会自动备份为 index.corrupt.<timestamp>.db 并重建空库;之后重新索引即可。
如果 MCP 工具没有传 repoPaths/rootPath,服务会优先用 MCP 进程当前工作目录推导 Git 仓库,并读取该仓库 .agent/java-repo-skimmer/index.db。npm wrapper 会保留用户启动 MCP 时的工作目录,方便客户端在当前项目下直接查询。
从旧版本升级时,如果检测到旧全局缓存:
~/.java-repo-skimmer/index.db服务只会输出 warning,不会自动迁移。重新调用 java_index_repos 后会生成新的 repo-local 缓存。
AST YAML 调试落盘默认关闭。仅调试 parser 时开启:
JAVA_REPO_SKIMMER_AST_DUMP=true ./scripts/run.shwatcher 轮询兜底默认只在 macOS 开启。如需在其他平台开启或调整频率,可设置:
JAVA_REPO_SKIMMER_WATCH_POLL=true
JAVA_REPO_SKIMMER_WATCH_POLL_INTERVAL_MS=30000将 JAVA_REPO_SKIMMER_WATCH_POLL_INTERVAL_MS=0 可关闭轮询兜底,只保留 WatchService。
清理缓存可使用 MCP 工具 java_clear_index。如果只是想做维护,不想删除仍存在的仓库索引,优先使用:
{
"removeMissingRepos": true,
"vacuum": true
}对应工具为 java_compact_index。它会移除已经不存在的仓库缓存,并在 vacuum=true 时让 SQLite 回收磁盘空间。
如需把缓存放到自定义目录,可设置:
JAVA_REPO_SKIMMER_DATA_DIR=/path/to/cache-dir ./scripts/run.sh设置该环境变量后,会使用自定义目录下的单个 index.db,适合 CI、临时调试或集中缓存;普通用户默认不需要设置。
npm 发布准备
当前项目已包含 npm wrapper。发布前需要在有 Maven 的环境执行:
npm run prepare:npm
npm pack --dry-run
npm publish --access publicprepare:npm 会生成:
dist/java-repo-skimmer.jarnpm 包通过 bin/java-repo-skimmer.js 启动该 jar。
项目结构
bin/java-repo-skimmer.js npm wrapper 入口
pom.xml Maven fat jar 构建配置
scripts/build.sh 构建
scripts/run.sh 本地 MCP 启动
scripts/smoke.sh MCP 端到端 smoke
scripts/test.sh 本地验证入口
scripts/reindex-fast.sh 增量 heuristic 索引
scripts/reindex-precise.sh 全量 precise 索引
src/main/java/io/github/jokeran/javareposkimmer/Main.java
src/main/java/io/github/jokeran/javareposkimmer/mcp/McpStdioServer.java
src/main/java/io/github/jokeran/javareposkimmer/index/IndexService.java
src/main/java/io/github/jokeran/javareposkimmer/index/IndexPersistence.java
src/main/java/io/github/jokeran/javareposkimmer/index/IndexStoreRouter.java
src/main/java/io/github/jokeran/javareposkimmer/index/JavaSourceParser.java
src/main/java/io/github/jokeran/javareposkimmer/index/PreciseJavaAnalyzer.java已知限制
precisionMode=precise依赖 JavaParser 对源码可解析;语法不完整文件可能进入failed_files。- 对复杂泛型、反射调用、动态代理等场景,静态调用边仍有边界。
java_get_file_outline目前返回轻量概览,后续可升级成真正骨架摘要。java_search_text当前优先走 FTS5 phrase 查询,适合精确业务词、SQL、常量和中文短语;极宽泛的多 token 搜索后续可继续增强 token OR/AND 查询策略。
参考
- MCP Java SDK 文档:modelcontextprotocol/java-sdk
- 官方 Java SDK 站点:Server docs
- 可借鉴项目:OpenGrok、Zoekt
