karst
A 4-step walkthrough

How karst works

Your AI tools read your repo blind and bill you for it. karst gives them a map first — so they load only what matters, and you see the cost before every call.

The problem

AI dev tools read your code blind.

Ask Cursor or a custom agent “how does checkout work?” and it dumps tens of thousands of tokens of vaguely-related files into the model — every single time. You can’t see what it loaded, you can’t scope it, and the bill arrives at the end of the month.

  • Bill shock. A single question can burn 30k+ input tokens. Usage-based pricing turns that into real money, fast.
  • Black-box context. When the answer is wrong you can’t tell if it was the model or the context it never saw.
  • No blast radius. Nothing tells you what else breaks when you change a function.
agent · “how does checkout work?” context window
42,000 tokens loaded · mostly irrelevant $0.13 / question
The fix, in four moves

Give the model a map before it reads

Click a step — or just watch. This is exactly what the engine does to your repo today.

byfoods / src / orders / orders.ts — karst
▾ src
▾ auth
users.ts
login.ts
▾ billing
stripe.ts
▾ orders
orders.ts
cart.ts
// imports
import { getUser } from '../auth/users';
import { charge } from '../billing/stripe';

chunk · checkout()export async function checkout(cartId: string) {
  const cart = await loadCart(cartId);
  const user = await getUser(cart.userId);
  const total = cart.items.reduce((s, i) => s + i.price, 0);
  return charge(user, total);
}

chunk · loadCart()async function loadCart(id: string) {
  return db.carts.findById(id);
}
checkout() getUser() charge() loadCart()
Files that change & call together → one named pack
ordersorders.ts · cart.ts · ~2 chunks
authusers.ts · login.ts
billingstripe.ts
› how does checkout work? — packs: orders
checkout() loads the cart, fetches the buyer via getUser() [orders/orders.ts:5], sums item prices, then calls charge() [billing/stripe.ts].
~3,800 tok · $0.019 vs $0.13 unscoped — shown before the call
01 · INDEX
Parse into chunks
Tree-sitter splits every function, class and method into a real chunk — never blind line-windows.
02 · GRAPH
Map who calls who
A knowledge graph of calls & imports. Now “what breaks if I change this?” is a graph walk, not a guess.
03 · PACK
Group into named packs
Related files become attachable packs — auth, billing, orders. The atomic unit of context.
04 · ASK
Load only what matters
A question loads only its pack. 60% fewer tokens, every answer cited, the cost shown before you spend it.
What actually changes

Same question. One-seventh the cost.

WITHOUT karst
$0.13
  • • 42,000 tokens dumped per question
  • • You can’t see what was loaded
  • • No citations — trust it or don’t
  • • No idea what a change will break
WITH karst
$0.019
  • • ~3,800 tokens — only the relevant pack
  • • You see (and pin) exactly what loads
  • • Every claim cited to file:line
  • karst impact lists the blast radius

Measured on Byfoods — a real 246-file NestJS + Next.js repo: 906 chunks, re-index 343s → 2.3s.

Straight about what’s built

Does it solve your problem? Here’s the honest map.

LIVE TODAY
  • ✓ On PyPI & the official MCP registry — pip install karst
  • ✓ MCP server — plug into Cursor & Claude Desktop
  • ✓ AST chunking across 6 languages
  • ✓ Call/import graph + impact analysis
  • ✓ Pack-scoped retrieval & cost meter
  • ✓ Incremental indexing + embedding cache
  • ✓ Diff code review with citations
COMING NEXT
  • ◷ Hosted indexing (no local daemon)
  • ◷ Team-shared pack library
  • ◷ GitHub PR review bot
  • ◷ OAuth for browser connectors (claude.ai / ChatGPT)

The engine and the MCP server that exposes it to Cursor & Claude Desktop are both real, tested, and shipping — install it today with pip install karst. Every number on this page is measured, not promised. We’d rather tell you exactly where the line is than pretend.

Want it pointed at your repo?

Install it today with pip install karst, or get product updates by email.

Install free Get updates