smart-search
Supports indexing and searching of Obsidian vaults, allowing users to incorporate their personal markdown notes into a searchable knowledge base accessible by local AI tools.
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., "@smart-searchfind the key findings in the 2023 annual report PDFs"
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.
Smart Search
A personal, local-first knowledge management system. Index your documents, notes, spreadsheets, and more into a searchable knowledge base that connects with everything running locally -- Claude Code (MCP), a desktop app, REST API, or CLI. Runs entirely on your machine: no cloud, no GPU, no subscriptions.
Version: 0.13.1 | License: MIT
Why Smart Search?
Your knowledge is scattered across notes, PDFs, slide decks, and spreadsheets. Smart Search brings it together:
Search everything locally. 14 document formats indexed into one knowledge base with hybrid search (semantic + keyword + reranking). Find what you need whether you remember the exact phrase or just the concept.
Connect with your tools. MCP server for Claude Code, REST API for scripts and automation, CLI for power users, desktop app for visual management. One index, many interfaces.
Stay responsive. All heavy lifting runs in an out-of-process Python server. Your editor, your Obsidian vault, your desktop -- nothing freezes during indexing.
Own your data. Everything stays on disk -- LanceDB vectors and SQLite metadata in a local directory. No cloud sync, no telemetry, no accounts. MIT licensed.
Keep it lightweight. ONNX embeddings with lazy loading and automatic GPU acceleration. The model loads when you search, unloads after 60 seconds idle on CPU (stays resident on GPU). Steady-state RAM under 200MB.
Features
Search
Hybrid search (default): combines vector similarity with FTS5 keyword matching via Reciprocal Rank Fusion, cross-encoder reranking, and MMR diversity selection
Cross-encoder reranking: jointly scores (query, document) pairs with TinyBERT-L-2 for higher precision than bi-encoder similarity alone (+5-15 nDCG@10 in benchmarks)
MMR diversity: eliminates redundant chunks from the same document, ensuring results cover distinct information
Semantic mode: pure vector search with configurable relevance threshold
Keyword mode: BM25 ranking via SQLite FTS5 with porter stemming and stopword removal
Folder filtering: restrict results to specific directories
Find related: discover similar documents by averaging chunk embeddings
Search pipeline architecture: interactive visual diagram of the full retrieval pipeline
Supported Files
Category | Formats |
Documents |
|
Spreadsheets |
|
Presentations |
|
| |
Text |
|
Web |
|
Data |
|
Notebooks |
|
Indexing
14 formats: all non-Markdown files converted via MarkItDown, then chunked by headings
Keyword-only indexing: structured files (CSV, XLSX, JSON) indexed in FTS5 for keyword search without vector embeddings
Persistent conversion worker: long-lived subprocess for binary file conversion -- eliminates per-file process creation overhead on Windows
Background indexing: non-blocking with per-folder progress, cancellation, and auto-resume on restart
Hash-based dedup: unchanged files are skipped automatically
Persistent indexing log: file status (indexed/failed) stored in SQLite, survives server restarts with per-file retry
Ephemeral indexes: create temporary
.smart-search/indexes inside any folder
Desktop App
Tauri v2 + React desktop application with warm dark theme
Quick Search:
Ctrl+Spaceglobal hotkey opens a floating search overlay (configurable shortcut)Dashboard: index stats, per-folder status, model download progress
Folder Manager: add/remove watch directories with drag-and-drop
Indexing Log: persistent file log with status, error details, per-file retry, and open-in-default-app
Settings: font scaling, embedding model selection, Matryoshka dimension picker, relevance threshold, autostart, MCP registration
Repair Index: one-click maintenance (orphan removal, FTS5 rebuild, LanceDB compaction, compatibility check)
Window state: remembers size and position between sessions
Graceful shutdown: server exits cleanly via HTTP signal when desktop app closes
System tray: background operation with tray icon
Embedding
Default model: snowflake-arctic-embed-m-v2.0 (int8 ONNX, 297MB, 0.554 MTEB retrieval)
Matryoshka truncation: 256-dim default, configurable per model
Lazy loading: model loads on demand, unloads after 60s idle to free RAM
Curated registry: switchable models with quality/size metadata
GPU auto-detection: CUDA and DirectML acceleration used automatically when available, CPU fallback otherwise
Architecture
Out-of-process: all heavy lifting in Python, Obsidian/desktop stays responsive
MCP server: 11 tools for Claude Code integration
REST API: 20 endpoints on
localhost:9742CLI:
smart-searchcommand with subcommands for all operationsFile-based storage: LanceDB (vectors) + SQLite (metadata + FTS5), no database server
System Requirements
Requirement | |
OS | Windows 10/11 (x64) |
RAM | 2 GB minimum (~200 MB idle) |
Storage | ~300 MB (with AI model) |
Runtime | Python 3.11+ (bundled in desktop installer) |
Network | Not required |
Quick Start
Prerequisites
Python 3.11+
uv(recommended) orpip
Install
uv pip install git+https://github.com/ekmungi/smart-search.gitRegister with Claude Code
claude mcp add smart-search -- smart-searchUse
In Claude Code:
"Add C:/Users/me/vault to the knowledge base"
"Search my knowledge base for transformer architecture"
"Find notes related to meeting-notes/2026-03-10.md"Installation Options
Option A: Install from GitHub (recommended)
uv pip install git+https://github.com/ekmungi/smart-search.gitOr with pip:
pip install git+https://github.com/ekmungi/smart-search.gitThis creates the smart-search command on your PATH.
Option B: Local development install
git clone https://github.com/ekmungi/smart-search.git
cd smart-search
uv pip install -e ".[dev]"Option C: Desktop app
Download the installer from the Releases page. The desktop app bundles the Python backend as a sidecar -- no Python installation required.
Verify installation
smart-search statsMCP Server Setup
Register smart-search as an MCP server with Claude Code:
Method 1: claude mcp add (recommended)
claude mcp add smart-search -- smart-searchWith a virtual environment:
claude mcp add smart-search -- /path/to/venv/Scripts/smart-searchMethod 2: .mcp.json file
{
"mcpServers": {
"smart-search": {
"command": "smart-search"
}
}
}Method 3: Python module
{
"mcpServers": {
"smart-search": {
"command": "/path/to/python",
"args": ["-m", "smart_search.server"],
"cwd": "/path/to/smart-search"
}
}
}Note: On Windows, use forward slashes in JSON paths or escape backslashes.
CLI Cheatsheet
# Index management
smart-search stats # Index stats and data directory
smart-search index ingest /path # Index a file or folder
smart-search index ingest /path --ephemeral # Create a local .smart-search/ index
smart-search index list # List all indexed files
smart-search index rebuild # Re-index all watched directories
smart-search index remove /path # Remove files from index
# Search
smart-search search "query" # Hybrid search (default)
smart-search search "query" --mode semantic # Vector-only search
smart-search search "query" --mode keyword # FTS5 keyword search
smart-search search "query" --folder /path # Search within a folder
smart-search search "query" --limit 5 # Limit results
# Watch directories
smart-search watch list # List watched directories
smart-search watch add /path/to/dir # Add a watch directory
smart-search watch remove /path/to/dir # Remove a watch directory
# Configuration
smart-search config show # Show current configuration
smart-search model show # Show current embedding model
smart-search model set model-name --dim 256 # Change embedding model
# Server
smart-search serve # Start HTTP server (port 9742)
smart-search mcp # Start MCP server (stdio)
# Ephemeral indexes
smart-search temp list # List ephemeral indexes
smart-search temp cleanup /path # Remove an ephemeral indexClaude Code Prompts
Task | Prompt |
Index a folder | "Index my notes in C:/Users/me/vault" |
Search | "Search my knowledge base for regulatory compliance" |
Add watch folder | "Add C:/Users/me/papers to the watch list" |
Remove watch folder | "Stop watching C:/Users/me/old-notes" |
Check stats | "Show knowledge base statistics" |
List indexed files | "List all indexed files" |
Find related notes | "Find notes related to meeting-notes/2026-03-10.md" |
Read a note | "Read the note at projects/smart-search.md" |
Force re-index | "Re-index C:/Users/me/vault with force=true" |
Temp index | "Create a temporary index of C:/Users/me/Downloads/papers" |
Search temp index | "Search the temp index at C:/Users/me/Downloads/papers for transformers" |
Clean up temp index | "Clean up the temporary index at C:/Users/me/Downloads/papers" |
MCP Tools
Tool | Description |
| Search with query, mode (semantic/keyword/hybrid), folder filter, doc type filter |
| Index statistics: documents, chunks, size, formats |
| Index a file or folder (background for directories) |
| Add a folder to the watch list and trigger indexing |
| Stop watching a folder, optionally delete data |
| List watched directories and their status |
| List indexed files with chunk counts |
| Find documents similar to a given note |
| Read a note's content (supports PDF, DOCX via MarkItDown) |
| Create an ephemeral index inside a folder |
| Delete an ephemeral index |
REST API
The HTTP server runs on localhost:9742 with 23 endpoints:
Method | Endpoint | Description |
GET |
| Server health, version, uptime |
GET |
| Index statistics |
GET |
| Search with mode, folder filter |
GET |
| List watched folders |
POST |
| Add folder (returns 202, background indexing) |
DELETE |
| Remove folder |
GET |
| List indexed files |
POST |
| Index file (sync) or folder (202 async) |
GET |
| Background indexing progress |
GET |
| Current configuration |
PUT |
| Update configuration |
GET |
| Available embedding models |
GET |
| Model cache status |
GET |
| Model memory status |
GET |
| Find related documents |
POST |
| Run index maintenance (orphans, FTS5, compaction) |
POST |
| Create ephemeral index |
GET |
| List ephemeral indexes |
POST |
| Retry failed files (clear + re-queue) |
POST |
| Graceful server shutdown |
DELETE |
| Delete ephemeral index |
Configuration
Data Directory
OS | Default Path |
Windows |
|
Linux |
|
macOS |
|
Override with: SMART_SEARCH_DATA_DIR=/custom/path
config.json
Persistent configuration stored in the data directory. Managed via CLI, REST API, or desktop Settings panel.
Environment Variables
All settings can be overridden with SMART_SEARCH_ prefixed variables:
Variable | Default | Description |
|
| Embedding model |
|
| Vector dimensions (Matryoshka) |
|
| Directories to watch |
|
| Default search mode |
|
| Minimum similarity score (semantic mode) |
|
| Maximum tokens per chunk |
|
| File types to index |
|
| Excluded directories |
|
| File watcher debounce |
|
| Default result count |
Architecture
All clients connect to the same HTTP server on port 9742. The server is the single source of truth -- there is only one backend process.
┌─────────────────────────┐
│ HTTP Server (:9742) │
│ smart-search serve │
│ (FastAPI, 20 endpoints)│
└──────┬──┬──┬────────────┘
│ │ │
┌──────────────┘ │ └──────────────┐
│ │ │
┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐
│ Desktop UI │ │ MCP Server │ │ CLI │
│ (Tauri v2) │ │ (proxy) │ │ smart-search│
│ fetch() │ │ → :9742 │ │ search/etc │
└─────────────┘ └─────────────┘ └─────────────┘
Started by user Started by Run manually
(or autostart) Claude Code in terminalWho starts the HTTP server?
Desktop app running: the Tauri app starts the server as a sidecar process. When you quit from the system tray, it kills the server.
No desktop app: run
smart-search servemanually, or the MCP tools will fail.
Key point: the MCP server does NOT run its own backend. It is a thin translator -- MCP protocol in, HTTP request to :9742, response back as MCP result. If the HTTP server is not running, MCP tools will return errors.
Component Details
Backend (Python, all share the HTTP server)
http.py / http_routes.py FastAPI app, 20 endpoints
server.py / mcp_client.py MCP server, proxies to HTTP
search.py Hybrid search: vector + FTS5 + RRF + rerank + MMR
fts.py FTS5 keyword search, BM25 ranking
fusion.py Reciprocal Rank Fusion (k=60)
reranker.py Cross-encoder reranking (TinyBERT, lazy-load)
mmr.py Maximum Marginal Relevance diversity selection
query_preprocessor.py Stopword removal (FTS5), query normalization
indexer.py Document ingestion pipeline
conversion_worker.py Persistent subprocess for binary file conversion
markitdown_parser.py File -> Markdown conversion
markdown_chunker.py Heading-based section splitting
embedder.py ONNX embedding with lazy load/unload
store.py LanceDB vectors + SQLite metadata + FTS5
startup.py Orphan reconciliation, FTS5 backfill, repair
watcher.py Watchdog file watcher with debounce
indexing_task.py Background task manager with cancellation
config_manager.py Persistent config.json
Storage (file-based, no database server)
LanceDB vectors/ directory (columnar, sub-50ms search)
SQLite metadata.db (indexed_files + chunks_fts virtual table)
Desktop (Tauri v2)
Rust System tray, sidecar manager, global shortcut
React Dashboard, Folder Manager, Settings, Quick SearchData Flow
File -> MarkItDown (non-.md) -> Markdown -> MarkdownChunker -> Chunks
-> Embedder -> LanceDB + SQLite FTS5Search Flow (hybrid mode)
Query -> Preprocess (stopwords / normalization)
-> Vector search (LanceDB) ─┐
-> Keyword search (FTS5 BM25) ─┼─> RRF Fusion
-> Cross-Encoder Rerank (TinyBERT, 30-60ms)
-> MMR Diversity (lambda=0.8, <1ms)
-> Final ResultsFor the full pipeline architecture with resource budgets and configuration reference, see docs/search-architecture.md or the interactive visual diagram.
Running Tests
# Fast tests only (default)
pytest
# All tests including slow integration tests
pytest -m ""
# With coverage
pytest --cov=smart_search --cov-report=term-missing425+ tests covering all modules. Slow tests (marked @pytest.mark.slow) require ML models to be downloaded.
Tech Stack
Component | Technology |
MCP server | FastMCP |
HTTP server | FastAPI + Uvicorn |
Document parsing | MarkItDown (14 formats: PDF, DOCX, XLSX, PPTX, EPUB, CSV, MSG, HTML, TXT, JSON, IPYNB) |
Markdown parsing | Custom heading-based splitter |
Embeddings | snowflake-arctic-embed-m-v2.0 via ONNX Runtime |
Vector store | LanceDB (file-based, columnar) |
Metadata + FTS | SQLite (FTS5 with porter stemming) |
Search fusion | Reciprocal Rank Fusion (RRF, k=60) |
Reranking | cross-encoder/ms-marco-TinyBERT-L-2-v2 via ONNX Runtime |
Diversity | Maximum Marginal Relevance (MMR, lambda=0.8) |
File watching | Watchdog |
Desktop | Tauri v2 + React + Tailwind CSS v4 + Motion |
Build | Hatchling (Python), PyInstaller (sidecar), NSIS (installer) |
License
MIT
This server cannot be installed
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/ekmungi/smart-search'
If you have feedback or need assistance with the MCP directory API, please join our Discord server