LittleLibrary is a self-hosted, local-only search and reading application for your personal text files (*.txt, *.md). It runs as an ASP.NET Core web app (.NET 10) with a single-page frontend: point it at a folder of notes or documents, then search, browse, and read them from the browser.
- Indexing — give it a path; every
*.txt/*.mdfile beneath that path is scanned and indexed. Re-indexing an already indexed path updates the entry in place instead of duplicating or erroring. - Search — full-text search over the indexed corpus using Lucene's standard query syntax: bare words,
AND/OR composition,+term/-term, quoted phrases, and prefix wildcards (sec*). Ranked results with best-effort snippets around matched terms (highlighted in the UI); malformed queries are rejected with an actionable error rather than silently lenient-matched. - Reading — open any document's full text from a reading pane with adjustable font size; dark/light/auto theming throughout.
- Management — list the index in pages, remove individual documents, and inspect indexing summaries.
| Endpoint | Purpose |
|---|---|
POST /api/documents/index |
Index (or update) every supported file under a path; returns files found / indexed / skipped counts |
GET /api/documents?page=&pageSize= |
Paginated listing of indexed documents |
DELETE /api/documents/{id} |
Remove one document from the index (idempotent) |
GET /api/documents/{id}/content |
Full text of a document for the reading pane |
POST /api/search |
Standard-syntax search query with optional result size; returns ranked hits with snippets (malformed queries → 400) |
Known backend failures are translated into compact JSON errors rather than stack traces. In development mode an OpenAPI endpoint is also exposed.
LittleLibrary exposes the index to AI agents over Model Context Protocol using the Streamable HTTP transport at POST /mcp (e.g. http://localhost:5000/mcp). MCP access is strictly read-only: it can search and retrieve, but never indexes, updates, or removes anything — those remain exclusive to the REST endpoints above. Every tool advertises readOnlyHint, and server-level instructions tell connected agents how matching works before they start querying.
| Tool | Purpose |
|---|---|
search_documents |
Full-text search; returns ranked hits with context snippets and opaque ids (query, optional size 1-100) |
get_document |
Full text of one document by the opaque id taken from a hit or listing entry (not guessable, not a path) |
list_documents |
Paginated browse of what is indexed (page, pageSize), with totals for pagination |
How search works (also delivered to agents in the MCP initialization handshake): queries use Lucene's standard syntax over the document body — a bare word matches documents containing it, multiple bare words combine as OR by default (AND or +term requires every term, -term excludes), quoted strings match exact phrases in order, and a trailing * gives prefix matching (sec* finds security; no stemming or fuzzy matching). Hits are ranked by relevance score and carry short snippets around the first matches. An empty result means no document satisfies the query's constraints; loosen it (drop required clauses, prefer OR) rather than repeating it verbatim.
Example client configuration (Claude Desktop-style):
{
"mcpServers": {
"littlelibrary": { "url": "http://localhost:5000/mcp" }
}
}No authentication is applied — like the rest of the app, MCP assumes a trusted local network. The index location follows Indexing:DataDirectory (default data/, resolved relative to the app directory); nothing leaves your machine.
LittleLibrary/— web app: controllers (search, documents), read-only MCP tools (Mcp/DocumentTools.cs), indexing pipeline (DirectoryFileScanner,DocumentIndexService), storage backend (LuceneIndexStore, backed by Apache Lucene via Lucene.Net), API error middleware, and the frontend underwwwroot/.LittleLibrary.Test/— unit tests for the indexing and storage layers.
dotnet run --project LittleLibraryThen open the local URL shown by Kestrel (e.g. http://localhost:5000). Enter a path in the Index panel to load documents, use Search to find them, and click a result to read it.
The index location is configurable via the Indexing:DataDirectory setting (default: data/, resolved relative to the app directory). Documents are keyed by their absolute file path; nothing leaves your machine.
Note: This project was created with AI assistance.