AiDex
About
Persistent code index using Tree-sitter for fast, precise code search. Replaces grep with ~50 token responses instead of 2000+.
Details
- Author
- cscsoftware
- Categories
- Developer Tools, Search
Jump to
Setup
Install AiDex in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/cscsoftware/AiDex
Follow the installation instructions in the repository README, then restart your MCP client.
The persistent brain for AI coding agents.
AiDex is an MCP server that gives AI coding assistants a memory, semantic search, and live telemetry β local-first, model-agnostic. Works with any MCP-compatible AI assistant: Claude Code, Claude Desktop, Cursor, Windsurf, Gemini CLI, VS Code Copilot, and more.
π§ Memoryβ Tasks, notes, and session-notes survive every chat. Auto-logged history, scheduled tasks, cross-session continuity. Your AI knows tomorrow what mattered today.
πSearchβ Three modes:exact(identifier),semantic(concept),hybrid(RRF fusion of both). Embeds code, docs, and workspace items into one ranking. Cross-project β every repo in one query. Optional LLM layer translates non-English queries and reranks results.
πTelemetryβ LogHub receives live logs from any app via HTTP (no SDK). The AI watches what your code actually does, not just what it says. Live-streamed in the Viewer.
What's Inside β 33 Tools in One Server
14 languagesβ C#, TypeScript, JavaScript, Rust, Python, C, C++, Java, Go, PHP, Ruby, HCL/Terraform, Kotlin, Swift β plus Astro frontmatter
# Find where "PlayerHealth" is defined β 1 call, ~50 tokens aidex_query({ term: "PlayerHealth" }) β Engine.cs:45, Player.cs:23, UI.cs:156 # All methods in a file β without reading the whole file aidex_signature({ file: "src/Engine.cs" }) β class GameEngine { Update(), Render(), LoadScene(), ... } # What changed in the last 2 hours? aidex_query({ term: "render", modified_since: "2h" }) # Search across ALL your projects at once aidex_global_query({ term: "TransparentWindow", mode: "contains" }) β Found in: LibWebAppGpu (3 hits), DebugViewer (1 hit) # Leave a note for your next session aidex_note({ path: ".", note: "Test the parser fix after restart" }) # Create a task while working aidex_task({ path: ".", action: "create", title: "Fix edge case in parser", priority: 1, tags: "bug" })
- What's Inside
- Semantic Search & LLM Layerπ
- The Problem
- The Solution
- Why Not Just Grep?
- How It Works
- Features
- Supported Languages
- Quick Start
- Available Tools
- Time-based Filtering
- Project Structure
- Session Notes
- Task Backlog
- Global Search
- AI Guidelines
- Log Hub
- Debug Dashboard
- Screenshots β LLM-Optimized
- Interactive Viewer
- CLI Usage
- Performance
- Technology
- Contributing
- License
v2.0added semantic search via locally-run embeddings β your AI can find a function even when it doesn't know the exact identifier.
Three modes β pick the right tool for the question
- Codeβ every method and type, three-tier chunking (signature + doc-comment + weighted identifier bag)
- Docsβ Markdown sections (README, CHANGELOG, docs/, plan files), split at heading boundaries
- Workspaceβ tasks, task logs, session notes, archived note history
One ranking, all kinds. A query like"how to write logs from external programs"surfaces the README's## Log Hubsection first, then thelogmethod incommands/log.ts, then any related task.
// Enable embeddings on a project (one-time, ~30s for AiDex itself, cached afterwards) aidex_init({ path: ".", embeddings: true }) // Search aidex_search({ query: "how do we batch requests to the LLM", path: "." }) aidex_search({ query: "retry with backoff", scope: "all" }) // across every embedded project
Or use theSettings tabin the Viewer (aidex_settings({ path: ".", open: true })) β toggles for embeddings, LLM provider, model, and the privacy switch.
When an Anthropic / OpenAI / OpenRouter / Ollama / HuggingFace API key is configured, AiDex can:
- Translatenon-English queries β "wie speichere ich Logs lokal" finds the right code
- Expandvague queries into 2-4 concrete subqueries (RRF-merged)
- Reranktop-N retrieval candidates
Privacy switchllm_send_codedefaults tooffβ only your literal query and metadata (paths, names, anchors) are sent. Code bodies stay local. Per-project, easy to verify in Settings.
Local-first: works fully offline with pure embeddings. The LLM layer is opt-in, never required.
Every time your AI assistant searches for code, it:
- Grepsthrough thousands of files β hundreds of results flood the context
- Readsfile after file to understand the structure β more context consumed
- Forgetseverything when the session ends β repeat from scratch
A single "Where is X defined?" question can eat 2,000+ tokens. Do that 10 times and you've burned half your context on navigation alone.
# Before: grep flooding your context AI: grep "PlayerHealth" β 200 hits in 40 files AI: read File1.cs, File2.cs, File3.cs... β 2000+ tokens consumed, 5+ tool calls # After: precise results, minimal context AI: aidex_query({ term: "PlayerHealth" }) β Engine.cs:45, Player.cs:23, UI.cs:156 β ~50 tokens, 1 tool call
Result: 50-80% less context used for code navigation.
The real cost of grep: Every grep result includes surrounding context. Search forUserin a large project and you'll get hundreds of hits - comments, strings, partial matches. Your AI reads through all of them, burning context tokens on noise.
AiDex indexes identifiers: It uses Tree-sitter to actually parse your code. When you search forUser, you get the class definition, the method parameters, the variable declarations - not every comment that mentions "user".
-
Index your project once(~1 second per 1000 files)
aidex_init({ path: "/path/to/project" })
AI searches the index instead of grepping
aidex_query({ term: "Calculate", mode: "starts_with" }) β All functions starting with "Calculate" + exact line numbers aidex_query({ term: "Player", modified_since: "2h" }) β Only matches changed in the last 2 hours
Get file overviews without reading entire files
aidex_signature({ file: "src/Engine.cs" }) β All classes, methods, and their signatures
The index lives in.aidex/index.db(SQLite) - fast, portable, no external dependencies.
- Tree-sitter Parsing: Real code parsing, not regex β indexes identifiers, ignores keywords and noise
- ~50 Tokens per Search: vs 2000+ with grep β your AI keeps its context for actual work
- Persistent Index: Survives between sessions β no re-scanning, no re-reading
- Incremental Updates: Re-index single files after changes, not the whole project
- Time-based Filtering: Find what changed in the last hour, day, or week
- Auto-Cleanup: Excluded files (e.g., build outputs) are automatically removed from index
- Zero Dependencies: SQLite with WAL mode β single file, fast, portable
- Node.js β₯ 20(check withnode --version)
- macOS:brew install nodeornvm install 20 && nvm use 20
- Linux: use your package manager ornvm
- Windows:nodejs.org
- If you usenvm, the repo ships a.nvmrcβnvm usepicks the right version automatically.
That's it.Setup runs automatically after install β it detects your installed AI clients (Claude Code, Claude Desktop, Cursor, Windsurf, Gemini CLI, VS Code Copilot) and registers AiDex as an MCP server. It also adds usage instructions to your AI's config (~/.claude/CLAUDE.md,~/.gemini/GEMINI.md).
To re-run setup manually:aidex setup| To unregister:aidex unsetup| To skip auto-setup:AIDEX_NO_SETUP=1 npm install -g aidex-mcp
2. Or register manually with your AI assistant
For Claude Code(~/.claude/settings.jsonor~/.claude.json):
{ "mcpServers": { "aidex": { "type": "stdio", "command": "aidex", "env": {} } } }
For Claude Desktop(%APPDATA%/Claude/claude_desktop_config.jsonon Windows):
{ "mcpServers": { "aidex": { "command": "aidex" } } }
Note:Bothaidexandaidex-mcpwork as command names.
Important:The server name in your config determines the MCP tool prefix. Use"aidex"as shown above β this gives you tool names likeaidex_query,aidex_signature, etc. Using a different name (e.g.,"codegraph") would change the prefix accordingly.
For Gemini CLI(~/.gemini/settings.json):
{ "mcpServers": { "aidex": { "command": "aidex" } } }
For VS Code Copilot(runMCP: Open User Configurationin Command Palette):
{ "servers": { "aidex": { "type": "stdio", "command": "aidex" } } }
For other MCP clients: See your client's documentation for MCP server configuration.
Add to your AI's instructions (e.g.,~/.claude/CLAUDE.mdfor Claude Code, or the equivalent for your AI client). This tells the AIwhen and howto use AiDex instead of grepping:
## AiDex - Persistent Code Index (MCP Server) AiDex provides fast, precise code search through a pre-built index. Always prefer AiDex over Grep/Glob for code searches. ### REQUIRED: Before using Grep/Glob/Read for code searches
Do I want to search code? βββ .aidex/ exists β STOP! Use AiDex instead βββ .aidex/ missing β run aidex_init (don't ask), THEN use AiDex βββ Config/Logs/Text β Grep/Read is fine
exactNEVER do this when .aidex/ exists: - βGrep pattern="functionName"β βaidex_query term="functionName"- βGrep pattern="class.Name"β βaidex_query term="Name" mode="contains"- βRead file.csto see methods β βaidex_signature file="file.cs"- βGlob pattern="/.cs"+ Read β βaidex_signatures pattern="/.cs"### Session-Start Rule (REQUIRED β every session, no exceptions) 1. Callaidex_session({ path: "<project>" })β detects external changes, auto-reindexes 2. If.aidex/does NOT exist β runaidex_initautomatically (don't ask) 3. If a session note exists β show it to the user before continuing 4. Before ending a session: always leave a note about what to do next ### Question β Right Tool | Question | Tool | |----------|------| | "Where is X defined?" |aidex_query term="X"| | "Find anything containing X" |aidex_query term="X" mode="contains"| | "All functions starting with X" |aidex_query term="X" mode="starts_with"| | "What methods does file Y have?" |aidex_signature file="Y"| | "Explore all files in src/" |aidex_signatures pattern="src/"| | "Project overview" |aidex_summary+aidex_tree| | "What changed recently?" |aidex_query term="X" modified_since="2h"| | "What files changed today?" |aidex_files path="." modified_since="8h"| | "Have I ever written X?" |aidex_global_query term="X" mode="contains"| | "Which project has class Y?" |aidex_global_signatures term="Y" kind="class"| | "All indexed projects?" |aidex_global_status| ### Search Modes -(default): Finds only the exact identifier βlogwon't matchcatalog-contains: Finds identifiers containing the term βrendermatchespreRenderSetup-starts_with: Finds identifiers starting with the term βUpdatematchesUpdatePlayer,UpdateUI### All Tools (30) | Category | Tools | Purpose | |----------|-------|---------| | Search & Index |aidex_init,aidex_query,aidex_update,aidex_remove,aidex_status| Index project, search identifiers (exact/contains/starts_with), time filter | | Signatures |aidex_signature,aidex_signatures| Get classes + methods without reading files | | Overview |aidex_summary,aidex_tree,aidex_describe,aidex_files| Entry points, file tree, file listing by type | | Cross-Project |aidex_link,aidex_unlink,aidex_links,aidex_scan| Link dependencies, discover projects | | Global Search |aidex_global_init,aidex_global_query,aidex_global_signatures,aidex_global_status,aidex_global_refresh| Search across ALL projects | | Guidelines |aidex_global_guideline| Persistent AI instructions & conventions (key-value, global) | | Sessions |aidex_session,aidex_note| Track sessions, leave notes (with searchable history) | | Tasks |aidex_task,aidex_tasks| Built-in backlog with priorities, tags, summaries, auto-logged history, scheduled/recurring tasks | | Log Hub |aidex_log| Universal log receiver β any program sends logs via HTTP, AI queries them, live in Viewer | | Screenshots |aidex_screenshot,aidex_windows| Screen capture with LLM optimization (scale + color reduction, no index needed) | | Viewer |aidex_viewer| Interactive browser UI with file tree, signatures, tasks, and live logs | 14 languages: C#, TypeScript, JavaScript, Rust, Python, C, C++, Java, Go, PHP, Ruby, HCL/Terraform, Kotlin, Swift β plus Astro frontmatter ### Session Notes Leave notes for the next session β they persist in the database:
aidex_note({ path: ".", note: "Test the fix after restart" }) # Write aidex_note({ path: ".", note: "Also check edge cases", append: true }) # Append aidex_note({ path: "." }) # Read aidex_note({ path: ".", search: "parser" }) # Search history aidex_note({ path: ".", clear: true }) # Clear
- Before ending a session: automatically leave a note about next steps - User says "remember for next session: ..." β write it immediately ### Task Backlog Track TODOs, bugs, and features right next to your code index:
aidex_task({ path: ".", action: "create", title: "Fix bug", priority: 1, tags: "bug" }) aidex_task({ path: ".", action: "update", id: 1, status: "done" }) aidex_task({ path: ".", action: "log", id: 1, note: "Root cause found" }) aidex_tasks({ path: ".", status: "active" })
aidex_task({ path: ".", action: "create", title: "Check PR status", due: "3d", interval: "3d", task_action: "gh pr list" })
Priority: 1=high, 2=medium, 3=low | Status: backlog β active β done | cancelled ### Global Search (across all projects)
aidex_global_init({ path: "/path/to/all/repos" }) # Scan & register aidex_global_init({ path: "...", index_unindexed: true }) # + auto-index small projects aidex_global_query({ term: "TransparentWindow", mode: "contains" }) # Search everywhere aidex_global_signatures({ term: "Render", kind: "method" }) # Find methods everywhere aidex_global_status({ sort: "recent" }) # List all projects
aidex_screenshot() # Full screen aidex_screenshot({ mode: "active_window" }) # Active window aidex_screenshot({ mode: "window", window_title: "VS Code" }) # Specific window aidex_screenshot({ scale: 0.5, colors: 2 }) # B&W, half size (ideal for LLM) aidex_screenshot({ colors: 16 }) # 16 colors (UI readable) aidex_windows({ filter: "chrome" }) # Find window titles
No index needed. Returns file path β use Read to view immediately. LLM optimization strategy: Always start with aggressive settings, then retry if unreadable: 1. First try: scale: 0.5, colors: 2 (B&W, half size β smallest possible) 2. If unreadable: retry with colors: 16 (adds shading for UI elements) 3. If still unclear: scale: 0.75 or omit colors for full quality 4. Remember what works for each window/app during the session β don't retry every time.
Ask your AI:"Index this project with AiDex"
aidex_init({ path: "/path/to/your/project" })
Track what changed recently withmodified_sinceandmodified_before:
aidex_query({ term: "render", modified_since: "2h" }) # Last 2 hours aidex_query({ term: "User", modified_since: "1d" }) # Last day aidex_query({ term: "API", modified_since: "1w" }) # Last week
- Relative:30m(minutes),2h(hours),1d(days),1w(weeks)
- ISO date:2026-01-27or2026-01-27T14:30:00
Perfect for questions like"What did I change in the last hour?"
AiDex indexes ALL files in your project (not just code), letting you query the structure:
aidex_files({ path: ".", type: "config" }) # All config files aidex_files({ path: ".", type: "test" }) # All test files aidex_files({ path: ".", pattern: "/.md" }) # All markdown files aidex_files({ path: ".", modified_since: "30m" }) # Changed this session
File types:code,config,doc,asset,test,other,dir
Usemodified_sinceto find files changed in this session - perfect for"What did I edit?"
Leave reminders for the next session - no more losing context between chats:
aidex_note({ path: ".", note: "Test the glob fix after restart" }) # Write aidex_note({ path: ".", note: "Also check edge cases", append: true }) # Append aidex_note({ path: "." }) # Read aidex_note({ path: ".", clear: true }) # Clear
Note History(v1.10): Old notes are automatically archived when overwritten or cleared. Browse and search past notes:
aidex_note({ path: ".", history: true }) # Browse archived notes (shows summaries) aidex_note({ path: ".", search: "parser" }) # Search note history (searches summaries too) aidex_note({ path: ".", history: true, limit: 5 }) # Last 5 archived notes
Note Summaries(v1.15): Provide asummarywhen writing/clearing a note β the archived note gets this one-sentence description. History then shows summaries instead of truncated text:
aidex_note({ path: ".", note: "New focus", summary: "Previous session: finished parser refactoring" })
- Before ending a session:"Remember to test X next time"
- AI auto-reminder: Save what to verify after a restart
- Handover notes: Context for the next session without editing config files
- Search past sessions:"What did we do about the parser?"
Notes are stored in the SQLite database (.aidex/index.db) and persist indefinitely.
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.




