Turning a Book Recommender into an AI App in One Day: MCP Development Pitfalls

A developer turned BookDNA into an MCP server in one day; two bizarre bugs exposed hidden traps in real deployment.
A developer transformed the book recommendation tool BookDNA into an MCP server in one day using mcp-use on Manufact Cloud, exposing four tool interfaces. Two bugs stood out: legacy Open Library cover redirects blocked by the MCP component's security whitelist, and a platform proxy rewriting user-identifying headers so all users shared one rate limit. The lessons: allow the entire redirect chain, and test request-header behavior in real deployments.
A developer, driven by a personal craving for fantasy romance novels with a "fae court enemies to lovers" premise, spent a single day transforming his existing book recommendation tool BookDNA into an AI application and deploying it as an MCP server. Along the way, two seemingly bizarre bugs taught him valuable lessons.
From Book Recommender to MCP App: The Birth of BookDNA
The core idea behind BookDNA is to extract a book's "DNA" — its tropes, setting, and tone — and then recommend matching books based on those traits. Most importantly, every recommendation is verified for authenticity through Open Library, ensuring no nonexistent books are suggested.
This transformation used the mcp-use framework and deployed the service on Manufact Cloud, turning it into an MCP (Model Context Protocol) server. Any MCP-compatible AI chat tool can call it. The author exposed four tool interfaces: search_book, get_book_dna, recommend, and recommend_by_tropes. The recommendation tool returns a small app directly in the chat interface — a parchment-style bookshelf, with each book's cover accompanied by a one-line recommendation reason below it.
What excited the author most was that when testing in Manufact's Inspector chat using a GPT model (rather than Claude), everything worked flawlessly. The same server, compatible with any AI — this is precisely the vision the MCP protocol promised, and witnessing it materialize was satisfying.

MCP (Model Context Protocol) is a communication standard proposed and open-sourced by Anthropic in late 2024, designed to let AI applications connect to external tools and data sources in a unified way. Before MCP, if a developer wanted different AI assistants (such as Claude, GPT, or various IDE plugins) to call the same tool, they often had to adapt the interface separately for each platform. MCP decouples capability providers from callers by defining a standardized server-side protocol — including three primitives: tools, resources, and prompts. Any AI chat tool that implements an MCP client can discover and call protocol-compliant servers without code changes. In this article, BookDNA encapsulates book recommendation capability as an MCP server, which is why it can plug and play in GPT models beyond Claude.
mcp-use is a Python-based MCP development framework that simplifies tool declaration, parameter validation, and server deployment. Its Inspector chat interface allows real-time debugging of MCP tool calls, making it an essential tool for validating behavior during development.
Bug 1: Only One Cover Displays Correctly
On the first test, only one cover loaded correctly on the bookshelf; the other four appeared as broken images. But after checking the data, every book's cover URL was valid — the problem wasn't at the data level.
After investigation, the cause emerged: legacy Open Library covers redirect to a different server on archive.org. The MCP App component runs under a strict security policy that only allows images from whitelisted sites, and the author had only allowed Open Library, so the redirected images were silently blocked. The one cover that loaded successfully happened to be a newer link without redirection.
The fix was to add archive.org to the allow list. The author also added a fallback: if a cover fails to load, the card displays a parchment-style "title page" showing the book title and author, rather than a broken image.
Takeaway: If your component needs to load images, make sure to allow every site in the redirect chain, not just the first one.
MCP App components typically run in a sandboxed iframe or controlled WebView, enforcing a Content Security Policy (CSP). The CSP img-src directive restricts allowed image source domains via a whitelist; domains not on the list are silently blocked by the browser — the request never even fires, and developers only see blocking logs in the console while the front end shows broken images. What's more insidious here is the redirect chain: when the browser validates image loading redirects, it checks whether the final landing page's domain is also whitelisted; intermediate redirect domains also need to be allowed. Legacy Open Library cover links often 302 to archive.org, so whitelisting only openlibrary.org isn't enough. In practice, the allow list should cover the entire redirect chain, or you should proxy image requests to consolidate domains. The "parchment fallback card" mentioned in the article is a more robust strategy: even if loading fails, users still see the title and author, avoiding a broken icon ruining the experience.
Bug 2: All Users Share the Same Rate Limit
Since the server is public, the author added rate limiting to protect his AI call budget, including per-user rate limits. But when testing against the live deployment, something unexpected happened: the platform's proxy rewrites the request header identifying the user, and the address the code read was actually the proxy's address, not the real user's. As a result, all users shared the same rate limit quota.
The change was small, but discovering the problem depended entirely on testing against the real deployment environment, not trusting the local dev environment.
Takeaway: Any feature that depends on request headers must be tested against the real deployment environment.
A server running behind a reverse proxy or cloud platform (such as Manufact Cloud, Vercel, etc.) typically sees the proxy itself as the direct connecting party, not the end user. To address this, the HTTP protocol defines a series of forwarding headers: X-Forwarded-For records the original client IP, X-Forwarded-Proto records the original protocol, and X-Real-IP is often used to store a single-value client address. Different platforms handle these headers differently: some append, some rewrite, some strip. If code directly reads request.client.host or the wrong forwarding header field, it will identify all users as the same source, breaking per-user rate limiting, risk control, canary releases, and more. The safe approach is to prioritize platform-provided identity markers (such as authenticated user IDs), or confirm in the documentation which header the proxy preserves, and verify identification results using multiple egress IPs in the real deployment environment.
Development Approach and Toolchain
The entire project was built using Claude Code. The author emphasizes that he made all decisions, reviewed every change, and tested everything personally, while maintaining a "friction log" recording every confusing point during development.
This development model reflects a pragmatic direction for AI-assisted programming today: AI accelerates implementation, humans handle judgment and verification.
The "friction log" is a common practice in product and engineering teams: developers record, from a first-person perspective, every confusing, clunky, or counterintuitive part of using their own tool, as a basis for improvement. It stems from an internal "dogfooding" culture, and companies like Google and Stripe have similar mechanisms. In the era of AI-assisted programming, the value of friction logs is further amplified: AI can rapidly generate large amounts of code, but the real experience of every step a human developer takes — including which prompts repeatedly fail and which changes require multiple rollbacks — is the key data for judging whether a toolchain is usable. By maintaining a friction log, the author is essentially building a feedback loop for the division of labor where "AI accelerates implementation, humans handle judgment," turning vague discomfort into trackable, fixable, concrete items.
How to Try It
The project is open-sourced on GitHub: github.com/ksaivarsha/bookdna, and the MCP server address is https://calm-wave-h30fs.run.mcp-use.com/mcp. If you're also building MCP applications, the author would love to hear what pitfalls you've encountered.
These two bugs reveal a common lesson: in MCP and AI application development, the gap between the local environment and the real deployment is often where the problem lies. Security policies, proxy behavior, request header rewriting — these infrastructure-level details only surface when the online environment is fully tested. For developers entering the MCP ecosystem, this is a highly valuable practical reference.
One-line Summary
A developer turned BookDNA into an MCP server in one day, and two bizarre bugs revealed hidden traps in real deployment environments.
Paragraph Summary
A developer transformed his existing book recommendation tool BookDNA into an MCP server, deployed on Manufact Cloud using the mcp-use framework, letting any MCP-compatible AI chat tool call it, with four tool interfaces for search, DNA extraction, and recommendations. During one day of development, two bugs provided key lessons: first, legacy Open Library covers redirect to archive.org, but the MCP component's security policy only allowed Open Library, causing covers to be silently blocked; the fix requires allowing the entire redirect chain. Second, the platform proxy rewrites the user identification header, causing all users to share the same rate limit quota; only testing against the real deployment environment can uncover this. The author used Claude Code as the primary build tool, insisting on human decision-making and verification, ultimately open-sourcing the project and distilling the core lesson: the infrastructure gap between local and online is the biggest hidden risk in MCP application development.
Related articles

JobRunner MCP Server: AI Agents Can Now Fix Failed Java Jobs
JobRunner launches an open-source MCP server enabling AI agents to view cluster status, diagnose failures, and recover Java jobs—incident response from any cloud coding environment or existing agent.

MLAI Digital Launches 9 Security Agents: MCP Server Safeguards the Full Lifecycle of Agentic AI
MLAI Digital launches Security MCP Server with nine built-in specialized security agents covering vulnerability discovery, attack simulation, prompt injection detection, API and infrastructure assessment, and accelerated remediation—embedding security validation across the full Agentic AI lifecycle from development to production.

Running Isaac Lab on H100 GPUs: Exploring Better Approaches
Exploring optimization methods for running Isaac Lab on NVIDIA H100 GPUs, including MIG configuration, mixed precision, TensorRT acceleration, and community experience to improve robotics simulation and reinforcement learning efficiency.