A privacy-focused recommendation engine that learns from your ratings and reviews across books, movies, TV shows, and video games.
- Runs locally. Your data never leaves your machine
- Works without AI. Smart scoring algorithms that don't need an LLM
- AI is optional. Enable Ollama integration when you want deeper insights
- You own your data. A SQLite database you can query, back up, or delete
It imports from sources you already use, enriches items with metadata, and ranks recommendations through a transparent scoring pipeline. Your love of sci-fi books can influence game and movie suggestions through semantic genre clusters. Browse and tune everything from a themeable web UI or the CLI, which are interchangeable interfaces to the same engine.
mkdir -p recommendinator/{config,data,inputs} && cd recommendinator
docker run -d \
--name recommendinator \
-p 18473:8000 \
-v "$(pwd)/config:/app/config" \
-v "$(pwd)/data:/app/data" \
-v "$(pwd)/inputs:/app/inputs:ro" \
--restart unless-stopped \
ghcr.io/therealahall/recommendinator:latestThe container writes a starter config/config.yaml you do not need to edit. Open
http://localhost:18473 and set everything up from the app. Then, in order:
- Set up enrichment first. It fills in the genres, tags, and descriptions the scoring pipeline depends on. Skipping it produces poor recommendations.
- Connect a data source, from the table below.
- Get recommendations, in the web UI or with
python3.11 -m src.cli recommend --type book --count 5.
Running from source instead of Docker? See the Quick Start guide. For AI features, GPU support, reverse proxies, and the full deployment reference, see docs/DOCKER.md.
This is a personal, single-user tool with no authentication on any
endpoint. It binds to 127.0.0.1 by default. Change the host to 0.0.0.0 for
LAN access and anyone on your network can view and modify your data. Do not
expose it to the public internet. See docs/SECURITY.md.
Each source has its own setup guide. Pick the ones you use.
| Source | Type | Setup |
|---|---|---|
| Goodreads (CSV export) | Books | goodreads_csv |
| Goodreads (public shelves via RSS) | Books | goodreads_rss |
| The StoryGraph | Books | storygraph_csv |
| Calibre-Web | Books | calibre_web |
| Steam | Games | steam |
| GOG | Games | gog |
| Epic Games | Games | epic_games |
| Sonarr | TV Shows | sonarr |
| Radarr | Movies | radarr |
| Trakt | TV Shows / Movies | trakt |
| ROM Library | Games | roms |
| CSV / JSON / Markdown | Any | generic_csv · generic_json · markdown |
For adding, editing and removing sources in the UI, parallel sync, and library export, see docs/DATA_SOURCES.md.
Core, no AI required
- Multi-source ingestion, with cross-content recommendations through semantic genre clusters
- A transparent scoring pipeline over genre, creator, series order, tag overlap and rating patterns (how it works)
- Natural-language custom rules like "avoid horror"
- Metadata enrichment from TMDB, OpenLibrary and RAWG, automatic or edited by hand
- Content-length filtering, multi-user support, fuzzy library search, themes
Optional AI, opt-in and local
- Conversational chat over your library, with memory and user profiling
- Semantic similarity, LLM-reasoned explanations, smart rule interpretation
See Enabling AI features below.
Copy config/example.yaml to config/config.yaml. It holds only what is needed
to stand the app up, which is where the server binds and where the database
lives:
web:
host: "127.0.0.1"
port: 18473
storage:
database_path: "data/recommendations.db"Under Docker those two are inert, because the image passes --host and --port
on the command line and CLI flags beat config.yaml. Publish a different port
with APP_PORT instead. See docs/DOCKER.md.
Everything else lives in the database and is set from the app. Data sources come
from the Data tab or the source CLI. Global settings, from AI toggles to
scorer weights to logging, come from the Settings page or the settings CLI.
python3.11 -m src.cli settings list
python3.11 -m src.cli settings set features.ai_enabled true
python3.11 -m src.cli settings set-secret enrichment.providers.tmdb.api_keyAPI keys and OAuth tokens are stored encrypted, so enter them from the Settings
page or settings set-secret, never config.yaml. See
docs/SCORING.md for what the weights do and
ARCHITECTURE.md for
precedence.
A sync fills in around what you have said, it does not talk over you. Ratings and reviews are only ever written into an empty field, completion dates give way only to later ones, and status moves forward, never back. The single exception is a completed TV show whose season checklist you have filled in, which returns to in-progress when a sync brings new seasons. Your own edits win outright, and any field you do not mention is left alone. The full rules cover every case.
An export is a snapshot, not a patch. Every row it writes states whether that item is ignored, so re-importing one replaces your whole ignore list with the one you had on the day you exported. That is how you un-ignore things in bulk, and it is why you import an export once and remove it rather than leaving it configured as a source.
The Goodreads CSV plugin was renamed from goodreads to goodreads_csv.
Existing items and DB-stored source configs are relabeled automatically on first
startup. If you configure Goodreads through config.yaml, rename
plugin: goodreads to plugin: goodreads_csv.
python3.11 -m src.cli update --source all
python3.11 -m src.cli recommend --type book --count 10
python3.11 -m src.cli library list --type book --status completed --sort rating
python3.11 -m src.cli library list --search "die hard"
python3.11 -m src.cli chat startFull command reference: docs/CLI.md.
For semantic similarity and LLM-powered explanations:
- Docker:
docker compose --profile ai up -d app-aisets up Ollama and the models for you. - Local: install Ollama, run
ollama pull mistral:7b, then turn onfeatures.ai_enabled,features.embeddings_enabledandfeatures.llm_reasoning_enabledfrom the Settings page. All three are restart-required.
See docs/MODEL_RECOMMENDATIONS.md for model selection.
| Document | Description |
|---|---|
| QUICKSTART.md | Getting started guide (Docker and from-source) |
| docs/DATA_SOURCES.md | Managing sources, parallel sync, export |
| docs/CLI.md | Full CLI command reference |
| docs/SCORING.md | How the recommendation engine scores |
| docs/ENRICHMENT_SETUP.md | Metadata enrichment setup (critical) |
| ARCHITECTURE.md | System design and components |
| CONTRIBUTING.md | Contributing guidelines |
| docs/DOCKER.md | Docker deployment, AI mode, GPU, reverse proxy |
| docs/CONVERSATION_GUIDE.md | Chat interface and AI conversation |
| docs/CUSTOM_RULES.md | Custom preference rules |
| docs/PLUGIN_DEVELOPMENT.md | Adding new data sources |
| docs/THEME_DEVELOPMENT.md | Creating custom web UI themes |
| docs/MODEL_RECOMMENDATIONS.md | Ollama model selection |
| docs/CHROMADB_SETUP.md | ChromaDB setup (AI-only) |
| docs/OLLAMA_SETUP_GUIDE.md | Ollama installation and setup |
| docs/SECURITY.md | Security considerations |
| docs/PYTHON_VERSION.md | Python version requirements |
| docs/TROUBLESHOOTING.md | Common issues and solutions |
Python 3.11 recommended (see docs/PYTHON_VERSION.md), SQLite, and Ollama if you want the AI features.
PolyForm Noncommercial 1.0.0, free for personal and noncommercial use.