DEV Community

Cody Topp
Cody Topp

Posted on

ShelfReady: A Private KDP Listing Studio That Runs Gemma on Your Own Machine

Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle Submission ๐Ÿ’ธ

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

ShelfReady: a finished colouring-book listing scoring 100 on the KDP checks

What I Built

I'm a designer and an independent publisher. Part of my business is colouring books on Amazon KDP, and the slowest part of every launch isn't the artwork. It's the listing: a title, a subtitle, a description and seven keyword boxes, each with its own limits and rules.

General-purpose AI tools make that job faster, but they don't make it safer. Ask one for a colouring-book listing and you'll often get "Bestselling Coloring Book ยท Perfect Gift ยท Free Bonus Pages". Each of those phrases breaks KDP's metadata guidelines. Sales-rank claims, "free", program names and other people's brands can all get a listing flagged or suppressed. Speed isn't worth much if the output can't go live.

ShelfReady is the tool I wanted for my own workflow. You give it the facts about your book: theme, audience, style, number of designs, trim size and marketplace. In about 40 seconds, on an ordinary 8-core CPU with no GPU, it returns:

  • a title and subtitle with a live 199-character meter,
  • seven keyword phrases, each counted against KDP's 50-character box,
  • a formatted HTML description using only the tags KDP supports,
  • and a KDP readiness score with every issue explained in plain English.

Every field stays editable, and the checks re-run as you type. Copy each field straight into KDP, or export the whole listing as a text file.

Who pays for this? KDP has a large community of low-content and colouring-book publishers, most of them running lean side businesses. They already pay for keyword research tools and listing templates. I'd price ShelfReady for that market as a one-time licence, somewhere in the $19 to $29 range. Because the model runs locally, my cost per listing is zero, so that price can stay low without the product losing money every time someone clicks Generate.

Demo

ShelfReady demo: sample brief, local generation (sped up), live KDP checks

The 29-second demo above is a real run with nothing staged. The generation segment is sped up 15ร— and labelled as such. The full-resolution MP4 is in the repo: docs/shelfready-demo.mp4.

The two moments that matter most:

1. The checks catch what a tired human misses. Typing "Bestselling Edition" into the title drops the score from 100 to 80 and flags it instantly as prohibited sales-rank language.

Live check flags a banned word

2. When something's wrong, it tells you what to do. No stack traces. If Ollama isn't running or the model isn't installed, you get the exact command to fix it.

Clear, actionable error state

Code

GitHub logo ctopp11 / shelfready

Private, local-first KDP listing studio for colouring-book publishers. Gemma 3 via Ollama + a deterministic KDP rules engine.

ShelfReady

A private, local-first KDP listing studio for colouring-book publishers. Give it the facts about your book. It writes the title, subtitle, a formatted description and all seven keyword boxes using Gemma 3 running on your own machine through Ollama, then checks every line against Amazon KDP's published metadata rules before you paste anything into KDP.

ShelfReady: a finished listing that scores 100/100 on the KDP checks

Built for the DEV ร— Hacktoberfest 2026 Open-Source AI Challenge, Week 2: Side Hustle.


Why it exists

Writing a KDP listing takes longer than most people expect, and mistakes cost real money. Generic AI tools will happily write "Bestselling Coloring Book, Perfect Gift, Free Bonus Pages". Every one of those phrases breaks KDP's metadata rules and can get a listing suppressed. ShelfReady splits the job in two:

The model (Gemma 3, local) The rules engine (plain Python, deterministic)
Writes persuasive, specific copy from your facts Enforces KDP's character limits, banned terms, allowed
โ€ฆ

ShelfReady is pure Python standard library plus vanilla HTML, CSS and JS. There's no pip install and no build step. It's MIT licensed.

ollama pull gemma3:4b
python3 -m shelfready      # โ†’ http://127.0.0.1:8787
Enter fullscreen mode Exit fullscreen mode

How I Built It

The model: Gemma 3 4B, running locally through Ollama. I chose Gemma 3 4B because it hits the balance this product needs: small enough (about 2.5 GB quantised) to run on the CPU of an ordinary publisher's computer, and capable enough to write specific, buyer-focused copy. ShelfReady calls Ollama's /api/chat with structured outputs: a JSON schema that forces exactly four fields and exactly seven keywords. That rules out the whole "the model returned prose instead of JSON" class of failures by design.

The design decision that matters: the model writes, the code decides. I don't trust any language model, open or closed, to enforce a 50-character limit or remember that "Kindle Unlimited" is banned in keywords. So the architecture separates the two:

brief โ†’ validate โ†’ Gemma drafts (streamed) โ†’ sanitise โ†’ mechanical fixes โ†’ KDP rules engine
                                                                         โ†“ blocking errors?
                                                  Gemma repairs, with the exact errors fed back
Enter fullscreen mode Exit fullscreen mode
  • kdp_rules.py is a deterministic rules engine. Each rule maps to a line in KDP's public help pages on metadata, keywords and descriptions. It covers combined title length, the 60-character skim threshold, promotional and time-sensitive language, Amazon program names, a trademark tripwire, quotation marks and HTML in keywords, plural and word-order duplicates, keywords that only repeat title words, the 4,000-character description limit, KDP's short list of allowed HTML tags, and contact details, emoji and review requests in descriptions. It's covered by 27 unit tests.
  • Mechanical fixes are automatic, and every one is disclosed. If Gemma leaves bare paragraphs (Amazon collapses newlines), forgets to close a <li>, or writes "colouring" in a keyword for Amazon.com (US shoppers type "coloring"), ShelfReady fixes it and adds an "auto-fixed" line saying exactly what changed. Judgement calls are never auto-fixed. They're flagged for you to decide.
  • One targeted repair pass. If blocking errors remain, the exact error messages go back to Gemma for a single revision. That's cheaper and more reliable than regenerating from scratch.
  • Streaming UX. The server streams progress as NDJSON, so the interface shows a real progress bar and character count instead of a frozen spinner, and Cancel stops the model on the server instead of just hiding the spinner.
  • Safe rendering. The description preview is rebuilt node by node, keeping only KDP's allowed tags and no attributes, so model output can't inject anything into the page.

As a designer, I held the interface to the same standard as my books. It has a warm paper palette, one deep forest accent, a serif for the moments that should feel editorial, and nothing on screen that doesn't help you ship a listing.

Full disclosure: this was built with heavy AI assistance. An AI coding agent wrote the code and drafted this write-up, working to a brief built around how my KDP business actually runs. The rules philosophy and the design standard are the ones I hold my own books to. That feels like the honest way to build in 2026, and it's exactly the leverage this challenge is about.

Why Does Open Innovation Matter?

For this product, open weights aren't a philosophy. They're what make the business viable.

  1. The unit economics work. A listing tool lives on volume. Publishers regenerate, tweak and regenerate again. With a hosted API, every click is a cost I'd have to pass on or absorb. With Gemma on the user's own machine, the marginal cost of a listing is zero, so a small one-time price works.
  2. Unreleased books stay private. A publisher's upcoming catalogue is competitive information. ShelfReady binds to localhost and sends the brief nowhere. There's no account, no API key and no third-party log of what you're launching next quarter.
  3. No platform risk. Hosted APIs change prices, deprecate models and adjust behaviour without notice. ShelfReady runs on a model file I can keep, so the listing that worked in October still works in March.
  4. I can tune the stack to the niche. Swapping models is one environment variable (SHELFREADY_MODEL=gemma3:12b). Open weights also leave room for the obvious next step: fine-tuning a small Gemma on KDP-compliant colouring-book listings.

The trade-off is honest too: on a CPU-only machine a listing takes around 40 seconds instead of a few. For a task you do once per book, I'll take private, free and permanent over instant.

Prize Categories

Best Use of Gemma. Gemma 3 4B, running locally via Ollama, is the engine of the product. It writes every listing and performs the repair pass, and it's constrained by Ollama structured outputs and a deterministic KDP rules engine.

Top comments (0)