Supercharge your AI Agents with AST-Precise Search

GraphIndexer: AST-Precise Context Search for AI Agents

Zero-Database · Air-Gapped · Hybrid Search. Reduce context usage by up to 88%.

View on GitHub

MIT License · Node.js v18+ · Works with Claude Code, Cursor & Claude Desktop

TL;DR — What is graph-indexer?

graph-indexer is an open-source (MIT) Model Context Protocol (MCP) server that indexes a codebase into AST-precise chunks using Tree-sitter, so AI coding agents can search code by concept instead of reading entire files. It combines BM25 lexical search with optional vector embeddings (hybrid search) and stores the index as local files — no database, no cloud services, no telemetry. Across 5 production codebases it reduces context usage by 65–88% per query (mean 77.9% token savings), with Recall@5 of 100%, MRR of 0.95, and 0.5 ms mean query latency.

Requirements
Node.js v18 or later. Ollama is optional (only needed for semantic/vector search; lexical-only mode works without it).
Primary use case
Giving AI coding agents (Claude Code, Cursor, Claude Desktop) token-efficient, precise code retrieval over large repositories via MCP tools such as search_code, resolve_symbol, and get_call_graph.
Installation
npm install graph-indexer --save-dev, then npx graph-indexer init.
Supported languages
TypeScript/TSX, JavaScript, Python, Go, Rust, PHP, Java, Kotlin, C#, Ruby, and CSS/SCSS.

Stop burning tokens on full-file reads

Same agent task — “Add error handling to the payment processing flow” — two very different context bills.

WITHOUT graph-indexer

The agent greps for keywords, then reads entire files into context to find the relevant logic.

  • → read src/services/payment.service.ts (4,800 tokens)
  • → read src/controllers/payment.controller.ts (3,900 tokens)
  • → read src/utils/errors.ts (2,600 tokens)
  • → read 4 more files… (5,100 tokens)

~16,400 tokens consumed

WITH graph-indexer

The agent searches by concept and receives only the exact AST chunks it needs.

  • → search_code("payment processing error handling")
  • → processPayment() (chunk · 310 tokens)
  • → handlePaymentError() (chunk · 280 tokens)
  • → PaymentError class (chunk · 340 tokens)

~930 tokens consumed

That’s a 94% reduction on this task — and a mean of 77.9% across benchmarks.

Benchmarked on real codebases

Measured across Axios, Express, NestJS, FastAPI and Gin — not toy repos.

77.9%
Mean token savings

65–88% reduction per query across 5 production codebases

100%
Recall@5

The right chunk is always in the top 5 results

0.95
MRR

Correct answer ranks #1–2 on average

0.5ms
Mean latency

Local file-based index, no network round-trips

Built for serious codebases

Precision retrieval without giving up privacy, speed, or simplicity.

Privacy First

Runs 100% locally with zero telemetry. The index lives in plain files inside your repo — no database server, no cloud API, no code ever leaving your machine. Safe for air-gapped and compliance-bound environments.

zero-database · air-gapped · no telemetry

AST-Precise

Tree-sitter parses your source into exact functions, classes and symbols — chunks follow code structure, never arbitrary line windows.

Hybrid Engine

BM25 lexical matching fused with vector embeddings via Ollama. Exact identifiers and fuzzy concepts both land — or run lexical-only with no Ollama at all.

Topology Aware

Tracks bidirectional dependencies and call graphs across your repo. Ask get_call_graph who calls a function — or what it calls — and get a get_repo_map overview without reading a single file.

Indexed in under a minute

Two commands. init auto-detects your IDE, wires up npm scripts and .gitignore, and asks which languages to index.

~/your-project — zsh
$ npm install graph-indexer --save-dev
$ npx graph-indexer init

 Detected IDE: Claude Code (.mcp.json)
 Added npm scripts: mcp:index, mcp:start
 Updated .gitignore

? Which languages should be indexed? (space to select)
  ◉ TypeScript / TSX
  ◉ JavaScript
  ◯ Python
  ◯ Go
  ◯ Rust
  ◯ PHP · Java · Kotlin · C# · Ruby · CSS/SCSS

 Saved to .graph-indexer.json — run npm run mcp:index to build the index

With semantic search (recommended)

ollama pull nomic-embed-text
npm run mcp:index

Lexical-only (no Ollama needed)

INDEXER_EMBEDDINGS=off npm run mcp:index