ashlr
Open-source · MIT · Zero telemetry

Ship less context.
context.

Open-source token ledger for Claude Code. 19 MCP tools. Mean 74.0% savings on files ≥ 2 KB, measured to the byte. MIT-licensed. Zero telemetry.

Tokens saved by users this week
+0
$ claude mcp add ashlr -- npx -y ashlr-plugin
Token comparison

The same file. 79% fewer tokens.

Without ashlr — raw Read
import { createHash } from "crypto"; import { readFileSync, writeFileSync } from "fs"; import path from "path"; export interface GenomeEntry { id: string; symbol: string; file: string; line: number; kind: "function" | "class" | "interface" | "type" | "const"; summary: string; tokens: number; hash: string; updatedAt: number; } export interface GenomeIndex { version: number; rootDir: string; entries: GenomeEntry[]; totalTokens: number; lastScan: number; } function hashContent(content: string): string { return createHash("sha256").update(content).digest("hex").slice(0, 12); } export function loadIndex(rootDir: string): GenomeIndex | null { const indexPath = path.join(rootDir, ".ashlrcode", "genome", "index.json"); try { const raw = readFileSync(indexPath, "utf8"); return JSON.parse(raw) as GenomeIndex; } catch { return null; } } export function saveIndex(rootDir: string, index: GenomeIndex): void { const dir = path.join(rootDir, ".ashlrcode", "genome"); const indexPath = path.join(dir, "index.json"); writeFileSync(indexPath, JSON.stringify(index, null, 2), "utf8"); } export function mergeEntries( existing: GenomeEntry[], incoming: GenomeEntry[] ): GenomeEntry[] { const map = new Map<string, GenomeEntry>(); for (const entry of existing) map.set(entry.id, entry); for (const entry of incoming) map.set(entry.id, entry); return Array.from(map.values()).sort((a, b) => a.file.localeCompare(b.file)); } export function pruneStale( entries: GenomeEntry[], rootDir: string ): GenomeEntry[] { return entries.filter((e) => { try { const abs = path.resolve(rootDir, e.file); const content = readFileSync(abs, "utf8"); return hashContent(content) !== e.hash || true; } catch { return false; } }); } export function buildSummaryBlock(entries: GenomeEntry[]): string { return entries .map((e) => `[${e.kind}] ${e.symbol} @ ${e.file}:${e.line} — ${e.summary}`) .join("\n"); } export function estimateTokens(text: string): number { // ~3.5 chars per token average for source code return Math.ceil(text.length / 3.5); } export function findBySymbol( entries: GenomeEntry[], symbol: string ): GenomeEntry | undefined { return entries.find( (e) => e.symbol === symbol || e.symbol.endsWith("." + symbol) ); } export function topByTokens( entries: GenomeEntry[], n = 10 ): GenomeEntry[] { return [...entries] .sort((a, b) => b.tokens - a.tokens) .slice(0, n); }
100 KB0 B · 0 tokens
With ashlr — ashlr__read snipCompact
import { createHash } from "crypto"; import { readFileSync, writeFileSync } from "fs"; import path from "path"; export interface GenomeEntry { id: string; symbol: string; file: string; line: number; kind: "function" | "class" | "interface" | "type" | "const"; summary: string; tokens: number; hash: string; updatedAt: number; } export interface GenomeIndex { version: number; [... 3840 bytes elided — 61 lines omitted ...] export function topByTokens( entries: GenomeEntry[], n = 10 ): GenomeEntry[] { return [...entries] .sort((a, b) => b.tokens - a.tokens) .slice(0, n); }
21 KB0 B · 0 tokens
snipCompact: head + tail, middle elided — exact bytes shown in-place
03 · How it works

Three mechanisms. Every file read, every grep, every byte accounted for.

ashlr doesn't compress with magic. It wraps the tools Claude Code already uses, applies three concrete techniques at call time, and writes every saving to a local ledger you can audit.

Read it smart

snipCompact head + tail truncation.

Large files come back as head + tail with an elision marker for the middle — the parts Claude actually scans. Typical 60 KB source file arrives as ~9 KB. A single call saves ~51 KB.

$ ashlr__read src/auth.ts
// lines 1-24 (head) …
[…43,042 bytes elided…]
// lines 486-510 (tail)
61,840 bytes → 9,203 bytes  −85.1%
Search with memory

Genome-aware grep.

When a .ashlrcode/genome/ is present, ashlr__grep returns pre-summarized sections instead of raw ripgrep output. Claude gets the understanding it needs, not the noise.

$ ashlr__grep 'checkoutSession'
genome → 3 sections, 1.8 KB
rg equiv → 47 matches, 24.1 KB
−92.5% · honest count emitted alongside result
Keep it honest

Live counter. Every saving. Every session.

Every tool call appends to a local ledger under ~/.ashlr/stats.json. The status line ticks up within ~550 ms of each call. Sessions are keyed by CLAUDE_SESSION_ID so concurrent terminals never collide.

status line
ashlr · 7d ▁▂▃▄▅▇█ · session +100K · lifetime +4.3M
01MCP Tools

15 tools. Every read fewer tokens.

Drop-in replacements for Claude Code’s built-ins. snipCompact trims large results head&plus;tail; genome RAG retrieves only what’s relevant.

ashlr__efficiency79.5%

read, grep, edit, savings — snipCompact truncation + genome RAG + diff-only edits in one server.

ashlr__sql58.4%

Query SQLite, Postgres, or any libsql database without echoing the full schema back every time.

ashlr__bash44.8%

Long-running shell commands with live tail, start/stop control, and output capped to budget.

ashlr__tree

Directory tree with depth and ignore controls — returns a compact structure map, not a file flood.

ashlr__http64.2%

Authenticated HTTP requests with response truncation; no raw 50 KB JSON dumps in context.

ashlr__diff54.3%

Unified diff between two file paths or two text blobs — surface the delta, not the full files.

ashlr__logs

Tail and search structured log files with time-window filters and line budget.

ashlr__genome

Propose and consolidate repo knowledge entries — the scribe loop that keeps RAG retrieval sharp.

ashlr__orient

Entry-point overview of an unfamiliar repo: top files, recent commits, and genome summary in one call.

ashlr__github

Create and read issues and PRs with body truncation — no 200-line diff blobs poisoning context.

ashlr__glob

Pattern-match file paths across the repo with depth limits and gitignore awareness.

ashlr__webfetch

Fetch a URL and return only the readable text — strips boilerplate, headers, and nav chrome.

ashlr__multi_edit

Atomic batched edits across N files in a single call — one round-trip instead of N sequential patches.

ashlr__ask

Pose a targeted question to a sub-agent with a minimal context slice — haiku-priced delegation.

ashlr__diff_semantic

Semantic diff that groups changes by intent (rename, extract, refactor) rather than raw line delta.

02Slash Commands

30 skills. Zero friction.

Type /ashlr- in Claude Code to access dashboards, demos, and diagnostics.

/ashlr-allow

Auto-approve every ashlr tool at session start

/ashlr-usage

Per-tool call counts and token breakdown for this session

/ashlr-errors

Deduplicated MCP server error log with root-cause hints

/ashlr-demo

30-second scripted showcase of savings on your actual repo

/ashlr-badge

Generate and embed an SVG savings badge in your README

/ashlr-legend

Plain-text guide to every element in the ashlr status line

/ashlr-dashboard

Rich per-tool bar charts and 7d/30d savings history

/ashlr-coach

Proactive nudges based on your session patterns

/ashlr-handoff

Context-pack for the next session to resume cold

03Benchmark

See it save tokens.

Reproducible against your own codebase: bun run bench. Numbers below from the ashlr-plugin source repo.

79.5%mean on files >= 2 KB
Tokens per read · large file
100,000
without ashlr
20,500
with ashlr
File-by-file breakdownsaved %
genome/retriever.ts
79.7%
genome/fitness.ts
79.8%
genome/scribe.ts
80.9%
genome/generations.ts
85.9%
compression/context.ts
73.2%
04Pricing

Free forever. Cloud when you need it.

The free tier is the product. Pro adds hosted infrastructure — it does not remove or degrade anything in Free.

Free
$0forever

The full plugin — every tool, every skill, no strings.

  • +35 MCP tools + 30 skills
  • +Local genome scribe loop
  • +Per-session token ledger
  • +Cursor + Goose ports (MCP only)
Start free
Pro
$12per month

Cloud infra for one developer who wants sync and speed.

  • +Everything in Free
  • +Cloud LLM summarizer
  • +Cross-machine stats sync
  • +Live auto-updating badge
Team
$24per user/month

Shared genome and org-level visibility for engineering teams.

  • +Everything in Pro
  • +Shared encrypted team genome (E2E + vclock)
  • +Org savings dashboard
  • +SSO + SCIM + audit log
05Open source

Auditable to the last byte.