Dev.to AI 🤖 Ai 👁 0 📖 2 min read

I turned my book recommender into an AI app in a day. Here are the two bugs that taught me the most.

I read a lot of fantasy, especially romantasy, and I’ve always wanted to ask an AI for something specific, like “enemies to lovers in a fae court,” and get back real books, not made-up titles. So I built BookDNA: it rea

I turned my book recommender into an AI app in a day. Here are the two bugs that taught me the most.

I read a lot of fantasy, especially romantasy, and I’ve always wanted to ask an AI for something specific, like “enemies to lovers in a fae court,” and get back real books, not made-up titles.

So I built BookDNA: it reads a book’s “DNA” (its tropes, setting, and tone), recommends books that match, and checks every single suggestion against Open Library, so it never recommends a book that doesn’t exist.

This week I turned it into an MCP server using mcp-use and deployed it on Manufact Cloud. Now any AI chat that supports MCP can use it.

What I built

Four tools an AI can call: search_book, get_book_dna, recommend, and recommend_by_tropes. The recommend tools return a small app that appears right inside the chat: a parchment shelf of book covers, each with a one-line reason it was picked.

My favorite moment: I tested it in Manufact’s Inspector chat using a GPT model, not Claude, and it worked perfectly. One server, any AI. That’s the promise of MCP, and seeing it happen was really satisfying.

Bug 1: only one cover showed up

My first shelf showed one cover and four broken images. Every book had a valid cover link, so the data wasn’t the problem.

It turned out that older Open Library covers redirect to a different server on archive.org. MCP App widgets run with a strict security policy that lists which sites they’re allowed to load images from, and I’d only allowed Open Library. The redirected images were silently blocked. The one cover that loaded was newer and didn’t redirect.

The fix was to allow archive.org too. I also added a fallback: if a cover ever fails, the card shows a parchment “title page” with the title and author instead of a broken image.

Lesson: if your widget loads images, allow every site in the redirect chain, not just the first one.

Bug 2: everyone shared one rate limit

The server is public, so I added rate limits to protect my AI budget, including a per-user limit. Testing it against the live deployment showed something I didn’t expect: the platform’s proxy rewrites the header that identifies the user, and the address I was reading belonged to the proxy, not the user. So every user was sharing one limit.

One small change fixed it, but I only found it because I tested against the real deployment instead of trusting my local setup.

Lesson: test anything that depends on request headers against your real deployment.

How I built it

I built this with Claude Code. I made the decisions, reviewed every change, and tested it myself, and I kept a “friction log” of everything that confused me along the way. A few items are already in this post.

Try it

GitHub: github.com/ksaivarsha/bookdna
MCP server: https://calm-wave-h30fs.run.mcp-use.com/mcp

If you build MCP Apps, I’d love to hear what tripped you up.

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.