code-index-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@code-index-mcpfind the definition of 'handleError' function"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
code-index-mcp
Self-hosted hybrid code search as an MCP server for Kilo CLI / OpenCode. Everything runs locally on your machine — no third-party MCP servers, no LSP, no SaaS.
Three search layers, one server:
Layer | Engine | Good for |
text | SQLite FTS5 | exact strings, identifiers, config keys, errors |
symbols | tree-sitter | "where is |
semantic | fastembed (local) → Qdrant | fuzzy "where do we do Y" |
Requirements
Python 3.10+
Qdrant running locally (you already have it) at
http://localhost:6333The rest is pip-installed (tree-sitter grammars + fastembed are local; the embedding model downloads once and then runs offline).
Related MCP server: Code Memory
Install
# from the project folder
uv venv
uv pip install -e .
# or: pip install -e .Nothing is written into your repos
All state lives outside the indexed repositories:
SQLite index →
~/.cache/code-index/<service-id>.sqlite3Qdrant collection →
code_<service-id>(derived from the repo's absolute path)Project registry →
~/.config/code-index/projects.toml
So you never commit anything, never edit .gitignore, and never add git hooks
inside the service repos — no PR noise.
Single project
code-index index # incremental index of CWD (or --path DIR)
code-index index --full # full rebuild
code-index statsMicroservices (many repos)
Register services in the external registry (no files in the repos):
# Register each service explicitly...
code-index add C:\work\billing --name billing
code-index add C:\work\payments --name payments
# ...or point at a parent folder and auto-discover every git repo inside:
code-index add-workspace C:\work --depth 1
code-index list # show resolved services
code-index index-all # (re)index every service (per-service index)
code-index stats-allThe registry file (~/.config/code-index/projects.toml) looks like:
[[service]]
name = "billing"
path = "C:/work/billing"
[[workspace]]
path = "C:/work"
depth = 1Per-project ignore (no files in the repo)
Each [[service]] (and [[workspace]]) can declare what to skip — all in the
external registry, so nothing is written into the service repo:
[[service]]
name = "billing"
path = "C:/work/billing"
ignore = ["**/generated/**", "*.pb.go", "docs/legacy/**"] # extra ignore globs
use_gitignore = true # ALSO skip whatever the repo-root .gitignore listsignoreis a list of glob patterns matched against repo-relative POSIX paths. Supported glob/.gitignore-like syntax:*(no/),**(any depth),?, a trailing/(directories only), and a leading/embedded/(anchored to the repo root). These are layered on top of the built-in ignores (build dirs, lock files, minified bundles, etc.).use_gitignore = trueadditionally reads the repo's top-level.gitignore(read-only — never written). Negation rules (!pattern) and nested per-directory.gitignorefiles are intentionally not supported, to keep the matcher tiny and predictable.For a
[[workspace]],ignore/use_gitignoreare inherited by every auto-discovered repo under it.
Watch indexing progress
code-index index # shows a live rich progress bar (TTY)
code-index index --plain # plain stderr logging instead
code-index status # one-shot table: phase / progress / files / symbols
code-index status --watch # live dashboard, refreshes ~1/s (Ctrl+C to stop)
code-index web # tiny local web dashboard at http://127.0.0.1:8765
code-index web --port 9000 # pick another portProgress is shared across processes via tiny JSON files in
~/.cache/code-index/status/<id>.json (atomic writes). So you can run
code-index status --watch (or open the web page) in one terminal and watch the
background code-index-watch daemon — or an index-all running elsewhere —
make progress in real time. The web UI is opt-in (started only by code-index web), single-threaded, and does work only when the browser polls — deliberately
light for a low-power machine.
Auto re-index (no git hooks)
A background daemon keeps every registered service fresh using filesystem events (watchdog) plus a periodic safety sweep — all outside the repos:
code-index-watch # FS events + sweep every 600s
code-index-watch --interval 300 # sweep every 5 min
code-index-watch --no-periodic # FS events onlyLeave it running (e.g. as a startup task / Windows service). It does an initial incremental index of each service, then re-indexes only what changes.
Wire it into Kilo CLI / OpenCode
Add a local MCP server to your config
(~/.config/kilo/opencode.json for Kilo CLI, or ~/.config/opencode/opencode.json
for OpenCode; a per-project opencode.json works too):
One MCP server can serve all your microservices — the agent picks the
service per call (or uses the default CWD service). Put this in the global
config (~/.config/kilo/opencode.json for Kilo, ~/.config/opencode/opencode.json
for OpenCode):
{
"$schema": "https://app.kilo.ai/config.json",
"mcp": {
"code-index": {
"type": "local",
"command": ["code-index-mcp"],
"enabled": true,
"environment": {
"CODE_INDEX_ROOT": "${cwd}",
"QDRANT_URL": "http://localhost:6333",
"CODE_INDEX_EMBED_MODEL": "BAAI/bge-small-en-v1.5",
"CODE_INDEX_SEMANTIC": "1"
}
}
}
}If
code-index-mcpisn't on PATH, use the absolute path to the venv script, e.g.["C:/Users/you/PycharmProjects/code-index-mcp/.venv/Scripts/code-index-mcp.exe"], or["python", "-m", "code_index.server"]with the venv's python.
Restart the CLI. The agent now sees tools:
search_text, search_symbol, file_symbols, search_semantic,
search_hybrid, list_services, reindex, index_stats. Every search tool
takes an optional service (name or id from list_services).
Keeping the index fresh
Background daemon (recommended):
code-index-watch(see above).On demand from the agent: it can call the
reindextool.Manual:
code-index index/code-index index-all.At server start: set
CODE_INDEX_REINDEX_ON_START=1for a quick background incremental of the default service when the MCP server launches.
Environment variables
Var | Default | Meaning |
|
| default project root (single-project / fallback) |
|
| where |
|
| where SQLite indexes live |
|
| Qdrant endpoint |
| – | optional Qdrant key |
|
| fastembed model |
|
| set |
|
|
|
Live indexing status is written to
~/.cache/code-index/status/<id>.json(underCODE_INDEX_CACHE_HOME). Inspect it withcode-index status/code-index status --watch, or thecode-index webdashboard.
Graceful degradation
No tree-sitter? → symbols layer off, text + semantic still work.
Qdrant down / fastembed missing? → semantic off, text + symbols still work.
The text (FTS5) layer always works as long as the SQLite index exists.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Krat12/mcp-code-index'
If you have feedback or need assistance with the MCP directory API, please join our Discord server