Skip to main content
Glama
allengox1994-creator

repo-map MCP server

cursor-token-saver

English | 简体中文

A cognitive layer for Cursor's agent. On one side, a content-addressed evidence store drives token usage to the floor — losslessly, with exact recovery on demand. On the other, verifiable semantic memory, a project world model and skill runbooks let the agent accumulate real understanding of your project across sessions. LLMs are stateless by nature; this system makes the agent stateful inside your project. Fully local, zero telemetry.

Core design principle: defer transmission, never permanently delete information. Source snippets and full command logs become local content with stable evidence IDs; the model gets a minimal first screen by default, and anything can be recovered exactly via context_expand. All budgets are soft, every block can be retried through, and every hook fails open.

Concepts & principles

Token waste and cross-session amnesia are two faces of the same problem: LLMs are stateless, every request re-transmits the whole context, and everything resets to zero when the session ends. This tool attacks both sides at once —

The saving side: a Content-Addressed Evidence Store. Everything that gets truncated, compacted or diffed is persisted by content hash with a stable evidence ID. The model receives only a minimal first screen (outline, diff, structural profile) by default; any line range can be recovered exactly by ID. What gets eliminated is the waste of "transmit everything by default" — with zero information loss.

The remembering side: a three-layer memory structure (mirroring the declarative/procedural split in cognitive science):

Layer

What it stores

Where it comes from

Semantic memory (facts)

Conventions, decisions, gotchas, entry points

Explicit memory_save by the agent + mechanical extraction from checkpoint decisions

World model (relations)

entity —relation→ entity triples: domain → port → service → script

Automatic scans of package.json / docker-compose / nginx / .env / CI

Skill memory (procedures)

Reusable runbooks: goal + successful command sequence

Mechanically extracted from the command timeline when a task wraps up; fail→fix journeys mined into gotchas

The trust anchor: Verifiable Memory. Memories carry evidence hashes — when a file changes, the memory is automatically flagged STALE. Mechanical extraction only produces candidates; nothing takes effect until the agent or a human confirms it. Long-unused entries are archived automatically; recurrence raises confidence. This machinery prevents "memory hallucination" from polluting future sessions: a memory system that blindly trusts whatever it stored eventually becomes a liability.

The loop: perceive → remember → recall → act → feed back → learn. Hooks observe every file read and command run (perception), distill them into verifiable memory (learning), code search automatically fuses in relevant memories (recall), and the bootstrap warm-start pack restores full task state in a few hundred tokens (continuity). The result: the agent gets cheaper and smarter in your repo, session after session.

Architecture diagram

Architecture diagram

The loop: perceive → remember → recall → act → feed back → learn. The thick green line is the lossless reinjection path — the model receives only a minimal first screen plus evidence IDs; everything else is recovered exactly, on demand.

Related MCP server: LightRAG Code Brain MCP

Quick start

# run in your project root
npx cursor-token-saver init                 # install (standard profile)
npx cursor-token-saver init --profile extreme   # maximum savings

npx cursor-token-saver dashboard            # global dashboard at http://localhost:4517 (all projects)
npx cursor-token-saver report --all         # global summary in the terminal
npx cursor-token-saver report               # current project stats
npx cursor-token-saver index                # optional: pre-build the neural embedding index
npx cursor-token-saver eval --limit 50      # optional: offline retrieval-quality evaluation
npx cursor-token-saver daemon               # optional: start the global model daemon manually (usually automatic)
npx cursor-token-saver start-all            # after a reboot: start all resident services in one shot

Cursor picks the hooks up automatically after install (check Settings → Hooks; restart Cursor if needed). Requires Node >= 18 on PATH.

What the hooks intercept

Hook

Event

Behavior

read-guard

preToolUse (Read)

Full reads beyond the line cap → blocked with the line count and suggested reading strategy; rapid re-reads of unmodified files → blocked with pointers; re-reads after a file changed transmit only a lossless line diff (old content + diff = new content; the full snapshot stays recoverable by ID). Anti-lockout: if the agent immediately retries the same file, it is force-allowed (reads within 25% of the cap pass straight through to avoid boundary friction)

file-blocklist

beforeReadFile

Blocks lockfiles, build output, minified bundles and oversized data files (data files are pointed to the context_query mode=profile structural profile). Files the user explicitly attaches with @ always pass

shell-guard

preToolUse (Shell)

Whitelisted noisy commands are captured in full as local artifacts; Jest/Vitest, Pytest, Cargo, Go test and compiler logs show only failure summaries / relevant stack traces first; re-running the same command (the classic edit → re-test loop) returns only a lossless diff against the previous output — a single marker line if byte-identical. Pure && chains whose every segment is whitelisted (e.g. npm run build && npm test) are governed as a whole. Anything omitted is recoverable by ID. Commands with pipes/redirection are left untouched

edit-invalidate

afterFileEdit

Allows re-reads after edits and keeps the read snapshot so the re-read goes through incremental diffing (prevents false blocks; read-guard has an mtime fallback of its own)

shell-audit

afterShellExecution

Pure stats: records command output volume to identify noise hogs

mcp-audit

afterMCPExecution

Pure stats: records output volume of other MCP tools (repo-map's own calls are recorded server-side)

session-track

sessionStart / stop / preCompact

Session stats; on context compaction, nudges that "a fresh session is cheaper"

init also writes:

  • .cursor/mcp.json: registers the repo-map MCP server (see below)

  • .cursor/rules/token-saver.mdc: one compact token-efficiency rule (locate via repo map / search first, read compactly, delegate exploration to subagents, prefer a fresh session once a task converges, plan large tasks first)

  • .cursorignore: a static low-value list (lockfiles, build output, fonts, archives, …) plus scanned oversized files, kept inside a marker block that never touches your own content. After install, sessionStart rescans every 24 hours and folds newly grown data/log files into the block automatically

MCP repo map (the proactive side: cheaper ways to get information)

Hooks are the "dam"; the unified context MCP is the "channel". init registers a zero-dependency local MCP server (node .cursor/hooks/token-saver/mcp-repo-map.mjs; enable it once under Settings → MCP). Tool definitions are themselves a fixed per-request cost, so tools/list exposes only 4 unified lossless tools by default; 5 legacy tools (repo_map/file_outline/smart_search/semantic_search/read_compact) stay hidden but still answer tools/call, and contextQuery.legacyTools=true restores them:

Tool

What it does

Where it saves

context_query

Unified entry point: search runs exact string, BM25 and local neural vectors with RRF fusion; plus map, outline, callgraph, read (with symbol skeleton reads), profile (data-file profiling), diff, lsp, bootstrap modes

First screen returns short previews and stable evidence IDs; on low confidence / recent test failures it widens internal candidates without shipping the noise to the model

context_expand

Expands an evidence ID through preview / compact / exact / full, or reads full logs by regex or line range

Compressed results always have an exact-text fallback; stale IDs after source changes are reported explicitly, preventing use of outdated evidence

context_checkpoint

Saves/restores goal, status, touched files, decisions and open questions

Compaction or a new session doesn't require replaying the whole conversation

repo_map

Whole-repo symbol map: class/function signatures + line numbers, ranked by import-graph PageRank (★ marks core files, which show more symbols), with subdirectory focus and a character budget

Replaces "read a pile of files to understand the project" — one call turns thousands of tokens into hundreds

file_outline

Full single-file outline (symbols + line numbers)

Outline first, then read exact ranges — replaces full reads

smart_search

Exact, compact search returning only path:line: matching line (ripgrep preferred, built-in scanner fallback)

Replaces exploratory reads done just to locate code

semantic_search

Concept-level search: local neural embeddings + BM25 hybrid (RRF fusion) for queries like "where is login handled"

Replaces multi-round trial-and-error grep

read_compact

Compact reads: strips comments/blank lines, folds long literals, keeps original line numbers with exact evidence IDs, supports start_line/end_line

Typically another 25–50% off source files; comments/literals recoverable by ID when they matter

Symbol extraction is a zero-dependency regex approach covering JS/TS/Python/Go/Rust/Java/Kotlin/Swift/C#/Ruby/PHP/C/C++. callgraph is an approximate import/reference graph that states its confidence limits — it does not impersonate a compiler-grade call graph. Every query's evidence is recorded in .cursor/token-saver/context-store/manifest.json; for source code only path, range, stamp and SHA-256 are stored — only full logs go into blobs/.

Lossless dedup, soft budgets and log artifacts

  • Content already transmitted and unchanged within a conversation returns just already_sent + ID; changed files get new IDs.

  • Read-only tool result dedup: when repo_map/file_outline etc. produce byte-identical results within 10 minutes (contextQuery.toolDedupeMs), only a one-line "unchanged" marker + artifact ID is returned; the full result stays recoverable by ID from any session. context_expand/context_checkpoint are never deduped.

  • Warm-start pack for new sessions: context_query {"mode":"bootstrap"} returns the latest checkpoint, Git-changed files, recent failed commands and recent evidence IDs in a few hundred tokens — a follow-up session doesn't re-explore. sessionStart auto-hints when a checkpoint exists within 48 hours.

  • Symbol-level skeleton reads: context_query {"mode":"read","file":"...","symbol":"..."} returns the target function/class in full while folding the rest of the file into a one-line-per-symbol skeleton — 60–80% cheaper than a full read, any range expandable afterwards.

  • Data-file profiling: context_query {"mode":"profile","file":"..."} returns a structural overview (keys/types/row counts/samples) + evidence ID for JSON/JSONL/CSV/TSV/YAML; exact records recoverable by regex/line range. A large JSON goes from hundreds of thousands of tokens to a few hundred.

  • Tool output accrues against a per-session soft budget. Past the warning ratio only subsequent first screens shrink — context_query's character budget halves and governed commands' head/tail lines halve — context_expand exact/full is never restricted.

  • Full stdout/stderr of noisy commands is stored as context-store artifacts; default retention 7 days / 512MB max, with TTL/LRU cleanup at sessionStart.

  • preCompact, file edits and stop maintain deterministic mechanical checkpoints; the agent adds true semantic decisions via context_checkpoint — the tool never fabricates summaries.

  • Configuration lives in the contextQuery, artifactStore and taskBudget sections; the dashboard's Context page shows evidence, artifact, budget and checkpoint stats.

Project semantic memory (stop re-exploring across sessions)

The biggest hidden waste in a new session is relearning the same engineering facts. The memory system persists them:

  • Write: the agent uses memory_save for conventions/decisions/gotchas/entry points (optionally linked to files). Four mechanical extraction channels produce candidates only, which take effect after confirmation — context_checkpoint decisions; fail→fix (when the same command flips from failing to passing with file edits in between, "command X failed, passed after editing A and B" is recorded automatically); runbooks (when a checkpoint marks a task complete, the exit-0 command sequence is extracted as a reusable skill, with recurrence raising confidence); world-model scans (throttled to 24h, scanning package.json / docker-compose / nginx / .env / CI for entity —relation→ entity triples). The machine never fabricates and never self-confirms.

  • Recall: context_query {"mode":"memory","query":"..."} searches by relevance (word-level for English, bigram for Chinese); {"mode":"world","query":"9501"} walks the relation subgraph from an entity (1–2 hops — one triple line replaces hundreds of config lines); bootstrap includes top entries automatically; mode=search code results automatically carry highly relevant memories (retrieval fusion, zero extra calls).

  • Verifiable: file-linked memories store content hashes; recall flags STALE explicitly after the file changes, and memory_save action=confirm re-confirms against current content — preventing memory hallucinations from polluting future sessions.

  • Consolidation: memory_save action=merge ids=[...] text="..." lets the agent merge related entries into one refined memory; originals are archived with mergedInto provenance.

  • Scope: project-level by default; scope=global stores to ~/.cursor-token-saver/ for cross-project recall (personal preferences). Global memories carry no file links and never go stale.

  • Governance: similar entries auto-merge; long-unrecalled ones auto-archive (recoverable, not deleted); candidates expire after 14 days unconfirmed; total count is capped. The dashboard's Memory page includes effectiveness metrics (active/candidate counts, total recalls, never-recalled, expiring candidates, relation/skill counts and skill reuse) with view/confirm/edit/archive/restore/delete.

  • Configured in the memory section (enabled/maxActive/decayDays/bootstrapMax).

Diff, LSP, test selection and offline evaluation

  • context_query {"mode":"diff"} stores the full Git patch as an artifact; the first screen returns only changed files, hunks and current source evidence IDs. Non-Git projects fall back explicitly to plain map/search.

  • context_query {"mode":"lsp","file":"...","symbol":"..."} calls your locally installed typescript-language-server, pyright-langserver, rust-analyzer or gopls on demand for references/definitions. Default 1.5s timeout with a circuit breaker; missing or failing servers fall back immediately to the existing import/exact-text graph.

  • test_select {"phase":"iterate"} picks relevant tests from Git changes, direct naming and reverse imports; on low confidence it returns the full-suite command outright, and when selected tests fail it offers the full-suite fallback. Call phase=final before handoff — it always returns the complete suite.

  • After a real index build or incremental refresh, an offline evaluation is scheduled automatically: 2-minute delay, background low priority, at most once per 24h per project, with a cross-process lock. If the MCP exits mid-way the schedule resumes on next start; failures only write status and never affect retrieval.

  • cursor-token-saver eval --dir . --limit 50 still works for an immediate manual run. It builds a query→expected-file dataset from real symbols and reports Hit@1, Hit@5, MRR to .cursor/token-saver/eval-report.json.

  • Auto-eval settings live in embedding.autoEval, embedding.autoEvalIntervalHours, embedding.autoEvalLimit, editable from the dashboard with schedule/run/failure status.

Global index daemon

Neural embeddings connect to a global daemon at 127.0.0.1:4518 by default, so every project shares one model instance while each project keeps its own vector index. It starts automatically on first retrieval; connection, startup or inference failures fall back instantly to in-project transformers → Ollama → BM25, never losing capability. Manual start:

cursor-token-saver daemon --port 4518

Config: embedding.useGlobalDaemon=false disables it, embedding.daemonPort changes the port. The daemon listens on loopback only; no source code leaves your machine.

One-shot startup after a reboot

Double-click start-all.command in the source directory, or run:

./start-all.sh
# or, if installed globally:
cursor-token-saver start-all

This idempotently starts the global dashboard (which serves the frontend, port 4517) and the global index daemon (port 4518); already-running services are not started twice. Logs live in ~/.cursor-token-saver/logs/. Project-level MCP servers don't belong in the script — Cursor starts them when the project opens.

Semantic search (neural embeddings)

semantic_search uses fully local neural embeddings (transformers.js + ONNX); code never leaves your machine. The default model is the multilingual Xenova/paraphrase-multilingual-MiniLM-L12-v2 (~120MB quantized, works for both English and Chinese queries); English-only projects can switch to Xenova/all-MiniLM-L6-v2 (~23MB):

  • Indexing: chunks along symbol boundaries (≤60 lines each), Int8-quantized vectors in .cursor/token-saver/embed-index.json, incrementally updated by mtime — only changed files are re-embedded

  • Model cache: ~/.cursor-token-saver/models/, shared by all projects, downloaded once; behind restrictive networks use HF_ENDPOINT=https://hf-mirror.com

  • Fully automatic: the MCP server (resident while the project is open in Cursor) builds the index ~45s after start, then runs a cheap staleness check every 5 minutes (file stats only), re-embedding incrementally on change — no manual index runs needed; semantic_search calls also refresh in place. cursor-token-saver index remains available for pre-building. Disable per-project with "embedding": { "autoIndex": false }

  • Fallback chain: transformers.js → (if unavailable) Ollama (nomic-embed-text) → BM25 — never dead

  • Config: the embedding section of .cursor/token-saver.json: { "backend": "auto|transformers|ollama|off", "model": "...", "ollamaModel": "..." }

Note: the scripts copied into your project remain zero-dependency; the neural-embedding dependencies live in the installed package (init records the package path in .cursor/token-saver/pkg.json). If the package is removed or moved, the fallback chain kicks in automatically.

Three aggressiveness profiles

Profile

Read cap

Re-read window

Data-file threshold

Command output governance

conservative

1500 lines

off

1 MB

off

standard (recommended)

800 lines

15 min

512 KB

head 50 / tail 100 lines

extreme

400 lines

45 min

128 KB

head 30 / tail 60 lines

Config lives in .cursor/token-saver.json; dashboard edits take effect immediately (hooks re-read config on every run). Each hook can be toggled and each threshold overridden individually.

Stats and the global dashboard

Every block/truncation event is appended to each project's own .cursor/token-saver/stats.jsonl (data never leaves the project; delete the project, delete the data). Each init and session start registers the project in the global registry ~/.cursor-token-saver/projects.json.

The dashboard is global: run npx cursor-token-saver dashboard from anywhere for an aggregate view of all registered projects (total savings, project overview table, cross-project trends/distributions/top lists, recent events with a project column); switch to a single project from the top-left for details and configuration. Config stays per-project; deleted projects are cleaned from the registry automatically. Only one dashboard instance is needed.

There's also an Index page: pick a project to inspect its embedding index — model, files/chunks indexed, index size and update time, plus per-file status (fresh / pending / unindexed / deleted) with path filtering. Pending files are refreshed incrementally by the MCP server; no manual action needed.

The Index page includes an auto-index status card: every automatic check/rebuild writes a heartbeat to .cursor/token-saver/embed-status.json (pid, last check/rebuild time, files re-embedded), from which the dashboard shows whether auto-indexing is "running" or "stopped" — "stopped" means that project's MCP server isn't running; restart Cursor or refresh it under MCP settings.

There's also a Waste Insights page: it mines the past 7 days of events for "money left on the table" — files repeatedly re-read in full, noisy commands outside the whitelist, files overridden after blocking — with matching calibration advice (adjust windows, caps, use profiling, etc.). This page saves nothing by itself, but keeps every threshold and whitelist calibrated against real usage.

Script copies auto-upgrade: after updating the package, the hook scripts copied into each project sync to the latest version at the next session start (session-track compares against the package source referenced in pkg.json and re-copies on drift, logged as a "script auto-upgrade" event). Note the resident MCP server process needs a restart (restart Cursor or refresh MCP) to run new code.

Note: hooks can't see billing-grade token counts, so savings are estimates: where original text is available, a CJK-aware estimate is used (CJK ≈ 1 token per char, otherwise ≈ 3.9 bytes per token); where only byte counts exist, bytes / 4; the context_tokens in preCompact events is the real value reported by Cursor.

Benchmarks (honest methodology)

cursor-token-saver bench replays six typical agent operations on your real codebase (structure browsing, close reading, unchanged re-read, post-edit re-read, repeated commands, data files), compares "raw full transmission" against "tool first screen" token volumes, prints the comparison table and writes .cursor/token-saver/bench-report.json. The report carries its own methodology statement: it measures transport-layer tokens, not API billing; scenarios are computed independently; every compression is losslessly recoverable. Marketing quotes must include the methodology.

Licensing (commercial component)

cursor-token-saver license provides offline licensing: Ed25519 signature verification, no network activation, no telemetry. activate <key> to activate, status to inspect, deactivate to remove; the vendor side issues with issue --email ... --plan pro|team --days 365 (private key at ~/.cursor-token-saver/vendor-private.pemnever commit it, always back it up). The free tier is fully functional today; license status is informational until paid features (memory sync, team memory vaults) land, gated by licenseStatus().

Landing page: https://allengox1994-creator.github.io/cursor-token-saver/ (source in site/, auto-deployed on push to main). Repository: https://github.com/allengox1994-creator/cursor-token-saver. Contact: allengox1994@gmail.com.

Why this doesn't weaken the agent

  • Truncation never loses information: the full content still exists (files on disk / logs persisted) — "push everything" merely becomes "pull on demand"

  • Every block carries directions, so the agent knows exactly how to get what it needs next

  • Range reads, user-attached files and complex shell commands always pass

  • Every hook fails open: crashes and timeouts never block the agent

  • A more focused context usually improves answer quality (attention dilution in long contexts is a well-documented problem)

Limitations

  • shell-guard command rewriting supports macOS / Linux only (skipped automatically on Windows; other hooks unaffected)

  • Savings are estimates, not billing figures

  • Dashboard charts use the Chart.js CDN; offline, charts degrade while tables and config keep working

Uninstall

Delete .cursor/hooks/token-saver/, .cursor/rules/token-saver.mdc and .cursor/token-saver*, then remove entries containing hooks/token-saver/ from .cursor/hooks.json, the repo-map entry from .cursor/mcp.json, and the marker block from .cursorignore. The global registry lives in ~/.cursor-token-saver/; deleted projects are cleaned up automatically, or remove the whole directory.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Provides persistent memory and a codebase knowledge graph for AI coding assistants, enabling shared context across multiple tools like Claude, Cursor, and ChatGPT, with significant token reduction.
    5
    25
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Provides persistent, anchored memory for AI coding agents, binding every decision to specific lines of code and delivering relevant context just-in-time via the Model Context Protocol.
    1
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Provides persistent codebase memory and semantic context for AI agents via AST-aware chunking and symbol graph indexing.
    1
    -