Skip to main content

Repo-local code intelligence for AI coding agents - symbols, semantic search, call graphs, routes, and token savings

Project description

SymDex icon

SymDex

The codebase oracle AI coding agents wish every repo already had.

Index once. Jump straight to the exact symbol, route, caller, callee, or file slice. Read only what you need.


PyPI Downloads Python License Stars


Cursor Codex Gemini Copilot Windsurf Roo Kilo


7,500 tokens -> 200 tokens

Per lookup. Every lookup. Approximate, but directionally real.

SymDex hero visual showing token reduction and code intelligence workflow

# Install the lean core
pip install symdex

# Add local semantic search when you want the sentence-transformers backend
pip install "symdex[local]"

# Or install the local-backend CLI as an isolated tool
uv tool install "symdex[local]"

# Or run without installing
uvx symdex --help

# Upgrade an existing install
py -m pip install -U symdex
uv tool upgrade symdex
uvx symdex@latest --help

# Install the SymDex agent skill globally for supported agents
npx skills add https://github.com/husnainpk/SymDex --skill symdex-code-search --yes --global

What SymDex Does

AI coding agents are useful until they have to rediscover your repo from scratch. They open whole files, grep broad patterns, miss the route handler, read the same utility twice, and spend thousands of tokens just getting oriented.

SymDex gives agents a repo-local retrieval layer before they start reading code.

It indexes your project into a small local SQLite knowledge base with:

  • exact symbols and byte offsets
  • file outlines and repo summaries
  • literal text search
  • optional semantic search
  • callers, callees, and circular dependency checks
  • extracted HTTP routes
  • a registry for one repo, many repos, or many worktrees

Then agents can ask for the narrow slice they need: the function, route, caller chain, file outline, or intent match. That means less blind browsing, less context waste, and answers that can explain how much token budget SymDex saved.

SymDex is local-first. Base symdex keeps symbol, text, route, graph, and MCP features lean. Install symdex[local] only when you want local semantic embeddings, or point the hosted backend at Voyage, OpenAI-compatible services, Gemini, or a compatible proxy when you want remote embeddings.

Current product stage as of April 18, 2026:

  • package version 0.1.25; latest public tag v0.1.25
  • 20 MCP tools across indexing, search, outlines, routes, stats, graphs, cache invalidation, and stale-index cleanup
  • 21 language surfaces, including HTML, CSS, Shell, Svelte, Markdown headings, and supported fenced code blocks
  • Android, Flutter, and iOS coverage through Kotlin, Dart, and Swift parser targets
  • route extraction across Python, JavaScript/TypeScript, Spring/Kotlin, Laravel, Gin-style Go, ASP.NET, Rails/Sinatra, Phoenix, and Actix
  • one-line CLI token-savings footers after successful search commands
  • MCP roi, roi_summary, and roi_agent_hint fields so agents can mention savings in their final response
  • semantic backends for local sentence-transformers, Voyage, OpenAI-compatible /embeddings, and Gemini Embedding
  • SYMDEX_EMBED_RPM request pacing for hosted embedding providers
  • symdex index --lazy for fast foreground structural indexing while embeddings build in a background watcher
  • low-memory symdex watch by default: structural refresh without loading embedding models unless --embed is passed
  • duplicate watcher protection, idle auto-exit, and state-aware watcher metadata
  • workspace-local ./.symdex state for Docker, portable workspaces, and teams that do not want indexes hidden in home directories
  • upgrade notices with exact pip, uv tool, and uvx commands when a newer release exists

SymDex Skill For Agents

Install the SymDex code-search skill to make agents use SymDex before broad file browsing:

npx skills add https://github.com/husnainpk/SymDex --skill symdex-code-search --yes --global

If you want the interactive installer instead, omit --yes --global.

What it does:

  • checks repo/index readiness first
  • uses SymDex before Read/Grep/Glob for discovery
  • prefers symbol-level and outline-level retrieval over full-file reads
  • guides agents toward callers, callees, routes, and semantic search when those are the better fit
  • keeps the workflow centered on lower-token code retrieval instead of broad file reads

The skill lives in this repo at skills/symdex-code-search/SKILL.md and follows the standard skills/<name>/SKILL.md layout.

Installing through the skills CLI uses the same public path that skills.sh indexes.


60-second quickstart

# Install the lean core
pip install symdex
# or
uv tool install symdex

# Index a project
symdex index ./myproject --repo myproject

# Search by symbol name
symdex search "validate_email" --repo myproject

# Search by literal text
symdex text "JWT" --repo myproject

# Add local semantic search only when you want embeddings
pip install "symdex[local]"

# Search by intent
symdex semantic "check email format" --repo myproject

# Show HTTP routes
symdex routes myproject -m POST

# Start the MCP server
symdex serve

Notes:

  • If you omit --repo on symdex index or symdex watch, SymDex auto-generates a stable repo id from the current git branch and worktree path hash.
  • After indexing, SymDex prints a code summary.
  • After successful search commands, SymDex prints a one-line ROI footer with approximate token savings.
  • MCP search tools also return roi_agent_hint, so agents can fold the savings into their user-facing response instead of burying it in logs.
  • When a newer PyPI release exists, normal CLI commands print exact upgrade commands for pip, uv tool, and uvx.
  • Set SYMDEX_STATE_DIR=.symdex on first index to keep repo databases, registry.db, and registry.json inside the current workspace. After that, commands run from the workspace auto-discover the local state.
  • --state-dir can be passed either globally or after the subcommand, for example symdex --state-dir .symdex repos or symdex repos --state-dir .symdex.
  • Canonical CLI commands are index and repos. Shell compatibility aliases also accept MCP-shaped names like index-folder, index-repo, and list-repos.
  • Semantic search requires stored embeddings. If a repo was indexed before the backend you want was enabled, re-index it with symdex index, symdex index --lazy, or symdex watch --embed.

Add to your agent config:

{
  "mcpServers": {
    "symdex": {
      "command": "uvx",
      "args": ["symdex", "serve"]
    }
  }
}

HTTP mode:

{
  "mcpServers": {
    "symdex": {
      "url": "http://localhost:8080/mcp"
    }
  }
}

Workspace-local state and Docker

SymDex defaults to ~/.symdex and also supports a workspace-local state directory for portable and containerized workflows.

Use it like this on first setup:

SYMDEX_STATE_DIR=.symdex symdex index ./myproject --repo myproject

That creates:

  • ./.symdex/<repo>.db
  • ./.symdex/registry.db
  • ./.symdex/registry.json

registry.json is the human-readable manifest. In workspace-local mode it stores relative root_path and db_path values, so you can inspect what is indexed without opening SQLite.

After the local state exists, SymDex auto-discovers it from the current workspace or any nested subdirectory.


What you get

SymDex feature grid showing core capabilities including semantic search, byte-precise extraction, call graph, routes, cross-repo registry, watch mode, and CLI plus MCP tools

Feature Details
Symbol search Find functions, classes, and methods with exact byte offsets
Semantic search Find code by intent instead of exact name
Text search Search indexed files by literal text across the repo
Byte-precise retrieval Read only the symbol span you need
File outline List symbols in a file without transferring the whole file
Repo outline Get a directory tree plus repo summary through MCP
Call graph Trace callers, callees, and circular dependencies
HTTP routes Extract Flask, FastAPI, Django, Express, Spring/Kotlin, Laravel, Gin-style Go, ASP.NET, Rails/Sinatra, Phoenix, and Actix routes
Markdown-aware docs Index Markdown headings and supported fenced code blocks for SDK docs, specs, repo docs, and design notes
Auto-watch Re-index on change, avoid duplicate watchers, stay low-memory by default, and auto-exit after idle time
Cross-repo registry Manage multiple indexed repos from one local registry
Workspace-local state Keep repo databases, registry.json, and watcher metadata inside ./.symdex for Docker and portable workspaces
Search ROI footer One-line approximate token savings after successful search commands
Agent ROI hint MCP tools return roi_agent_hint so agents can mention savings naturally in their replies
Code summary Files, Lines of Code, symbols, routes, skipped files, and languages after indexing
Optional embedding backends Use local embeddings, Voyage, OpenAI-compatible /embeddings, Gemini, or a compatible proxy only when needed

Where SymDex Fits

SymDex is built for agents that need precise repo-local retrieval without depending on an editor session, hosted index, or heavyweight service stack.

Approach Strong at Tradeoff Where SymDex differs
Editor-bound LSPs type-aware navigation and refactors inside the editor tied to an editor session and weak on intent search pre-indexed, terminal-first, semantic, and route-aware
LSP wrappers for agents deeper language-server-backed analysis heavier per-language setup and live-file coupling one SQLite index per repo and the same interface across repos
Graph-backed code indexers graph-style architecture queries extra backend/storage complexity zero-infra local storage with SQLite
Docker-heavy hybrid search stacks chunked semantic search with external services more moving parts at install and runtime local-first workflow with simple CLI and MCP setup
SymDex fast repo-local symbol, text, semantic, route, and call-graph retrieval not a full type checker or automated refactoring engine optimized for precise retrieval and agent efficiency

If you need full type-system reasoning or editor-native refactors, a language server still goes deeper. If you need pre-indexed retrieval, repo-local portability, and an MCP-friendly search layer, SymDex is the better fit.


CLI reference

# Indexing and maintenance
symdex index ./myproject --repo myproject       # Index with an explicit repo id
symdex index ./myproject                        # Auto-name from git branch + path hash
symdex index ./myproject --repo myproject --no-embed  # Skip semantic embedding work
symdex index ./myproject --repo myproject --lazy      # Index code now, embed in a background watcher
symdex watch ./myproject --repo myproject       # Keep an index fresh without loading embedding models
symdex watch ./myproject --repo myproject --embed  # Also refresh semantic embeddings on change
symdex invalidate --repo myproject              # Force re-index of a repo
symdex invalidate --repo myproject --file app.py
symdex gc                                       # Remove stale index databases
symdex repos                                    # List indexed repos

# Search
symdex search "validate_email" --repo myproject
symdex search "validate_email"                 # Search across all indexed repos
symdex find validate_email --repo myproject     # Exact lookup
symdex text "JWT" --repo myproject
symdex semantic "check auth token" --repo myproject

# Navigation
symdex outline auth/utils.py --repo myproject
symdex callers validate_email --repo myproject
symdex callees validate_email --repo myproject
symdex routes myproject
symdex routes myproject --method POST
symdex routes myproject --path /api

# Server
symdex serve
symdex serve --port 8080

MCP currently exposes additional repo-tree and repo-stats views that are not surfaced as dedicated CLI commands: get_file_tree, get_repo_outline, get_index_status, and get_repo_stats.


MCP tools

SymDex currently exposes 20 MCP tools:

Tool Purpose
index_folder Index a local folder and return indexing statistics
index_repo Index a repo and register it in the central registry
search_symbols Find functions, classes, and methods by name
semantic_search Find symbols by meaning using embedding similarity
search_text Search indexed files by text and return matching lines
get_symbol Read one symbol by byte offsets
get_symbols Bulk exact-name symbol lookup
get_file_outline List symbols in a single file
get_file_tree Return a directory tree without file contents
get_repo_outline Return a repo tree plus summary stats
get_callers Return symbols that call a named function
get_callees Return symbols called by a named function
search_routes Query extracted HTTP routes
get_index_status Return symbol count, file count, Lines of Code, staleness, and watcher state
get_repo_stats Return repo metrics such as language mix, fan-in, fan-out, and circular dependency count
get_graph_diagram Generate a Mermaid call graph
find_circular_deps Detect circular dependencies
list_repos List all indexed repos
invalidate_cache Force re-index on next use
gc_stale_indexes Remove index databases for repos that no longer exist on disk

Supported languages

Language Extensions
Python .py
JavaScript .js, .jsx, .mjs, .cjs, .cjsx, .mjsx
TypeScript .ts, .tsx, .mts, .cts, .mtsx, .ctsx
Go .go
Rust .rs
Java .java
Kotlin .kt, .kts
Dart .dart
Swift .swift
PHP .php
C# .cs
C .c
C++ .h, .hh, .hpp, .hxx, .cpp, .cc, .cxx
HTML .html, .htm
CSS .css, .scss, .sass, .less, .stylus, .styl
Shell .sh, .bash, .zsh
Elixir .ex, .exs
Ruby .rb
Vue .vue script blocks parsed as JavaScript or TypeScript
Svelte .svelte script blocks parsed as JavaScript or TypeScript
Markdown .md, .markdown, .mdx headings plus supported fenced code blocks

Powered by tree-sitter for code, language-pack grammar fallbacks, and a native Markdown scanner for headings and fenced code examples.


Supported platforms

SymDex works with any MCP client that supports stdio or streamable HTTP.

Platform Typical setup
Codex CLI Add to MCP settings
Gemini CLI Add to MCP settings
Cursor .cursor/mcp.json
Windsurf Add to MCP settings
GitHub Copilot .vscode/mcp.json
Roo Add to MCP settings
Continue.dev config.json
Cline Add to MCP settings
Kilo Code VS Code MCP settings
Zed Add to MCP settings
OpenCode opencode.json
Any MCP client uvx symdex serve or symdex serve --port 8080

Semantic embedding backends

Base symdex installs the lean core only. Choose the embedding extra that matches how you want semantic search to work:

  • symdex[local] for local sentence-transformers
  • symdex[voyage] for Voyage text embeddings
  • symdex[voyage-multimodal] for Voyage text plus images and PDFs

Remote OpenAI-compatible and Gemini backends use the Python standard library HTTP client, so they do not add a required dependency.

Local mode

pip install "symdex[local]"

SYMDEX_EMBED_BACKEND=local \
SYMDEX_EMBED_MODEL=all-MiniLM-L6-v2 \
symdex index . --repo myrepo

Voyage text mode

pip install "symdex[voyage]"

SYMDEX_EMBED_BACKEND=voyage \
VOYAGE_API_KEY=... \
SYMDEX_VOYAGE_MODEL=voyage-code-3 \
symdex index . --repo myrepo

SYMDEX_EMBED_BACKEND=voyage \
VOYAGE_API_KEY=... \
symdex semantic "parse source code" --repo myrepo

OpenAI-compatible mode

Use this for OpenAI, local OpenAI-compatible servers, and proxy services that expose POST /embeddings.

SYMDEX_EMBED_BACKEND=openai \
SYMDEX_EMBED_BASE_URL=https://api.openai.com/v1 \
SYMDEX_EMBED_MODEL=text-embedding-3-small \
SYMDEX_EMBED_API_KEY=... \
SYMDEX_EMBED_RPM=60 \
symdex index . --repo myrepo --lazy

For a local or proxy provider, set SYMDEX_EMBED_BACKEND=custom, point SYMDEX_EMBED_BASE_URL at its /v1 base URL, and set the model name it expects. If the provider does not need an API key, omit SYMDEX_EMBED_API_KEY.

Gemini mode

Gemini uses RETRIEVAL_DOCUMENT when indexing and RETRIEVAL_QUERY when searching.

SYMDEX_EMBED_BACKEND=gemini \
GEMINI_API_KEY=... \
SYMDEX_EMBED_MODEL=text-embedding-004 \
SYMDEX_EMBED_RPM=60 \
symdex index . --repo myrepo --lazy

Voyage multimodal mode

pip install "symdex[voyage-multimodal]"

SYMDEX_EMBED_BACKEND=voyage
SYMDEX_VOYAGE_MULTIMODAL=1
VOYAGE_API_KEY=...
SYMDEX_VOYAGE_MULTIMODAL_MODEL=voyage-multimodal-3.5
symdex index . --repo myrepo

Multimodal mode lets SymDex index supported images, screenshots, and PDFs as searchable asset entries.

Notes:

  • Base symdex keeps symbol, text, route, and call-graph features without pulling in the local embedding stack.
  • If SYMDEX_EMBED_BACKEND is unset, SymDex uses the local backend when symdex[local] is installed.
  • Local semantic search requires symdex[local] and downloads the model on first use.
  • Voyage text mode requires symdex[voyage].
  • Voyage multimodal mode requires symdex[voyage-multimodal].
  • OpenAI-compatible mode reads SYMDEX_EMBED_BASE_URL, SYMDEX_EMBED_MODEL, and optional SYMDEX_EMBED_API_KEY or OPENAI_API_KEY.
  • Gemini mode reads SYMDEX_EMBED_MODEL, SYMDEX_EMBED_BASE_URL, and SYMDEX_EMBED_API_KEY, GEMINI_API_KEY, or GOOGLE_API_KEY.
  • SYMDEX_EMBED_RPM applies request pacing to remote backends. Use it when free tiers or proxies enforce requests-per-minute limits.
  • symdex index --lazy performs the fast structural index first, then starts a background symdex watch --embed process so embeddings can fill in without blocking the foreground command.
  • symdex index --no-embed skips semantic embedding work entirely.
  • If the selected backend extra is missing, SymDex prints an actionable install hint.
  • Multimodal indexing is only active when SYMDEX_VOYAGE_MULTIMODAL=1.

FAQ

Where are indexes stored? By default, each repo gets its own SQLite database under ~/.symdex, plus a central registry database. If you set SYMDEX_STATE_DIR=.symdex or use symdex --state-dir .symdex ..., SymDex keeps repo databases, registry.db, registry.json, and watcher metadata inside the current workspace instead.

What does indexing print? A code summary with files, Lines of Code, symbol counts, routes, skipped files, errors, and language breakdown.

What do search commands print? CLI search commands print a one-line ROI footer showing approximate token savings. MCP search tools return structured roi, a concise roi_summary, and roi_agent_hint so clients can mention the savings when responding to users.

Do existing users get update notices? Yes. Interactive CLI commands can print a brief upgrade notice with exact commands for pip, uv tool, and uvx. --json output stays quiet so structured consumers are not broken.

Does semantic search require the internet? Not by default. Install symdex[local] for the local backend; it downloads its model once and then runs offline. Voyage, OpenAI-compatible, and Gemini modes require network access unless the base URL points at a local server.

Why does symdex semantic say my repo has no semantic embeddings? That repo was indexed without an embedding backend, or kept fresh by the default low-memory watch mode. Enable the backend you want, then run symdex index, symdex index --lazy, or symdex watch --embed so embeddings are written into the index.

Will symdex watch keep a large embedding model in memory? No, not by default. Watch mode refreshes the structural index without loading the local semantic model unless --embed is passed. It also refuses duplicate watchers for the same repo/root, can auto-exit after an idle timeout, and stores watcher metadata in the active state directory so workspace-local mode stays isolated.

Can I install SymDex without sentence-transformers? Yes. pip install symdex keeps the core symbol, text, route, and call-graph features without the local embedding dependencies. Install symdex[local] only when you want local semantic search.

Can I use SymDex on multiple repos and worktrees? Yes. SymDex maintains a central registry, supports explicit --repo names, and can auto-generate stable repo ids from the current branch and worktree path when you omit --repo.

Why do some agent logs show index-folder or list-repos while the CLI docs say index and repos? index_folder and list_repos are MCP tool names. The canonical shell commands are symdex index and symdex repos, and SymDex also accepts compatibility aliases such as symdex index-folder and symdex list-repos.

What happens when I delete a worktree or repo? Run symdex gc or call gc_stale_indexes through MCP. SymDex removes stale registry entries and their database files.

Can I exclude generated files? Yes. Use .symdexignore at the repo root with gitignore-style patterns. Common generated/build paths are also skipped by default.

Can I use SymDex without an AI agent? Yes. All core search and navigation features are available through the CLI.


Contributing

Issues and PRs are welcome at github.com/husnainpk/SymDex.

If SymDex saves you tokens, a star helps other people find it.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

symdex-0.1.25.tar.gz (66.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

symdex-0.1.25-py3-none-any.whl (67.3 kB view details)

Uploaded Python 3

File details

Details for the file symdex-0.1.25.tar.gz.

File metadata

  • Download URL: symdex-0.1.25.tar.gz
  • Upload date:
  • Size: 66.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for symdex-0.1.25.tar.gz
Algorithm Hash digest
SHA256 144f1b1f298b937ca838ab1efc530b85a3fe12b6b99da1e827799f2d53c0b00e
MD5 7f9699b861b6fd89985bb026a4c60a08
BLAKE2b-256 d988659ba7a1789a3df17dff6b99ad2b9f5210aec7784d830da1e453f8942cdb

See more details on using hashes here.

Provenance

The following attestation bundles were made for symdex-0.1.25.tar.gz:

Publisher: publish.yml on husnainpk/SymDex

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file symdex-0.1.25-py3-none-any.whl.

File metadata

  • Download URL: symdex-0.1.25-py3-none-any.whl
  • Upload date:
  • Size: 67.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for symdex-0.1.25-py3-none-any.whl
Algorithm Hash digest
SHA256 2a584ff548839bd491836d0d39714a5f3eac2d48f2f9f5135abf8bd8919c2654
MD5 af24bfe71490f1e3af03ed4ca84a3128
BLAKE2b-256 9f601a77c22d106f65fb0500b1121e973473f92841433d725c9cd7e152db25bb

See more details on using hashes here.

Provenance

The following attestation bundles were made for symdex-0.1.25-py3-none-any.whl:

Publisher: publish.yml on husnainpk/SymDex

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page