← Hannah Schlacter
ConsumerAIFull-StackAutomation

Kindle Agent

A private, invite-only library for my family and friends: search free sources for a book or an audiobook, and get it on a Kindle or straight onto your phone.

✨ Amazon silently rejects most EPUBs on the internet, so the file-repair step ended up being the whole product. Once my family was depending on it, diagnosing failures mattered just as much — a break nobody can explain reads the same as a product that's broken.

The problem

I read on a Kindle, and so do my mom and my 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. Once other people started using it, a second problem showed up: when it broke, nobody could tell me what happened. They just stopped getting books.

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 auth. One search fans out across five sources in parallel — Standard Ebooks, Gutenberg, Open Library, LibGen, and a self-hosted torrent bridge — deduped into a single ranked list. The pick is repaired to spec and delivered. Delivery has two modes, because not everyone reading is on a Kindle. Kindle users get the file emailed. Everyone else downloads it straight to the device, which turned out to be the harder path — an iPhone home-screen app has no download manager, so a JavaScript blob download silently does nothing. That path navigates the page to a GET route instead, and iOS then offers Open in Books or Save to Files. It has grown well past search-and-send. Audiobooks run as a deliberately separate subsystem, since a 700MB .m4b breaks every assumption the ebook path makes. Want to Read watches for a book you couldn't get yet and delivers it the moment a copy appears. Followed Book Lists tracks what real book clubs are reading each month and tells you when a new pick lands. A shared EPUB cache means the second person to want a book gets it instantly.

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: rewrite the file to spec, which is the actual product. Magic links kept dying to Gmail's link prefetcher, so the token consume had to go POST-only. The failure I didn't predict was legibility. Search would return nothing and there was no way to know whether the book didn't exist, a source was down, or the query was worded wrong. Three books failed in one day for three different reasons, and the telling one had a perfectly spelled title whose file simply has no author in the name, so including the author is what lost it. Searching one way and calling that the answer was the bug.

What I learned

When other people depend on your side project, the work shifts from adding features to telling the truth about failures. Every empty search now records what each source actually did, and the admin page will name which LibGen mirror timed out. A search tries the title with the author, then the title alone, then the title without its subtitle, then the author alone. The constraint I'm most glad I kept: no LLM or search API key anywhere in the product. Anything that needs open-ended reasoning runs as an MCP server on the user's own Claude, so the app stays deterministic, free to run, and never breaks because a key expired.

If I kept going

Per-job fetch tokens so a leaked bridge token can't pull any file. Better onboarding for the one manual step every user still does themselves: allowlisting the sender on Amazon. And a real answer for the books no source has, which is still the honest gap.

What was built

Frontend & Auth

Invite-only, installable as a home-screen app

  • Next.js 16 / React 19
  • Tailwind CSS 4
  • Magic-link auth, 30-day sessions
  • Upstash Redis
  • Versioned What's New splash

Search Aggregation

Five sources in parallel, one ranked list

  • Standard Ebooks
  • Project Gutenberg
  • Open Library
  • LibGen
  • Self-hosted torrent bridge
  • Four-way query fallback on a miss

Delivery

Kindle email or direct to device

  • EPUB rewritten to spec (the E999 fix)
  • Resend to a per-user Kindle address
  • In-place GET download for iOS home-screen apps
  • Shared EPUB cache for repeat books
  • Per-user send cap

Audiobooks

A parallel subsystem, not a bolt-on

  • Download-only, a Kindle can't play one
  • 100MB to 1GB .m4b or bundled .mp3
  • Its own queue, routes, and progress UI
  • Per-device save instructions

Discovery

Finds books you're not searching for

  • Want to Read auto-delivers on availability
  • Followed Book Lists tracks club picks
  • Monthly pick notifications
  • Reading status, ratings, and stats

Reliability

Every failure has to be answerable

  • Per-source outcome on every empty search
  • Named LibGen mirror failures
  • Live bridge health check
  • Per-person admin drill-down
  • Resend bounce webhook

Prototype

The front door: a private, invite-only library for family and friends. A book can land on a Kindle or download straight to the device you are holding.

The front door: a private, invite-only library for family and friends. A book can land on a Kindle or download straight to the device you are holding.

One search fans out across every source at once, each result tagged with where it came from. The Books/Audiobooks toggle switches to a separate audiobook pipeline.

One search fans out across every source at once, each result tagged with where it came from. The Books/Audiobooks toggle switches to a separate audiobook pipeline.

Your library: covers, Goodreads ratings, reading status, and filters by genre or by the book list a title came from.

Your library: covers, Goodreads ratings, reading status, and filters by genre or by the book list a title came from.

Want to Read: books no source had yet, and who recommended them. The app keeps watching and delivers one the moment a copy appears.

Want to Read: books no source had yet, and who recommended them. The app keeps watching and delivers one the moment a copy appears.

Followed Book Lists: follow a public club and its monthly picks show up here, with a notification when a new one lands.

Followed Book Lists: follow a public club and its monthly picks show up here, with a notification when a new one lands.

View live ↗