code-context-mcp
An MCP server that indexes a repository into a local vector store and returns the few relevant blocks, with line ranges, instead of whole files.
- Status
- Public and working. Small on purpose.
- Stack
- Python 3.10+ · ChromaDB · LM Studio / nomic-embed-text · MCP
- Size
- ~16k of Python
- Links
- GitHub
Reading a file into an agent's context is the default move and usually the wrong one. A 3,000-line module answers a question with 2,900 lines of noise, and the noise is not free — it displaces the rest of the task.
This indexes a project into a local Chroma collection and exposes semantic search over it, so
the answer to "where does the permission check happen" is four blocks with path:line ranges
rather than four files.
project files ──▶ chunker ──▶ LM Studio (nomic-embed) ──▶ ChromaDB
│
the agent ◀── MCP tools (search_code / index_project) ◀────┘
Everything is local
Embeddings come from LM Studio's OpenAI-compatible endpoint running nomic-embed-text on the
machine. No API key, no upload, and no clause anywhere about what happens to a private
codebase after it is embedded.
That constraint also happens to make re-indexing cheap enough to do casually, which matters more than it sounds — an index you are reluctant to rebuild is an index that is out of date.
Incremental by content hash
Indexing walks the project honouring .gitignore, splits files into line-windowed chunks,
embeds each one, and upserts. A re-index hashes file contents and skips anything unchanged, so
the second run over a repository costs almost nothing.
Line windows rather than syntax-aware chunks was a deliberate compromise. A tree-sitter chunker per language is better and is also the kind of dependency that turns a small tool into a project; windowed chunks with overlap retrieve well enough that I have not needed to find out where the ceiling is.
Four tools, nothing else
index_project, search_code, index_status, clear_index. The status tool exists because
the failure mode of a retrieval server is silent: it returns results that look fine and are
stale, and the only way to catch that is to be able to ask how many files and chunks it thinks
it has and which model produced them.