The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the AiDex listing page.
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.

| Without AiDex | With AiDex | |
|---|---|---|
Find PlayerHealth | Grep → 200 hits in 40 files → reads 5 files → 2,000+ tokens | 1 query → 3 exact locations → ~50 tokens |
| Get file structure | Reads entire 500-line file → 1,500 tokens | Signatures → classes + methods → ~80 tokens |
| What changed today? | git diff + grep + context → 3,000+ tokens | Time-filtered query → ~50 tokens |

| Category | Tools | What it does |
|---|---|---|
| Semantic Search 🆕 | search, settings | Hybrid / semantic / exact retrieval over code, docs & workspace. Settings tab to configure embeddings + LLM layer |
| Index & Identifier Search | init, query, update, remove, status | Index your project, search identifiers by name (exact/contains/starts_with), time-based filtering |
| Signatures | signature, signatures | Get classes + methods of any file without reading it — single file or glob pattern |
| Project Overview | summary, tree, describe, files | Entry points, language breakdown, file tree with stats, file listing by type |
| Cross-Project | link, unlink, links, scan | Link dependencies, discover indexed projects |
| Global Search | global_init, global_query, global_signatures, global_status, global_refresh | Search identifiers across ALL your projects — "Have I ever written X?" |
| Guidelines | global_guideline | Persistent AI instructions & coding conventions — shared across all projects |
| Sessions | session, note | Track sessions, detect external changes, leave notes for next session (with searchable history) |
| Task Backlog | task, tasks | Built-in task management with priorities, tags, auto-logged history, and scheduled/recurring tasks |
| Log Hub | log | Universal log receiver — any program sends logs via HTTP, queryable by the AI, live in Viewer |
| Screenshots | screenshot, windows | Cross-platform screen capture with LLM optimization — scale + color reduction saves up to 95% tokens |
| Viewer | viewer | Interactive browser UI with file tree, signatures, tasks, logs, search, and live reload |
14 languages — C#, TypeScript, JavaScript, Rust, Python, C, C++, Java, Go, PHP, Ruby, HCL/Terraform, Kotlin, Swift — plus Astro frontmatter
v2.0 added semantic search via locally-run embeddings — your AI can find a function even when it doesn't know the exact identifier.
| Mode | What it does | When to use |
|---|---|---|
exact | Identifier match (same as aidex_query) | You know the name. PlayerHealth → 3 hits |
semantic | Vector KNN over embedded code+docs+workspace | You know the concept. "how do we cache the model" → finds getQueryEmbedder |
hybrid (default) | RRF fusion of both | Mixed queries. Robust by default |
One ranking, all kinds. A query like "how to write logs from external programs" surfaces the README's ## Log Hub section first, then the log method in commands/log.ts, then any related task.
Or use the Settings tab in 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:
Privacy switch llm_send_code defaults to off — 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:
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.
Index once, query forever:
Result: 50-80% less context used for code navigation.
| Grep/Ripgrep | AiDex | |
|---|---|---|
| Context usage | 2000+ tokens per search | ~50 tokens |
| Results | All text matches | Only identifiers |
| Precision | log matches catalog, logarithm | log finds only log |
| Persistence | Starts fresh every time | Index survives sessions |
| Structure | Flat text search | Knows methods, classes, types |
The real cost of grep: Every grep result includes surrounding context. Search for User in 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 for User, 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)
AI searches the index instead of grepping
Get file overviews without reading entire files
The index lives in .aidex/index.db (SQLite) - fast, portable, no external dependencies.
| Language | Extensions |
|---|---|
| C# | .cs |
| TypeScript | .ts, .tsx |
| JavaScript | .js, .jsx, .mjs, .cjs |
| Rust | .rs |
| Python | .py, .pyw |
| C | .c, .h |
| C++ | .cpp, .cc, .cxx, .hpp, .hxx |
| Java | .java |
| Go | .go |
| PHP | .php |
| Ruby | .rb, .rake |
| HCL/Terraform | .tf, .tfvars, .hcl |
| Kotlin | .kt, .kts |
| Swift | .swift |
| Astro | .astro (TypeScript frontmatter) |
node --version)
brew install node or nvm install 20 && nvm use 20nvm, the repo ships a .nvmrc — nvm use picks 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
For Claude Code (~/.claude/settings.json or ~/.claude.json):
For Claude Desktop (%APPDATA%/Claude/claude_desktop_config.json on Windows):
Note: Both
aidexandaidex-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):
For VS Code Copilot (run MCP: Open User Configuration in Command Palette):
For other MCP clients: See your client's documentation for MCP server configuration.
Add to your AI's instructions (e.g., ~/.claude/CLAUDE.md for Claude Code, or the equivalent for your AI client). This tells the AI when and how to use AiDex instead of grepping:
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
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
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" })
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
Ask your AI: "Index this project with AiDex"
Or manually in the AI chat:
| Tool | Description |
|---|---|
aidex_init | Index a project (creates .aidex/) |
aidex_query | Search by term (exact/contains/starts_with) |
aidex_signature | Get one file's classes + methods |
aidex_signatures | Get signatures for multiple files (glob) |
aidex_update | Re-index a single changed file |
aidex_remove | Remove a deleted file from index |
aidex_summary | Project overview |
aidex_tree | File tree with statistics |
aidex_describe | Add documentation to summary |
aidex_link | Link another indexed project |
aidex_unlink | Remove linked project |
aidex_links | List linked projects |
aidex_status | Index statistics |
aidex_scan | Find indexed projects in directory tree |
aidex_files | List project files by type (code/config/doc/asset) |
aidex_note | Read/write session notes (persists between sessions) |
aidex_session | Start session, detect external changes, auto-reindex |
aidex_viewer | Open interactive project tree in browser |
aidex_task | Create, read, update, delete tasks with priority and tags |
aidex_tasks | List and filter tasks by status, priority, or tag |
aidex_screenshot | Take a screenshot (fullscreen, window, region) with optional scale + color reduction |
aidex_windows | List open windows for screenshot targeting |
aidex_global_init | Scan directory tree, register all indexed projects in global DB |
aidex_global_status | List all registered projects with stats |
aidex_global_query | Search terms across ALL registered projects |
aidex_global_signatures | Search methods/types by name across all projects |
aidex_global_refresh | Update stats and remove stale projects from global DB |
aidex_global_guideline | Store/retrieve AI guidelines and coding conventions (key-value, global) |
aidex_log | Universal log receiver — start HTTP server, query logs, live stream in Viewer |
Track what changed recently with modified_since and modified_before:
Supported formats:
30m (minutes), 2h (hours), 1d (days), 1w (weeks)2026-01-27 or 2026-01-27T14:30:00Perfect 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:
File types: code, config, doc, asset, test, other, dir
Use modified_since to find files changed in this session - perfect for "What did I edit?"
Leave reminders for the next session - no more losing context between chats:
Note History (v1.10): Old notes are automatically archived when overwritten or cleared. Browse and search past notes:
Note Summaries (v1.15): Provide a summary when writing/clearing a note — the archived note gets this one-sentence description. History then shows summaries instead of truncated text:
Use cases:
Notes are stored in the SQLite database (.aidex/index.db) and persist indefinitely.
Keep your project tasks right next to your code index - no Jira, no Trello, no context switching:
Tasks can have due dates and repeat intervals. Overdue tasks are reported at every session start across ALL projects:
Due formats: Relative ("30m", "2h", "3d", "1w") or ISO date ("2026-04-10")
At every aidex_session call, the Task Scheduler checks ~/.aidex/global.db for due tasks across all projects — even if you're working on a different project. Recurring tasks automatically advance their due date after each trigger.
Features:
backlog → active → done | cancelledbug, feature, docs, etc.).aidex/index.dbYour AI assistant can create tasks while working ("found a bug in the parser, add it to the backlog"), track progress, and pick up where you left off next session.
Search across ALL your indexed projects at once. Perfect for "Have I ever written a transparent window?" or "Where did I use that algorithm?"
This scans your project directory, registers all AiDex-indexed projects in a global database (~/.aidex/global.db), and reports any unindexed projects it finds by detecting project markers (.csproj, package.json, Cargo.toml, etc.).
With index_unindexed: true, it also auto-indexes all discovered projects with ≤500 code files. Larger projects are listed separately for user decision. Add show_progress: true to open a live progress UI in your browser (http://localhost:3334).
ATTACH DATABASE to query project databases directly — no data copying.aidex/index.db as the single source of truthMyApp/ is removed when MyApp/Frontend/ and MyApp/Backend/ exist as separate indexed projects)Store persistent coding conventions, review checklists, and AI instructions in a single place — shared across all projects.
Use cases:
Guidelines are stored in ~/.aidex/global.db — available across all your projects without aidex_init. Ask your AI: "Load the review guideline and apply it to this file."
Turn any program into a log source for your AI assistant. Your app sends logs via HTTP POST, the AI queries them via MCP, and you see them live in the Viewer — zero dependencies, zero setup in your code.
aidex_log({ action: "init" })aidex_viewer({ path: "." }) — Logs tab shows live stream| Endpoint | Method | Body | Description |
|---|---|---|---|
/log | POST | { level, source, message, data? } | Single log entry |
/logs | POST | [{ ... }, ...] | Batch (multiple at once) |
/health | GET | — | Status + buffer usage |
Fields: level (debug/info/warn/error), source (app name), message (text, required), data (optional JSON), timestamp (optional, ms)
init is calledpersist: true)query with consume: true removes returned entries — ideal for pollingLogs and dashboard widgets flow app → AI. The Control API is the return channel: AI → app. It turns the Log Hub into a tiny, zero-dependency command bus — so an AI assistant can drive any running program without you writing a server.
The AI sets a command; your app polls for it, runs it, and posts the result back:
control_set { id, value } — the AI (or a Viewer slider/switch) sets a control slot.GET /control — your app reads all current control values.POST /control — your app writes back results / acknowledgements.POST /control/press { id } — registers one press of a button control. The hub owns the counter, so presses from several open dashboards add up instead of overwriting each other.control_get — the AI reads what the app reported.A
buttonvalue is a press counter, not a flag — your app polls at its own pace, so compare against the last count you saw rather than testing for "pressed". Any backwards jump means the hub restarted or the panel was cleared: adopt the value, don't read it as a million presses.
Two slots by convention give you full request/response: a *_cmd slot the AI writes, a *_result slot the app writes, and an *_ack counter so each command runs exactly once (bump the command id every time; the app skips any id it has already handled).
That's the whole protocol. A client needs nothing but an HTTP library you already have.
A ~30-line Fusion 360 add-in (urllib only, no SDK) polls GET /control, executes the command on Fusion's main thread, and posts the result back. With nothing else, an AI assistant drove Fusion to parametrically design a complete 3D enclosure — sketches, extrusions, screw-boss domes with heat-set inserts, USB-C cut-outs, reset/button holes — verifying every step by reading back the actual face geometry.
The pattern is universal: anything that can POST and GET — Blender, a CNC controller, a game, a home-automation hub — becomes AI-steerable with a few lines and no bespoke server. Two safety rules carry over from that build:
id and ack it — polling means you'll see the same command repeatedly, so skip what you've already done.The scrolling log stream is great for what happened when — but useless for fast, repeating values (audio levels, buffer fill, FPS, sensor readings). The Debug Dashboard is the opposite: a fixed-slot panel where each value has a permanent spot and overwrites in place instead of scrolling away. Live in the Viewer's Live tab, styled like a hardware monitor (MSI Afterburner / HWiNFO).
It rides on the same Log Hub server — no extra setup. Your program sends widget updates via HTTP POST; sending the same id again updates that widget.
| Type | Looks like | Use for |
|---|---|---|
label | big value + unit | FPS, state text, counters |
progress | bar with warn/crit colouring | buffer fill, percentages |
gauge | radial tachometer (or status LED for strings) | temperature, load, ok/warn/error |
plot | real-time line graph with grid + min/max/avg | audio signal, latency, any time series |
Fields: id (required), type (label/progress/gauge/plot/slider/number/toggle/button, required on first send), value (number, status string, or number array for a full plot frame), group, label, unit, min, max, warn, crit, color, order.
Endpoints: POST /panel (one), POST /panels (batch), POST /panel/clear ({id} for one, empty for all).
id, so a freshly-opened or reloaded Viewer shows the whole dashboard immediately.type again (plain value-only updates to a cleared id are ignored).A ready-to-run showcase animates all widget types (audio waveform, GPU gauges drifting through their zones, a signal generator cycling sine → sawtooth → triangle → square, latency spikes):
Or use the ▷ Demo button on the Live tab — it copies the run command to your clipboard; paste it into a terminal. (The browser can't spawn a process itself.) It sits in the toolbar even while the dashboard is still empty, since it's how you get your first widgets. scripts/demo-dashboard.ps1 is a one-command launcher that checks the Log Hub first.
Running it twice starts two instances that fight over the same widgets (visible flicker) — stop the old one (Ctrl+C) before starting another.
Take screenshots and reduce them up to 95% for LLM context. A typical screenshot goes from ~100 KB to ~5 KB — that's thousands of tokens saved per image.
| Raw Screenshot | Optimized (scale=0.5, colors=2) | |
|---|---|---|
| File size | ~100-500 KB | ~5-15 KB |
| Tokens consumed | ~5,000-25,000 | ~250-750 |
| Text readable? | Yes | Yes |
| Colors | 16M (24-bit) | 2 (black & white) |
Most screenshots in AI context are for reading text — error messages, logs, UI labels. You don't need 16 million colors for that.
| Parameter | Values | Description |
|---|---|---|
scale | 0.1 - 1.0 | Scale factor (0.5 = half resolution). Most HiDPI screens are 2-3x anyway. |
colors | 2, 4, 16, 256 | Color reduction. 2 = black & white, ideal for text screenshots. |
The tool description tells LLMs to optimize automatically:
scale: 0.5, colors: 2 (smallest possible)colors: 16 (adds shading for UI elements)scale: 0.75 or full colorThis way the AI learns the right settings per app without wasting tokens on oversized images.
.aidex/ neededExplore your indexed project visually in the browser:
Opens http://localhost:3333 with:
/control channelThe Live tab is a live dashboard with fixed slots: send the same id again and the value updates in place instead of scrolling away. Interactive slider/number/toggle/button widgets flow back to the source (HTTP /control, or aidex_log control_set so the AI can tune a running program too). A button carries a press counter, not a flag, so a source polling at its own pace never misses a click. Full guide: docs/loghub-panel-dashboard.md.

The Controls group holds one of each interactive type: a slider, two toggles, and a button with its press counter beside it. Scrolled further down, several sources share the same dashboard — the hub knows nothing about what any value means, so a synth firmware and a demo script coexist without either being aware of the other:

The sliders react in real time — watch the GIF:







Close with aidex_viewer({ path: ".", action: "close" })
aidex-mcpworks as an alias foraidex.
| Project | Files | Items | Index Time | Query Time |
|---|---|---|---|---|
| Small (AiDex) | 19 | 1,200 | <1s | 1-5ms |
| Medium (RemoteDebug) | 10 | 1,900 | <1s | 1-5ms |
| Large (LibPyramid3D) | 18 | 3,000 | <1s | 1-5ms |
| XL (MeloTTS) | 56 | 4,100 | ~2s | 1-10ms |
GitHub Discussions — Ask questions, share your setup, suggest ideas.
| Category | For |
|---|---|
| Q&A | Setup help, usage questions |
| Ideas | Feature suggestions |
| Show & Tell | Share your workflow |
| Announcements | Release news (maintainer only) |
See CONTRIBUTING.md for full details. Quick summary:
src/parser/languages/ and open a PRMIT License - see LICENSE
Uwe Chalas & Claude