Kindle Agent
A private, invite-only book search that sends any title straight to my family's Kindles — five sources, one tap.
The problem
I read on a Kindle, and so do my mom and sister. Getting a book on there means a weeks-long Libby hold or Amazon's price — and Send-to-Kindle is a manual hunt-download-email loop where half the EPUBs you find fail silently.
My hypothesis
Put a search box in front of every free and self-hosted source, wire it into Amazon's Send-to-Kindle pipe, and the whole dance collapses to one tap. The bet: aggregation plus reliable formatting is the product, not any single source.
What I built
An invite-only Next.js app with magic-link and password auth. Search fans out across five sources — Standard Ebooks, Gutenberg, Open Library, LibGen, and a self-hosted torrent bridge — deduped into one ranked list, then the pick is cleaned through Calibre and emailed to your Kindle via Resend. The torrent source runs on a free Oracle VM (Jackett + qBittorrent + Calibre in Docker, over Tailscale). Built for three accounts from day one — my mom and sister each get their own library and history.
What broke
Amazon rejects almost every EPUB on the internet with an opaque E999 error. I burned time on AZW3 and MOBI before finding the fix: run every file through Calibre, which re-zips it to spec. Magic links kept dying to Gmail's link prefetcher, so the token consume had to go POST-only. And LibGen ranks so badly that "the nightingale" returns Florence Nightingale biographies.
What I learned
The reliability layer is the product, and it's invisible until it fails. Building for three users instead of one forced the real work — uniqueness checks, send caps, and a bounce webhook so a silent delivery failure actually surfaces.
If I kept going
Per-job fetch tokens so a leaked bridge token can't pull any file. Query enrichment to fix LibGen's ranking. And smoother onboarding for the one manual step every user still does themselves — allowlisting the sender on Amazon.
What was built
Frontend & Auth
Invite-only app, magic-link + password
- Next.js 16 / React 19
- Tailwind CSS 4
- Magic-link + password (bcryptjs)
- Upstash Redis (users, history)
Search Aggregation
Five sources deduped into one ranked list
- Standard Ebooks
- Project Gutenberg
- Open Library
- LibGen
- Self-hosted torrent bridge
- Source + seeder chips per result
Send Pipeline
Calibre clean → Resend → Kindle
- Calibre EPUB reparse (the E999 fix)
- Resend (kindle@schlacter.me sender)
- Per-user Kindle address
- 20/day per-user send cap
Torrent Bridge
Self-hosted, zero-cost, publicly reachable
- Oracle Cloud always-free VM
- Tailscale Funnel (public HTTPS)
- Jackett + qBittorrent
- Flask + Calibre in Docker
Multi-user Safety
Built for three accounts from day one
- Kindle-address uniqueness index
- Per-user send quota
- Resend bounce webhook
- Delivery test + drift banner



