@QingQ77: 为编码 Agent 提供基于 tree-sitter 的结构化、字节精确、低 token 消耗的代码库访问能力 https://github.com/Entelligentsia/grove… 用 Rust 写了一个双面工具:既当 CLI…

X AI KOLs Timeline 工具

摘要

Grove is a Rust-powered tool that uses tree-sitter to provide coding agents with structured, byte-precise, token-efficient access to codebases, supporting 27 languages via CLI and MCP server.

为编码 Agent 提供基于 tree-sitter 的结构化、字节精确、低 token 消耗的代码库访问能力 https://github.com/Entelligentsia/grove… 用 Rust 写了一个双面工具:既当 CLI 也用 MCP 协议跑,核心是靠 tree-sitter 语法树给 AI Agent 提供代码结构信息,不用 grep 也不用读整个文件。 支持 27 种语言,有 7 个工具:outline 看文件骨架、source 取单个符号的源码、map 看目录的依赖关系、callers 查谁调了它、definition 跳定义、symbols 搜符号、check 检查语法错误。
查看原文
查看缓存全文

缓存时间: 2026/07/01 12:07

为编码 Agent 提供基于 tree-sitter 的结构化、字节精确、低 token 消耗的代码库访问能力

https://github.com/Entelligentsia/grove…

用 Rust 写了一个双面工具:既当 CLI 也用 MCP 协议跑,核心是靠 tree-sitter 语法树给 AI Agent 提供代码结构信息,不用 grep 也不用读整个文件。

支持 27 种语言,有 7 个工具:outline 看文件骨架、source 取单个符号的源码、map 看目录的依赖关系、callers 查谁调了它、definition 跳定义、symbols 搜符号、check 检查语法错误。


Entelligentsia/grove

Source: https://github.com/Entelligentsia/grove

grove — structural sight for coding agents

grove gives coding agents structural, byte-precise, token-cheap access to a codebase via tree-sitter — instead of reading whole files. One engine, seven tools, two faces (a human CLI grove <verb> and an MCP server grove serve), with grammars loaded at runtime from a WASM registry, so adding a language needs no recompile and no toolchain on the consumer.

grove in action — install + an agent answering a question with grove, no grep, no whole-file reads

(asciinema cast: docs/assets/grove_demo.cast — play it interactively with asciinema play docs/assets/grove_demo.cast.)

Why grove

Agents burn tokens and round-trips grep-ing and read-ing whole files to answer “where is this defined / what does it do / who calls it.” grove replaces that with one symbol at a time, by exact bytes, behind a stable id the agent passes between turns.

  • Token-cheapoutline a 1700-line file as a skeleton; source one symbol’s body, not the whole file. A map call returns a directory’s definitions + references in one shot.
  • Byte-precise & stable — every result carries a symbol-id (<lang>:<relpath>#<name>@<line>, 1-based) you pass forward across turns.
  • One engine, two faces — the same Rust binary drives the CLI and an MCP server, so a human and an agent see the same thing.
  • Runtime grammars — all 27 official tree-sitter grammars load from a hosted WASM registry; new languages are a registry entry, not a recompile.

Not an LSP. grove is a syntactic, tree-sitter-powered shell for agents — not a semantic language server. It speaks MCP (not LSP), parses (doesn’t analyze), and locates (doesn’t refactor): no type inference, completion, rename, or type-resolved go-to-def. It’s the cheap syntactic layer beneath where an LSP’s semantics begin — complementary, not competitive. Full reasoning: Is grove an LSP?.

27 languages out of the box — one binary, grammars loaded at runtime from the hosted WASM registry:

Bash BashC CC++ C++C# C#Go GoJava JavaJavaScript JavaScriptJulia Julia
PHP PHPPython PythonRuby RubyRust RustScala ScalaTypeScript TypeScriptTSX TSXAgda2
CSS CSS2Embedded Template2Haskell Haskell2HTML HTML2JSDoc2JSON JSON2OCaml OCaml2OCaml Interface OCaml Interface2
CodeQL2Regex2Verilog2

2 minimal profile — core tools only (callers/definition degrade); full profile = all tools. <kbd> = no official logo. Profiles are data, not compiled in. See Languages & grammars.

See VISION.md for the product vision.

Quick start

# 1. install (one line — detects platform, verifies sha256)
curl -fsSL https://raw.githubusercontent.com/Entelligentsia/grove/main/install.sh | sh

# 2. wire it into a project (in the project root)
grove init

grove init detects the project’s languages, auto-fetches their grammars, and writes .mcp.json (the tools exist) + a CLAUDE.md steering directive (the agent reaches for grove instead of grep) + grove.lock. That’s it — your agent now has structural sight. Other install channels (Homebrew, npm, cargo, agent skill) and --as mcp|skill|both are in Install and Setup.

As an agent skill (Claude Code, Cursor, Codex, Cline, …): npx skills add Entelligentsia/grove — the skill self-installs the binary on first use if it’s missing. See Setup.

Evaluated on real codebases

grove is measured in is-grep-enough — a fair, blind-judged comparison of three navigation regimes (text baseline, structural grove, semantic lsp) given the same agent the same prompt across 50 tasks: 10 large, popular, grammar-backed repos × 5 rungs of climbing complexity (locate a symbol → trace flow → recover an architecture). Same substrate, one variable — the navigation capability. Explore every run in the live dashboard.

Same answer, far fewer tokens — across 5 rungs of task complexity grove ties on answer quality and runs about 2x leaner on context, 2.8x leaner on the hardest tasks

The result is a curve, not a verdict:

  • Answer quality ties — and on the hardest traces grove is the more reliable one. Grounding ~0.97 and completeness ~0.99 across all three arms; grep is enough to be correct most of the time. But where text search drifts on a dense trace — the C++ L5 architecture trace drops baseline grounding to 0.80 — grove holds 0.97, because it cites the real syntax tree instead of guessing line numbers.
  • grove runs leaner on context, and the lead widens with complexity. ~395K mean tokens vs 567K (lsp) and 780K (baseline) overall — roughly half the text-search context. By the hardest rung (architecture / binding-spine), baseline pushes ~1.5M tokens against grove’s ~534K — 2.8× leaner (on the TypeScript L5 trace, 2.43M → 570K, 4.3× leaner) — while grove stays tightest on quality.
  • Reported honestly, including where grove doesn’t win. On trivial locate-one-symbol tasks (L1), grove’s fixed structural-call overhead means it isn’t the cheapest — plain text search is. grove pays off on the navigation that actually costs tokens: tracing flow, mapping a subsystem, recovering an architecture.

Token throughput isn’t the billed bill — much of baseline’s volume is cheap cache reads — but it is what drives context-window pressure and latency. Full methodology, per-repo data, blind judgements, and every raw transcript: is-grep-enough · live dashboard.

The tools

CommandWhat it returns
outlinegrove outline <file>a file’s definition skeleton (kind · name · parent · signature · id)
symbolsgrove symbols <dir> --name <n>repo-wide symbol search — --name is exact, --name-contains for substring
sourcegrove source <id>one symbol’s full source — no whole-file read
checkgrove check <file>ERROR / MISSING nodes — post-edit syntax check (exit 1 if any)
callersgrove callers <name> -d <dir>call sites of a symbol, each with its enclosing function
mapgrove map <dir>directory dependency graph: definitions + outgoing references, no bodies
definitiongrove definition <name> / --at <f:l:c>go-to-def, by name or from a usage position

Add --json to any command for the agent-facing shape. Full reference + examples: Tools.

As a library — grove-core

The same engine ships as a standalone crate, grove-core, so you can embed grove’s structural queries directly in Rust — no subprocess, no CLI. The grove binary is a thin clap + MCP shell over it. The crate is clap-free; grammars still load at runtime from the WASM registry, so nothing is compiled in.

On crates.io as grove-cst — CST for the concrete syntax trees tree-sitter builds (grove-core is taken by an unrelated crate). Alias it so imports stay use grove_core::…:

# Cargo.toml
[dependencies]
grove_core = { package = "grove-cst", version = "0.1" }
use std::path::Path;
use grove_core::{init, ops};

fn main() -> anyhow::Result<()> {
    let project = Path::new(".");

    // 1. Provision grammars for this project's languages — fetches any missing
    //    grammar into the OS cache and pins grove.lock. Run once.
    for action in init::provision_project(project, false)? {
        println!("provisioned: {action}");
    }

    // 2. Query — grammars resolve from the cache. Every definition under `src/`,
    //    gitignore-aware, as typed results.
    for s in ops::symbols(&project.join("src"), None, None, false, false)? {
        println!("{} {} — {}:{}", s.kind, s.name, s.file, s.line);
    }
    Ok(())
}

(Offline? Set GROVE_REGISTRY=<dir> to resolve grammars from a pinned registry and skip the fetch — see core/README.md.)

The consumer surface is the ops module — the same seven tools (outline, symbols, source, check, callers, map, definition), returning typed Symbol / Defect / CallSite / FileMap values (re-exported at the crate root). init::provision_project is the grammar-provisioning entry point behind grove init. Crate overview and full API surface: core/README.md · core/src/lib.rs.

Documentation

Status

Pre-1.0. callers/definition are name-based (no receiver-type resolution); 12 languages ship a minimal profile (core tools only); no incremental reparse yet. Details and the rest of the roadmap: Roadmap.

相似文章

@VincentLogic: 这开源项目把 Claude Code 的成本砍了 25%。 它不做新模型,不做新 IDE。 就给 AI coding agent 画了张"代码地图"。 传统玩法:模型读完整个仓库 → 爆 token。 它的玩法:先把代码用 Tree-si…

X AI KOLs Timeline

一个开源项目通过Tree-sitter将代码解析成图结构并存入本地SQLite,为AI coding agent提供代码地图,从而减少token消耗和成本,平均节省57% token,成本降低25%。支持Claude Code、Cursor、aider等工具。

@austinit: 嘿,朋友们! 强烈安利 CodeGraph:把整个代码库变成结构化知识图谱的神器! 用 Tree-sitter 精准解析 AST,支持 20+ 语言,直接喂给 Claude/Cursor 等 AI Agent。 改代码前秒看影响范围,上下…

X AI KOLs Timeline

CodeGraph 是一个将代码库转换为结构化知识图谱的本地优先工具,利用 Tree-sitter 精准解析 AST 并支持 20 多种语言,可直接通过 MCP 协议喂给 Claude、Cursor 等 AI 编码代理,帮助快速分析代码影响范围,减少 token 消耗和工具调用次数。