Semantic code search as an MCP server. Point it at a project and an AI agent (or you) can find code by meaning, not just by keyword. "Where do we validate the auth token?" returns the right function even if it never uses the words "validate" or "auth."
Runs fully local: local embeddings, a local vector store, no API keys, nothing leaves your machine.
- AST-aware chunking. Python is split along function and class boundaries via the
astmodule, so a match is a whole meaningful unit, not a random window. Everything else falls back to line-based chunks. (chunker.py) - Local embeddings. Uses FastEmbed with
BAAI/bge-small-en-v1.5. No OpenAI key, no network calls. - Local vector store. Milvus Lite writes a single
milvus.dbfile under the project's own.code-index/directory. - Respects
.gitignore. Build artifacts,node_modules, and vendored code are skipped viapathspec. (gitignore_filter.py)
Exposed over the Model Context Protocol (server.py):
| Tool | What it does |
|---|---|
reindex(project_path) |
Full reindex: collect files, chunk, embed, store. Returns file/chunk counts and duration. |
search_code(project_path, query, limit=10) |
Semantic search. Returns ranked chunks with file_path, line range, content, chunk_type, name, and score. |
index_status(project_path) |
Reports whether an index exists and how stale it is (file count, chunk count, age, last indexed). |
pip install -r requirements.txtRegister it as an MCP server with your client (e.g. Claude Code):
{
"mcpServers": {
"code-index": {
"command": "python",
"args": ["/path/to/code-index/server.py"]
}
}
}Then, from your agent: reindex a project once, and search_code for the rest of the session. Re-run reindex when the tree has drifted (index_status tells you when it's stale).
python -m pytestCovers the chunker, the .gitignore filter, the indexer, and the server tools.
Python 3.10+. See requirements.txt (mcp, pymilvus[milvus_lite], fastembed, pathspec).