Stop feeding your AI entire codebases. Give it a scalpel instead. An MCP server that indexes your codebase structurally and exposes surgical query tools — so your AI agent reads 200 characters instead of 200 files. Measured across 782 real sessions: 99% token reduction. Every AI coding session starts the same way: the agent grabs cat or grep, reads a dozen files to find one function, then bloats i
Add this skill
npx mdskills install Mibayy/token-saviorStructural codebase indexer with 34 MCP tools delivering sub-millisecond queries and 99% token reduction
1<!-- mcp-name: io.github.Mibayy/token-savior -->23<div align="center">45# ⚔ token-savior67**Stop feeding your AI entire codebases. Give it a scalpel instead.**89[](https://github.com/Mibayy/token-savior/actions/workflows/ci.yml)10[](https://www.python.org/downloads/)11[](https://modelcontextprotocol.io)12[](https://github.com/Mibayy/token-savior)1314</div>1516---1718An MCP server that indexes your codebase structurally and exposes surgical query tools — so your AI agent reads 200 characters instead of 200 files.1920```21find_symbol("send_message") → 67 chars (was: 41M chars of source)22get_change_impact("LLMClient") → 16K chars (154 direct + 492 transitive deps)23get_function_source("compile") → 4.5K chars (exact source, no grep, no cat)24```2526**Measured across 782 real sessions: 99% token reduction.**2728---2930## Why this exists3132Every AI coding session starts the same way: the agent grabs `cat` or `grep`, reads a dozen files to find one function, then bloats its context trying to understand what else might break. By the end, half your token budget is gone before the first edit.3334`token-savior` replaces that pattern entirely. It builds a structural index once, keeps it in sync with git automatically, and answers "where is X", "what calls X", and "what breaks if I change X" in sub-millisecond time — with responses sized to the answer, not the codebase.3536---3738## Numbers3940### Token savings across real sessions4142| Project | Sessions | Queries | Chars used | Chars (naive) | Saving |43|---------|----------|---------|------------|---------------|--------|44| project-alpha | 35 | 360 | 4,801,108 | 639,560,872 | **99%** |45| project-beta | 26 | 189 | 766,508 | 20,936,204 | **96%** |46| project-gamma | 30 | 232 | 410,816 | 3,679,868 | **89%** |47| **TOTAL** | **92** | **782** | **5,981,476** | **664,229,092** | **99%** |4849> "Chars (naive)" = total source size of all files the agent would have read with `cat`/`grep`. These savings are model-agnostic — the index reduces context window pressure regardless of provider.5051### Query response time (sub-millisecond at 1.1M lines)5253| Query | RMLPlus | FastAPI | Django | CPython |54|-------|--------:|--------:|-------:|--------:|55| `find_symbol` | 0.01ms | 0.01ms | 0.03ms | 0.08ms |56| `get_dependencies` | 0.00ms | 0.00ms | 0.00ms | 0.01ms |57| `get_change_impact` | 0.02ms | 0.00ms | 2.81ms | 0.45ms |58| `get_function_source` | 0.01ms | 0.02ms | 0.03ms | 0.10ms |5960### Index build performance6162| Project | Files | Lines | Index time | Memory |63|---------|------:|------:|-----------:|-------:|64| Small project | 36 | 7,762 | 0.9s | 2.4 MB |65| FastAPI | 2,556 | 332,160 | 5.7s | 55 MB |66| Django | 3,714 | 707,493 | 36.2s | 126 MB |67| **CPython** | **2,464** | **1,115,334** | **55.9s** | **197 MB** |6869With the persistent cache, subsequent restarts skip the full build. CPython goes from 56s → under 1s on cache hit.7071---7273## What it covers7475| Language / Type | Files | Extracts |76|-----------------|-------|----------|77| Python | `.py`, `.pyw` | Functions, classes, methods, imports, dependency graph |78| TypeScript / JS | `.ts`, `.tsx`, `.js`, `.jsx` | Functions, arrow functions, classes, interfaces, type aliases |79| Go | `.go` | Functions, methods (receiver), structs, interfaces, type aliases |80| Rust | `.rs` | Functions, structs, enums, traits, impl blocks, macro_rules |81| C# | `.cs` | Classes, interfaces, structs, enums, methods, XML doc comments |82| Markdown / Text | `.md`, `.txt`, `.rst` | Sections via heading detection |83| JSON | `.json` | Nested key structure up to depth 4, `$ref` cross-references |84| Everything else | `*` | Line counts (generic fallback) |8586A workspace pointing at `/root` indexes Python bots, docker-compose files, READMEs, skill files, and API configs in one pass. Any agent task benefits — not only code refactoring.8788---8990## 34 tools9192### Navigation93| Tool | What it does |94|------|-------------|95| `find_symbol` | Where a symbol is defined — file, line, type, 20-line preview |96| `get_function_source` | Full source of a function or method |97| `get_class_source` | Full source of a class |98| `get_functions` | All functions in a file or project |99| `get_classes` | All classes with methods and bases |100| `get_imports` | All imports with module, names, line |101| `get_structure_summary` | File or project structure at a glance |102| `list_files` | Indexed files with optional glob filter |103| `get_project_summary` | File count, packages, top classes/functions |104| `search_codebase` | Regex search across all indexed files |105| `reindex` | Force full re-index (rarely needed) |106107### Impact analysis108| Tool | What it does |109|------|-------------|110| `get_dependencies` | What a symbol calls/uses |111| `get_dependents` | What calls/uses a symbol |112| `get_change_impact` | Direct + transitive dependents in one call |113| `get_call_chain` | Shortest dependency path between two symbols (BFS) |114| `get_file_dependencies` | Files imported by a given file |115| `get_file_dependents` | Files that import from a given file |116117### Git & diffs118| Tool | What it does |119|------|-------------|120| `get_git_status` | Branch, ahead/behind, staged, unstaged, untracked |121| `get_changed_symbols` | Changed files as symbol-level summaries, not diffs |122| `get_changed_symbols_since_ref` | Symbol-level changes since any git ref |123| `summarize_patch_by_symbol` | Compact review view — symbols instead of textual diffs |124| `build_commit_summary` | Compact commit summary from changed files |125126### Safe editing127| Tool | What it does |128|------|-------------|129| `replace_symbol_source` | Replace a symbol's source without touching the rest of the file |130| `insert_near_symbol` | Insert content before or after a symbol |131| `create_checkpoint` | Snapshot a set of files before editing |132| `restore_checkpoint` | Restore from checkpoint |133| `compare_checkpoint_by_symbol` | Diff checkpoint vs current at symbol level |134| `list_checkpoints` | List available checkpoints |135136### Test & run137| Tool | What it does |138|------|-------------|139| `find_impacted_test_files` | Infer likely impacted pytest files from changed symbols |140| `run_impacted_tests` | Run only impacted tests — compact summary, not raw logs |141| `apply_symbol_change_and_validate` | Edit + run impacted tests in one call |142| `apply_symbol_change_validate_with_rollback` | Edit + validate + auto-rollback on failure |143| `discover_project_actions` | Detect test/lint/build/run commands from project files |144| `run_project_action` | Execute a discovered action with bounded output |145146### Stats147| Tool | What it does |148|------|-------------|149| `get_usage_stats` | Cumulative token savings per project across sessions |150151---152153## vs LSP154155LSP answers "where is this defined?" — `token-savior` answers "what breaks if I change it?"156157LSP is point queries: one symbol, one file, one position. It can find where `LLMClient` is defined and who references it directly. Ask "what breaks transitively if I refactor `LLMClient`?" and LSP has nothing — the AI would need to chain dozens of find-reference calls recursively, reading files at every step.158159`get_change_impact("TestCase")` on CPython finds 154 direct dependents and 492 transitive dependents in 0.45ms, returning 16K chars instead of reading 41M. And unlike LSP, it requires zero language servers — one binary covers Python + TS/JS + Go + Rust + C# + Markdown + JSON out of the box.160161---162163## Install164165```bash166git clone https://github.com/Mibayy/token-savior167cd token-savior168python3 -m venv ~/.local/token-savior-venv169~/.local/token-savior-venv/bin/pip install -e ".[mcp]"170```171172---173174## Configure175176### Claude Code / Cursor / Windsurf / Cline177178Add to `.mcp.json` in your project root:179180```json181{182 "mcpServers": {183 "token-savior": {184 "command": "/path/to/.local/token-savior-venv/bin/token-savior",185 "env": {186 "WORKSPACE_ROOTS": "/path/to/project1,/path/to/project2",187 "TOKEN_SAVIOR_CLIENT": "claude-code"188 }189 }190 }191}192```193194### Hermes Agent195196Add to `~/.hermes/config.yaml`:197198```yaml199mcp_servers:200 token-savior:201 command: ~/.local/token-savior-venv/bin/token-savior202 env:203 WORKSPACE_ROOTS: /path/to/project1,/path/to/project2204 TOKEN_SAVIOR_CLIENT: hermes205 timeout: 120206 connect_timeout: 30207```208209`TOKEN_SAVIOR_CLIENT` is optional but lets the live dashboard attribute savings by client.210211---212213## Make the agent actually use it214215AI assistants default to `grep` and `cat` even when better tools are available. Soft instructions get rationalized away. Add this to your `CLAUDE.md` or equivalent:216217```218## Codebase Navigation — MANDATORY219220You MUST use token-savior MCP tools FIRST.221222- ALWAYS start with: find_symbol, get_function_source, get_class_source,223 search_codebase, get_dependencies, get_dependents, get_change_impact224- Only fall back to Read/Grep when token-savior tools genuinely don't cover it225- If you catch yourself reaching for grep to find code, STOP226```227228---229230## Multi-project workspaces231232One server instance covers every project on the machine:233234```bash235WORKSPACE_ROOTS=/root/myapp,/root/mybot,/root/docs token-savior236```237238Each root gets its own isolated index, loaded lazily on first use. `list_projects` shows all registered roots. `switch_project` sets the active one.239240---241242## How it stays in sync243244The server checks `git diff` and `git status` before every query (~1-2ms). Changed files are re-parsed incrementally. No manual `reindex` after edits, branch switches, or pulls.245246The index is saved to `.codebase-index-cache.json` after every build — human-readable JSON, inspectable when things go wrong, safe across Python versions.247248---249250## Programmatic usage251252```python253from token_savior.project_indexer import ProjectIndexer254from token_savior.query_api import create_project_query_functions255256indexer = ProjectIndexer("/path/to/project")257index = indexer.index()258query = create_project_query_functions(index)259260print(query["get_project_summary"]())261print(query["find_symbol"]("MyClass"))262print(query["get_change_impact"]("send_message"))263```264265---266267## Development268269```bash270pip install -e ".[dev,mcp]"271pytest tests/ -v272ruff check src/ tests/273```274275---276277## Known limitations278279- **Live-editing window:** The index is git-aware and updates on query, not on save. If you edit a file and immediately call `get_function_source`, you may get the pre-edit version. The next git-tracked change triggers a re-index.280- **Cross-language tracing:** `get_change_impact` stops at language boundaries. Python calling a shell script calling a JSON config — the chain breaks after Python.281- **JSON value semantics:** The JSON annotator indexes key structure, not value meaning. Tracing what a config value propagates to across files is still manual.282283---284285<div align="center">286287**Works with any MCP-compatible AI coding tool.**288Claude Code · Cursor · Windsurf · Cline · Continue · Hermes · any custom MCP client289290</div>291
Full transparency — inspect the skill content before installing.