2.7 KiB
Goal
Build a local, self-hosted documentation knowledge base that can ingest software docs, generate embeddings, store them in SQLite, and expose high-quality retrieval through MCP tools and resources.
Core Architectural Decisions
Storage
Use:
- SQLite for metadata and document storage
- FTS5 for keyword search
- sqlite-vec for vector similarity search
Avoid a separate vector database unless scale requirements emerge.
Embeddings
Use local embedding models via:
- sentence-transformers
Recommended model:
BAAI/bge-base-en-v1.5
Store embeddings alongside document chunks.
Ingestion
Primary sources:
- Git repositories containing Markdown docs
- Documentation websites via Crawl4AI
- Sitemap-driven crawls when available
Pipeline:
Source
↓
Extract
↓
Normalize
↓
Chunk by headings
↓
Embed
↓
Store
Track content hashes so unchanged documents are skipped during reindexing.
Retrieval
Implement hybrid retrieval:
FTS5 keyword search
+
sqlite-vec similarity search
↓
Candidate set
↓
Reranker
↓
Final results
Reranker:
BAAI/bge-reranker-v2
The retriever owns all ranking logic.
Public Interface
Do not expose vector search directly.
Expose a retrieval service through MCP:
search_docs(query)
get_context(query)
get_doc(path)
The MCP layer becomes the stable API.
Clients never interact with embeddings or vectors.
Repository Layout
src/
├── knowledge/
│ ├── models.py
│ ├── chunking.py
│ ├── embeddings.py
│ ├── ingestion.py
│ ├── sqlite_store.py
│ ├── hybrid_search.py
│ ├── reranker.py
│ └── retrieval.py
│
├── sources/
│ ├── git_docs.py
│ ├── crawl4ai_docs.py
│ └── sitemap_docs.py
│
├── mcp_server/
│ ├── tools.py
│ └── resources.py
│
└── cli/
├── ingest.py
└── reindex.py
Retrieval Flow
User Query
↓
Embed Query
↓
FTS5 Search
+
Vector Search
↓
Merge Results
↓
Rerank
↓
Return Context Bundle
Where a context bundle contains:
ContextBundle(
passages=[...],
citations=[...],
related_docs=[...],
)
Future Extensions
Without changing the architecture:
- Multiple documentation corpora
- Version-aware retrieval
- Code snippet indexing
- MCP resources for specific topics
- LangGraph integration
- Docker deployment
- Scheduled reindexing
The key design principle is: treat the vector store as an internal implementation detail and expose a retrieval-oriented MCP interface instead.