anatolykoptev/vaelor

GitHub: anatolykoptev/vaelor

一个自托管的 MCP 服务器,为 AI 编程 agent 提供持久的代码库调用图记忆、语义搜索和审查学习记录,使代码变更的风险评估、事故调试和 PR 审查具备结构化上下文。

Stars: 5 | Forks: 1

# Vaelor **为你的编程 agent 提供它无法通过 grep 获取的代码库记忆。**

Vaelor impact on ParseFile: before an agent edits a hot function it sees the real blast radius — HIGH risk, 133 symbols across five packages, the transitive callers, the string references the call graph misses, and the four tests that guard it. Known before the edit, not after CI.

Vaelor 是 [Krolik](https://krolik.tools) 背后的开源引擎:一个自托管的 [MCP](https://modelcontextprotocol.io/) 服务器,它可以解析、图谱化并监控代码库,这样 AI agent 就不必在每次会话时重新探索它。跨 16 种语言的 Tree-sitter AST 解析为调用图提供数据,结合具备类型感知的 Go 解析(`go/types`)、持久化的 Apache AGE 知识图谱以及混合语义搜索。`review_pr` 会记住上次审查某个 symbol 时出现了什么问题。`debug_investigate` 可以将 Prometheus 告警和 Jaeger trace 关联回导致问题的函数。 [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) [![Go](https://img.shields.io/badge/go-1.24%2B-00ADD8.svg)](go.mod) 只需三个命令即可[快速开始](#quick-start)。如果它对你有帮助,点个 star 可以帮助下一个人发现它。 ## 为什么不直接用 grep 或代码索引? 每个代码搜索工具都能找到函数。但很少有工具能告诉 agent 当它改变时还有什么会坏掉,更少有工具能记住你上一次的审查或上一次的生产事故。 | | 组织级代码搜索 | 会话级 agent 工具 | 托管的 PR 审查机器人 | Vaelor | |---|---|---|---|---| | 用途 | 跨索引组织进行全文和符号搜索,作为上下文提供给 agent | 在单个 agent 会话内进行导航和编辑 | 作为托管服务在 PR 上自动发布审查评论 | 将搜索、调用图、爆炸半径和实时事故置于你自己运行的一个 MCP endpoint 之后 | Vaelor 的 Apache AGE 图谱承载了根据你的实际调用图计算出的 PageRank、社区和意外性分数,这些分数直接反馈给 `understand`、`prepare_change` 和 `review_pr`。`review_pr` 还会根据真实的 GitHub 审查结果,为每个 symbol 持久化一个判定结论,并且当任何人下次触碰该 symbol 时,`understand` 会自动将其呈现出来。这样一来,“这在审查中出过问题”的事实就跟随代码本身流转,而不是只存在于某个人的记忆中。`debug_investigate` 走得更远:它将实时的 Prometheus 告警和 Jaeger trace 与同一个调用图融合,生成一个排好序的 `file:function` 假设,因此事故可以被直接定位到代码,而不仅仅是一个仪表板上的告警。agent 对于哪些变更是高风险的感知来源于你真实代码库的结构,并且在每次图更新时都会重新计算。 ## 快速开始 ### Docker(推荐) ``` docker build -t vaelor . docker run -p 8897:8897 \ -e LLM_API_BASE=http://host.docker.internal:8317/v1 \ -e LLM_API_KEY=your-key \ vaelor ``` ### 从源码构建 需要 Go 1.24+ 和一个 C 编译器(用于 tree-sitter 语法的 CGO)。 ``` make build # → bin/vaelor ./bin/vaelor ``` ### 注册为 MCP 服务器 ``` claude mcp add -s user -t http vaelor http://127.0.0.1:8897/mcp ``` ### 试试看 无需本地克隆:`understand` 和 `call_trace` 直接接收 GitHub 仓库,并在首次调用时获取。首次调用会为仓库建立索引,因此请给它几秒钟时间;之后它就会被缓存。建议从一个小的仓库开始: ``` { "tool": "call_trace", "arguments": { "repo": "gorilla/mux", "symbol": "ServeHTTP", "direction": "callees", "depth": 2 } } ``` 遍历 `Router.ServeHTTP` 的路由路径并带有环检测 —— 不需要 Docker volume 挂载,也不需要 `DATABASE_URL`。 还没有 `LLM_API_KEY`?大多数工具仍然可以运行:它们只会跳过叙述和排名层。要确切了解哪些功能会降级以及哪些不会,请查看 [LLM 依赖](#llm-dependency)。 ## 它能做什么 ### 理解代码库 `explore`:针对远程仓库的快速、无需克隆的概览。`understand`:针对 symbol 的深入剖析,涵盖调用者、被调用者、复杂度、死代码分数,以及该 symbol 上之前的任何审查结论。`code_research`:结合 BM25F、embeddings 和图扩展,专为拥有 1 万+ 文件的 monorepo 设计。 ### 了解变更会破坏什么 `impact_analysis`:可配置的爆炸半径深度(默认 5),根据代码变动率重新排序热点。`prepare_change`:在一次调用中完成影响分析和死代码检查。`call_trace`:带有环检测和 LLM 叙述的双向调用链。 ### 按含义搜索,而非关键字 `semantic_search`:pgvector 结合混合 RRF 和 1 跳图扩展。`symbol_search`,`code_search`,`github_code_search`(无需克隆)。 ### 审查并记住 `review_pr` / `review_delta`:git 引用之间的差异爆炸半径分析,会发布到 GitHub 并在批准或拒绝时持久化每个 symbol 的学习记录。`code_compare`:两个仓库之间的结构差异对比,涵盖架构、API 设计和质量。`rewrite`:跨 16 种语言的结构化 AST 搜索替换,优先进行 dry-run。 ### 调试实际运行的代码,而不仅仅是 diff 中的内容 `debug_investigate`:7 阶段事故根因分析,从指标飙升和失败的 trace 到 symbol 解析、调用图遍历、LLM 融合以及运行时二进制漂移,最终排名定位到 `file:function`。`fleet_versions`:对比源码中固定的 image tag 与实际部署的内容。`dataflow`:污点分析、死存储、SQL/命令注入 sink。`dead_code` 和 `code_health`:一个 A-F 的评分,涵盖复杂度、测试覆盖率、依赖新鲜度、OSV 漏洞。 ### 其他值得关注的功能 `find_duplicates`:通过语义相似度在一个仓库中查找近乎重复的 symbol(需要 `EMBED_URL` + `DATABASE_URL`)。`suggest_reviewers`:根据创作记录、同变耦合和近期活跃度,为 PR 的文件路径对候选审查者进行排名。 这只是主要的工具集,而不是全部。下表记录了稳定的工具;在运行中的服务器上调用 `tools/list` 可以获取完整的当前列表。 ## 工具参考 这里是稳定且有文档记录的工具集。服务器还开放了另外几个工具;在运行中的实例上使用 `tools/list` 可以获取最权威的当前列表。 | Tool | Description | |------|-------------| | `repo_analyze` | 分析代码库。包含深度模式 (AST + LLM)、快速模式 (GitHub Code Search) 或 issue/PR 搜索 | | `repo_search` | 通过并行网络搜索 + GitHub/GitLab API 发现跨平台的代码库,由 LLM 排序 | | `github_code_search` | 通过 Code Search API 在 GitHub 上搜索代码。返回文件路径和匹配的片段 | | `file_parse` | 使用 tree-sitter 解析单个文件。返回 symbol 表或原始 AST | | `code_compare` | 从结构上对比两个代码库:架构、API 设计、代码质量 | | `dep_graph` | 构建依赖图。输出格式为 Mermaid、Graphviz DOT 或 JSON | | `symbol_search` | 按名称模式跨代码库搜索 symbol(函数、类型、常量) | | `code_search` | 类 Grep 搜索,支持正则表达式和路径通配符过滤,包含上下文行 | | `call_trace` | 追踪调用链:被调用者(正向)或调用者(反向),支持深度控制 | | `code_graph` | 通过自然语言查询 Apache AGE 中的持久化代码知识图谱 | | `debug_investigate` | 7 阶段生产事故根因分析:Prom 飙升 + Jaeger 失败 trace + symbol 解析 + 调用图遍历 + LLM 融合 + 运行时二进制漂移,最终排名定位到 `file:function` | | `semantic_search` | 混合 RRF:BM25F + pgvector + 1 跳 AGE 图扩展。按概念而非关键字查找 | | `understand` | 具备类型感知的 symbol 深入剖析。聚合 call_trace + symbol_search + 复杂度 + tested_by + dead_code_score + 之前的学习记录 | | `impact_analysis` | 可配置的爆炸半径深度(默认 5)。直接调用者、传递性调用者、根据变动率重排热点 | | `prepare_change` | 变更前风险评估:结合影响分析和死代码检查 | | `dead_code` | 带有置信度分数的未使用 symbol 检测,而不是简单的平铺列表 | | `dataflow` | IL/CFG 污点跟踪、死存储、SQL/命令注入 sink | | `rewrite` | 跨 16 种语言的结构化 AST 搜索替换,支持 `$WILDCARDS`,提供 dry-run 和执行模式 | | `review_pr` | git 引用之间的差异爆炸半径分析;持久化每个 symbol 的学习记录 | | `review_delta` | 两个 git 引用之间的差异爆炸半径分析 | | `code_research` | 结合 BM25F + embeddings + DAG 扩展,专为 1 万+ 文件的 monorepo 设计 | | `design_search` | 通过 UI 描述查找 `DESIGN.md` 系统 (multilingual-e5-large, 1024-dim) | | `resolve_frame` | 通过 source map 还原被压缩的 JS 堆栈帧 | | `site_analyze` | 技术栈和 SEO 审计,BFS 爬虫 | | `site_crawl` | BFS 网络爬虫 | | `code_health` | 代码库评分 A-F:复杂度、测试覆盖率、依赖新鲜度、OSV 漏洞 | | `explore` | 快速代码库概览,不使用 LLM,针对远程仓库无需克隆 | | `fleet_versions` | 将源码中固定的容器 image 引用与已部署的运行时容器进行对比。可捕获“配置一致、源码看似正确,但行为异常”这类 Bug | | `find_duplicates` | 通过语义相似度在一个代码库中查找近乎重复的 symbol。需要 `EMBED_URL` + `DATABASE_URL` | | `suggest_reviewers` | 根据创作记录、同变耦合和近期活跃度,为 PR 的文件路径对候选审查者进行排名 | | `remember_graph_insights` | 持久化一条学习记录,使其在未来的 `understand` 调用中呈现 | | `wp_plugin_search` | 搜索 WordPress.org 插件目录 | ## 学习循环 `review_pr`(设置 `dry_run=false` 时)会在完成的 GitHub 审查中,为每个被修改的 symbol 写入一条学习记录:`APPROVE` 映射为 `good`,`REQUEST_CHANGES` 映射为 `bad`,其他所有情况映射为 `neutral`。dry-run 路径会在同一记录中写入 `risk_level`。下次任何人对该 symbol 调用 `understand` 时,`Store.Nearest` 会查找最接近的历史学习记录,并将它们作为 `prior_learnings` 附加在结果中,无需额外调用。该循环由 `LEARNINGS_DATABASE_URL` 控制(缺省回退至 `DATABASE_URL`);如果两者都未设置,它将静默失效,而不会抛出错误。 ## 图信号生态系统 两种图表示形式通过 `internal/graphx` 协同工作,且互相不知道对方的包结构,因此当还没有图快照时,下面的每个消费者都会降级输出字节完全相同的结果。 | 信号 (AGE 计算) | 使用者 | |---|---| | PageRank, community | `understand` (`graph_analytics`), `prepare_change` (`communities_crossed`, `high_pagerank_callers`) | | Surprise score | `review_pr` (当值 ≥0.5 时触发 `high_surprise` 标志) | | Handlers / fetches (跨语言路由) | `call_trace` (跨服务边界获取 +1 深度的节点) | | Tested-by | `impact_analysis` (`tests_covering`) | ## 运行时版本感知 当生产环境的 Bug 存在于已部署的二进制层面而不是源码中时(固定 tag 漂移、同主机差异、静默自动更新),Vaelor 可以探测正在运行的容器,并将它们与索引代码库中固定的版本进行对比。 - `fleet_versions`:专用工具。传入 `host`(默认为本地 Docker socket)和可选的 `service` 过滤器。返回每个目标的 diff 结果:`Match` / `TagDrift` / `DigestDrift` / `OnlySource` / `OnlyRuntime` / `Unresolved`。 - `debug_investigate` 阶段 7:当调查以设置了 `host` 开始时自动运行。漂移信息进入 LLM prompt 的优先级受 top 20 非 `Match` 差异限制,排序规则为 `TagDrift` > `DigestDrift` > `Unresolved` > `OnlyRuntime` > `OnlySource`。 ### SSH 探针 连接远程主机直接使用系统的 `ssh` 二进制程序;Vaelor 没有维护自己的 SSH 栈,因此 `~/.ssh/config`(ProxyJump、agent、identities、port、known_hosts)是唯一的配置真理来源。该驱动默认关闭:使用 `GOCODE_FLEET_SSH_ENABLE=true` 开启。在远程上执行的命令仅限于内部白名单,确切地说是 `docker ps --no-trunc --format={{json .}}`,其过滤值会在任何 exec 调用之前进行正则验证。 | Env | Default | Purpose | |---|---|---| | `GOCODE_FLEET_DEFAULT_HOST` | `""` | `debug_investigate` 阶段 7 的备用主机。留空 = 跳过 | | `GOCODE_FLEET_DOCKER_SOCKET` | `/var/run/docker.sock` | 本地 Docker 引擎 socket 路径 | | `GOCODE_FLEET_SSH_ENABLE` | `false` | 必须设为 `true` 才能使用 `ssh://` 目标 | | `GOCODE_FLEET_SSH_BINARY` | `ssh` | 系统 ssh 二进制程序,默认在 PATH 中解析 | | `GOCODE_FLEET_TIMEOUT` | `10s` | 单次探测超时时间 | ## 配置 | Variable | Default | Description | |----------|---------|-------------| | `MCP_PORT` | `8897` | HTTP 服务器端口 | | `LLM_API_BASE` | `http://127.0.0.1:8317/v1` | 兼容 OpenAI 的 LLM endpoint | | `LLM_API_KEY` | *(可选)* | 请参阅下方的 [LLM 依赖](#llm-dependency) | | `LLM_MODEL` | `cerebras-gpt-oss-120b` | 模型名称(全新部署的缺省值;请根据部署覆盖修改) | | `GITHUB_TOKEN` | *(可选)* | 提升 API 速率限制,访问私有仓库 | | `WORKSPACE_DIR` | `/tmp/go-code-workspace` | 用于克隆仓库的临时目录 | | `MAX_FILE_KB` | `512` | 解析的最大文件大小 (KB) | | `MAX_REPO_MB` | `200` | 接受的最大仓库大小 (MB) | | `REDIS_URL` | *(可选)* | 用于 L2 解析/LLM 缓存的 Redis URL | | `DATABASE_URL` | *(可选)* | 用于 Apache AGE 代码图的 PostgreSQL DSN(`code_graph`、学习循环以及上方的图信号所必需) | | `EMBED_URL` | *(可选)* | Embedding 服务器 endpoint(`semantic_search` 必需) | | `GITHUB_WEBHOOK_SECRET` | *(可选)* | 设置以启用 `/webhook/github` PR 审查接收器 | 完整的环境参考(SearXNG, GitLab, fallback-model 链,fleet SSH,索引调优):[CLAUDE.md](CLAUDE.md)。 ### LLM 依赖 `LLM_API_KEY` 是可选的。服务器可以在没有它的情况下启动,并且大多数工具照常运行: | 类别 | 工具 | 没有 `LLM_API_KEY` 时的行为 | |----------|-------|-------------------------------| | **硬依赖** | `code_graph` (自然语言查询), `repo_search` | 返回 MCP 错误:*"requires LLM_API_KEY to be set"* | | **软依赖** | `repo_analyze` (quick/raw 模式), issue/PR 搜索 | 返回确定性结果加上一个 `(LLM unavailable)` 标记 | | **增强型** | `call_trace`, `dead_code`, `impact_analysis` | 输出完整的核心内容;叙述/增强字段为空 | | **调试型** | `debug_investigate` | 运行确定性阶段(trace 分析、指标飙升、告警违规);LLM 假设排名将被跳过,并设置 `LLMSkippedReason` | 设置 `LLM_API_BASE` + `LLM_API_KEY` + `LLM_MODEL` 即可以全容量运行所有工具。任何兼容 OpenAI 的 endpoint 均可使用:OpenAI、通过代理的 Anthropic、本地 Ollama 实例。 ## 架构 ``` cmd/vaelor/ : MCP server, tool handlers (one file per tool) internal/ parser/ : tree-sitter AST parsing, 16 language handlers ingest/ : repo cloning, file walking, gitignore filtering clean/ : code cleaning for LLM context render/ : rendering modes (signatures, skeleton, focused) analyze/ : analysis orchestration compare/ : structural diff engine callgraph/ : call chain tracing (BFS/DFS, bidirectional), type-aware for Go codegraph/ : Apache AGE knowledge graph embeddings/ : semantic search: pgvector store, embed pipeline, hybrid RRF, graph expansion learnings/ : pgvector-backed store for prior review findings investigate/ : Prometheus + Jaeger correlation for debug_investigate fleet/ : deployed-vs-source container image drift github/ : GitHub API (search code/issues/repos, metadata) llm/ : LLM client with retry and fallback keys cache/ : generic LRU cache with Redis L2 ``` ## 分析模式 **深度模式(默认)。** 克隆代码库,遍历文件树,使用 tree-sitter 解析 AST,构建 symbol 表,并通过 LLM 回答问题。`depth` 控制上下文大小(overview/module/deep),`mode` 控制渲染方式(signatures/skeleton/focused)。 **快速模式(`mode=quick`)。** 使用 GitHub Code Search API,无需克隆。返回匹配的代码片段,可选是否由 LLM 进行总结。`mode=raw` 完全跳过 LLM 步骤。 **Issues/PRs 模式(`type=issue` 或 `type=pr`)。** 搜索 GitHub Issues/Pull Requests。返回包含状态、标签、作者的结构化结果,以及 LLM 对趋势的解读。 ## Webhook MCP 端口(`:8897`)上的 `POST /webhook/github` 用于处理 `pull_request` 事件(opened/synchronize/reopened)。需要提供 `X-GitHub-Event` 和 `X-Hub-Signature-256` header,并设置 `GITHUB_WEBHOOK_SECRET`。`REVIEW_POST_ENABLED=true` 会将审查发布到 GitHub;否则只会进行 dry log 记录。通过你现有的隧道将其暴露,并在代码库的 webhook 设置中注册它。 ## 传输方式 - **HTTP**(默认):在 `MCP_PORT` 上支持流式传输的 HTTP - **Stdio**:运行 `./vaelor --stdio` 支持 pipe/SSH 访问 ## 构建 ``` make build # Build binary (CGO required) make lint # Run golangci-lint make test # Run tests make deploy # Docker build + deploy ``` ## 许可证 [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) Apache 2.0, 版权所有 2026 Anatoly Koptev。 ## 贡献 关于如何添加新工具或新语言,请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。 有关安全漏洞,请参阅 [SECURITY.md](SECURITY.md)。请不要为此公开 issue。 如果 Vaelor 能让你的 agent 免于对同一个代码库事实进行两次重复探索,点个 star 可以帮助下一个人在从零开始构建第五个 MCP 代码搜索服务器之前发现它。
标签:AI编程助手, EVTX分析, Go, MCP服务, Ruby工具, SOC Prime, 云安全监控, 代码知识图谱, 开发工具, 弱口令爆破, 日志审计, 测试用例, 语义搜索, 请求拦截, 静态分析