A self-hosted news feed that learns what you care about, ranked and summarised by Claude.
1.5K
A self-hosted news feed that learns what you care about.
NewsNest gathers your RSS feeds into one calm stream, folds the same story from different outlets into a single card, and uses Claude to rank and summarise what matters to you.
Website · Features · Quick start · How it works · Configuration · Development
![]() | ![]() | ![]() |
| Feed, ranked for you | Swipe to sort | Dark mode, automatically |
Outlets and headlines are made up. Photos from Unsplash by Mohammad Rahmani, Gabriella Clare Marino and Amol Tyagi.
Checking a dozen news sites every day is slow, and most of what you see isn't for you. Algorithmic feeds fix that by learning what keeps you scrolling, which is not the same as what you want to read.
NewsNest is the opposite deal. You choose the sources, you write down what interests you, and you can see why every story ranks where it does. It runs on your own machine, keeps everything in one SQLite file, and talks to the Anthropic API with your own key.
/health endpoint report sources that fail or
go silent.You need Docker with Compose, and, for the AI features, an Anthropic API key. Pull the published image (no clone needed, and the one to use for a Portainer stack), or build from source.
Multi-arch (linux/amd64 + linux/arm64, so a Raspberry Pi or an ARM NAS works too):
ghcr.io/lucifix/newsnestdocker.io/lucifix/newsnestPaste this into Portainer (Stacks → Add stack → Web editor) or save it as docker-compose.yml
anywhere. Only the password needs filling in:
services:
newsnest:
image: ghcr.io/lucifix/newsnest:latest
container_name: newsnest
restart: unless-stopped
ports:
- 3095:8080
environment:
NEWSNEST_PASSWORD: change-me # required: with no password the app refuses all access
ANTHROPIC_API_KEY: "" # optional: enables ranking and summaries
TZ: UTC # your time zone, e.g. Europe/Ljubljana
volumes:
- newsnest-config:/config
- newsnest-data:/data
volumes:
newsnest-config:
newsnest-data:
For the full file, with host folders you can open and edit instead of Docker volumes, use
docker-compose.yml from this repo:
mkdir newsnest && cd newsnest
curl -fsSLO https://raw.githubusercontent.com/Lucifix/newsnest/main/docker-compose.yml
curl -fsSL https://raw.githubusercontent.com/Lucifix/newsnest/main/.env.example -o .env
mkdir -p config data # so Docker doesn't create them as root
# edit .env: set NEWSNEST_PASSWORD, and ANTHROPIC_API_KEY for AI
docker compose up -d
Update: docker compose pull && docker compose up -d. Set NEWSNEST_IMAGE_TAG in .env to pin a
release such as 0.3.1; the default is latest.
git clone https://github.com/Lucifix/newsnest.git && cd newsnest
cp .env.example .env # set NEWSNEST_PASSWORD, and ANTHROPIC_API_KEY for AI
mkdir -p config data # so Docker doesn't create them as root
docker compose up -d --build
Update: git pull && docker compose up -d --build
Open http://localhost:3095, log in with your password, and tap Set up my profile:
On first start NewsNest copies a starter config.yaml into config/, with
international news and tech feeds and no local ones. Change the feeds in Settings → Feeds, or edit
the file. It is re-read on every run, so there is nothing to restart.
Note
The login is a single shared password over plain HTTP, which is fine on your home network. If you expose NewsNest to the internet, put it behind an HTTPS reverse proxy.
flowchart LR
A["RSS / Atom feeds<br/>GitHub releases"] --> B["Fetch &<br/>de-duplicate"]
B --> C["Group the same story<br/>across outlets"]
C --> D["Claude scores<br/>topic · importance · fit"]
D --> E["Rank<br/>score × freshness × what you like"]
E --> F(["Your feed"])
F -- "likes · opens · ratings" --> E
A 60-second loop fetches the sources that are due, scores new stories in batches, and writes key points for the ones above your threshold. Scoring uses a small, cheap model with prompt caching; the rarer jobs (drafting your profile, the weekly suggestions) use a stronger one. Both are configurable.
What leaves your server: headlines and snippets, and for key points the article text, go to the Anthropic API using your key. Your feed list, ratings and database stay on your machine, and NewsNest itself sends no telemetry.
Everything lives in the config/ folder, which is re-read on every run:
| File | Purpose |
|---|---|
config.yaml | Feeds, GitHub repos, watches, schedules, thresholds, models and the spending cap. Every option is explained in config.example/config.yaml. |
interests.md | What you care about and what to skip. Written on the Profile page, or by hand. |
seed_examples.md | About 20 example headlines marked + (want) or - (don't want). |
Edits made in the Settings pages are written back to config.yaml, comments included.
Tip
The example config comes with international feeds, no region and the time zone `UTC`. Set where you live in **Settings → General** (country, city, time zone), and NewsNest offers your country's local pack.
Sections. Every feed belongs to one section, and the sections are the tabs along the bottom of the
feed. A new install starts with Local, World and Tech. In Settings → Feeds → Sections you can rename
them, add your own (Sports, Science, Cinema…), reorder them, and remove one (its feeds and stories move
to a section you pick). Local and World are built in: they can be renamed but not removed, and share the
News tab. A section is a tab once it has a feed; at most four can be tabs, and any further section
shows as a chip under For you. The list is the sections: key in config.yaml. A config.yaml
from before sections were editable has none and keeps the old four (Tech, Local, World, Lifestyle) until
you change them, so nothing needs migrating and the database is untouched.
Note
Once you edit sections, `config.yaml` has a `sections:` list that older NewsNest versions don't understand. To go back to an older image, restore the `config.yaml.bak` made by the last edit.
Set these in .env (see .env.example).
| Variable | Default | Purpose |
|---|---|---|
NEWSNEST_PASSWORD | – | Required. Password for the web UI. With none set, access is refused. |
ANTHROPIC_API_KEY | – | Turns on scoring, key points and the weekly suggestions. |
TZ | UTC | Container time zone (logs). The app itself uses timezone from config.yaml. |
NEWSNEST_PORT | 3095 | Port the web UI is published on. |
NEWSNEST_CONFIG_PATH | /opt/newsnest/config | Host folder for config.yaml and the profile files. |
NEWSNEST_DATA_PATH | /opt/newsnest/data | Host folder for the database. |
PUID / PGID | 1000 | User and group the container runs as. |
NEWSNEST_LOG_LEVEL | INFO | Log level. |
NEWSNEST_SCHEDULER | on | Set to off to disable background fetching (for development). |
.env.example sets the two paths to ./config and ./data.
Backup: open Settings → Install, backup & log out → Download database backup. It gives you a
single consistent .db file with all stories, ratings and history, and it is safe to take while the app
is running. Copy the config/ folder too: it holds your feeds and interests, which the download does
not include.
Restore: stop the container, put the backup in your data folder as newsnest.db, and start it again.
With Docker volumes (the Option A snippet), copy it in while the container is stopped:
docker cp backup.db newsnest:/data/newsnest.db.
sudo mkdir -p /opt/newsnest/config /opt/newsnest/data
sudo chown -R 1000:1000 /opt/newsnest
refs/heads/main, compose
path docker-compose.yml.NEWSNEST_PASSWORD and ANTHROPIC_API_KEY.ghcr.io; nothing is built on your server.http://<server>:3095/health, then open http://<server>:3095/.To update, choose Pull and redeploy on the stack, with Re-pull image turned on. The config and
database live in /opt/newsnest and survive redeploys.
NewsNest is a progressive web app: it gets a home-screen icon, opens full screen, and keeps your most
recent pages available offline. Browsers only offer to install over HTTPS, so open it through an
https address, for example one served by a reverse proxy, rather than http://<server>:3095.
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt pytest
.venv/bin/python -m pytest # run the tests
NEWSNEST_PASSWORD=dev NEWSNEST_SCHEDULER=off .venv/bin/python -m newsnest # the app on :8080
The first run copies config.example/ to ./config/ (git-ignored). Two helpers are useful when
adding or debugging sources:
.venv/bin/python -m newsnest.spike --source <feed-id> # fetch one source and print parsed samples
.venv/bin/python -m newsnest.runner --no-ai # one fetch-and-store tick, without AI
There is also a dev container with its own project name, port 3096 and the local ./config and
./data folders:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build
newsnest/
web.py FastAPI app: pages, settings, login, JSON endpoints
runner.py the 60-second loop: fetch due sources, then the AI steps
fetchers/ RSS/Atom and GitHub-releases fetchers
pipeline.py store items, de-duplicate by URL, record source health
grouping.py group the same story across outlets
scoring.py AI scoring and the final score
summaries.py key points, fetched from the article text
feed.py ranking and the home feed
profile*.py interests, drafting, and the weekly suggestions
discovery.py OPML import and sources on probation
db.py SQLite schema and migrations
templates/ Jinja templates static/ CSS, JS, fonts, icons
config.example/ starter config, copied to config/ on first start
tests/ pytest suite
Planned work and known limits are tracked in TODO.md.
Bug reports, ideas and pull requests are welcome. Found a bug? Settings → About & report a bug in the
app opens a new issue with your version filled in. Please open an issue first for anything big. Run
python -m pytest and ruff check . before you send a PR (CI runs the linter on every PR), and add
a test for what you change.
A local news pack for your country is an easy first PR: add a LocalPack to LOCAL_PACKS in
newsnest/packs.py with 8 to 10 national outlets across the spectrum, each checked
with newsnest.discovery.check_feed (https, working, posting in the last two weeks).
MIT, except the bundled fonts in newsnest/static/fonts/:
JetBrains Mono and
Space Grotesk are licensed under the
SIL Open Font License 1.1; their license files sit next to the fonts.
Content type
Image
Digest
sha256:6682b9758…
Size
73.2 MB
Last updated
about 9 hours ago
docker pull lucifix/newsnest