Self-hosted · local-first

A feed reader with pipes.

Tributary pulls RSS and Atom feeds into one quiet inbox, then lets you reshape the stream with small boxes: fetch, merge, filter, summarize, read. It runs on your machine, and the model boxes use Ollama locally.

No account. No cloud. One SQLite file.

morning-read.jsonDone · 12 items
Fetch
2 feeds · RSS / Atom
Filter
keyword: databases
SummarizeAI
local model · gemma3:1b
Read
12 items · unread
A pipe is a chain of boxes. Each box takes a list of items and returns a list.

A reader that stays quiet

Unread, starred and labeled items, with keyboard shortcuts for moving, starring and marking read. No algorithm decides what you see.

Pipes, not rules

Drag Fetch, Merge, Dedupe, Filter, Sort, Limit and Full text boxes onto a canvas. Save the chain as JSON you can read, edit and run from the CLI.

A local model in the chain

Summarize each item, keep only what matches a meaning, or add a “why you’d care” line. The AI boxes call Ollama on the same machine.

How it was built

Two local processes, one JSON spec.

The API is a small FastAPI service over SQLite. Feeds are fetched with httpx, parsed with feedparser and cleaned with trafilatura. Pipes are JSON specs executed by a box engine; the CLI and the API run the same spec. The reader is Next.js App Router with TanStack Query, and the editor is a React Flow canvas. AI boxes call Ollama through one local client and cache each answer in SQLite.

Reader
Next.js 16 App Router · React 19 · Tailwind CSS · TanStack Query
Editor
React Flow canvas · JSON pipe specs
API
FastAPI · SQLAlchemy · SQLite
Fetching
httpx · feedparser · trafilatura
Model
Ollama · summaries, meaning filters, why-care
Search
SerpAPI, optional · refined by the local model
Storage
One SQLite file · no accounts

Start with the reader.

Build a pipe when you want to reshape the stream.