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,

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.
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.
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.
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.
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.
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.
Expand Meg Hildreth Meg Hildreth Meg Hildreth Follow Joined Oct 14, 2026 • Oct 14 Dropdown menu Copy link Hide i work at manufact this is awesome to see!! thanks for sharing