DEV Community

Cover image for Everlogue’s Reading Companion - a book recommendation agent grounded in structured Sanity
Sophia Castillo
Sophia Castillo

Posted on

Everlogue’s Reading Companion - a book recommendation agent grounded in structured Sanity

Sanity Challenge Path One Submission

This is a submission for the Sanity Challenge, Path One: Ship an Agent That Queries Real Content

What I Built

Everlogue is a home for everything you read. It brings together a book catalog, private reading shelves, celebrity book-club selections, and Ask Everlogue, a Reading Companion grounded in structured Sanity content.

The catalog began with selections from four clubs: Reese’s Book Club, Oprah’s Book Club, Read with Jenna, and GMA Book Club. From there, it grows through its readers.

Readers can import their Goodreads CSV files to bring over their Want to Read, Currently Reading, and Read shelves. They can also search for a book and add it to an Everlogue shelf. If that book isn’t already in the catalog, the addition creates a request for review. Once reviewed and approved, the book joins the shared catalog and becomes available for discovery and recommendations.

That growing catalog is the foundation of Everlogue’s Reading Companion. I wanted it to feel like talking to a thoughtful friend in a bookshop—someone who listens to what you want today and helps you find something you’ll enjoy.

When a reader asks, “What should I read next?”, the companion starts with:

What are you in the mood for—or what’s a book you loved and want something similar to?

Their answer guides the search across the full approved Everlogue catalog, including suitable books on their Want to Read shelf. For signed-in readers, books already read or currently being read are excluded. The companion returns three recommendations with short, personal, spoiler-free explanations, grounded in books that actually exist in Everlogue.

For readers who want to explore a book further, I established a Sanity Context Knowledge Base using six website sources containing book-club announcements, summaries, and author interviews. I reviewed the generated entries covering book premises, themes, club selections, and author conversations, checked their citations, and made corrections.

I then configured a dedicated MCP endpoint, Everlogue Book Knowledge, so the companion could retrieve supporting material for questions about books. Its instructions require sources for factual claims, discourage unnecessary spoilers, and keep the conversation warm and natural. I selected OpenAI gpt-5.4-mini as the starting model.

The two sources serve different purposes: the structured catalog determines which books the companion can recommend, while the knowledge base supports deeper, source-backed conversations about them.

As readers contribute more books and those additions are approved, Everlogue’s catalog grows—and the Reading Companion gains more possibilities to help someone find their next read.

Demo

https://www.everlogue.app/

Code

https://github.com/sphcastillo/everlogue

The companion lives in:

  • src/lib/companion-agent.ts — recommendation path vs Sanity Context MCP path
  • src/lib/companion-catalog.ts — GROQ catalog search, shelf exclusions, Want to Read
  • src/lib/companion-selection.ts — interpret the request, pick three supported candidates
  • src/app/api/companion/route.ts — authenticated shelf context, then the agent
  • docs/reading-companion.md — how Context and recommendations are wired

How I Used Sanity

Building the Knowledge Base

I added six website sources containing book-club announcements, summaries, and interviews to Sanity Context. The generated entries covered book premises, themes, selections, and author conversations. I reviewed the generated content, investigated citations, and made corrections rather than treating ingestion as the end of the editorial process.

I created a dedicated Everlogue Book Knowledge MCP endpoint. The companion’s instructions emphasize factual support, a warm personal tone, and avoiding unnecessary spoilers.

For Knowledge Base questions, the server connects through an MCP client and gives the model the tools exposed by the endpoint:

  • initial_context establishes how to navigate the Knowledge Base.
  • knowledge_base_search finds relevant entries.
  • knowledge_base_read retrieves supporting content.

The agent must retrieve content before answering. Its instructions require it to ground book facts in that retrieval and cite source titles and URLs it actually used. Responses stream into the existing companion interface. The Context token stays on the server, and the MCP connection closes when the response finishes or is interrupted.

In an end-to-end check, I asked about The Christie Affair. The companion called the Context tools, identified Nina de Gramont, and returned a source-backed answer. I checked tool activity as well as the text of the response.

Connecting knowledge to a reader’s library

The companion uses two complementary content paths. Knowledge Base questions go through Sanity Context MCP. Recommendations query the structured catalog directly with GROQ through @sanity/client.

That distinction matters: a book does not need an ingested article or Knowledge Source link to be recommended. A reader-imported title can qualify through its catalog description and genres. Article-backed answers use retrieved sources; catalog-based recommendations do not invent article citations.

Sanity stores the relationships that make personalization possible: books and genres, reader profiles, shelves and shelf entries, ratings, and reviews. Optional page-count and series information support explicit constraints when that information is available. The authenticated reader’s identity determines which shelf entries and feedback apply.

The recommendation flow interprets the request, retrieves eligible candidates, selects up to three, and writes short explanations from the supplied metadata. It combines the reader’s current mood with structured eligibility checks and their own feedback. Missing metadata is not permission to invent a fact.

What I worked through while building

Much of the work was deciding what “helpful” should mean. We refined rules around low ratings, current preferences, series order, repeated suggestions, and the difference between a contextual book mention and a request for something similar.

I also kept the model and added measurement: per-question token counts, cached input, estimated cost, duration, and outcomes are saved in Sanity. Daily usage limits and smaller, relevant context help prepare the companion for visitors. Two live test questions recorded about $0.015 combined in estimated model cost—a small test sample, not a forecast.

Testing the surrounding experience mattered too. A first-sign-in failure exposed a profile-resolution problem after Clerk authentication. We changed setup to use the profile returned by Sanity’s creation transaction and made retry lookups bypass request memoization. We also moved homepage personalization behind separate loading boundaries and parallelized independent queries, keeping library data fresh.

The final hurdle was to make it clear what circumstances the reader companion should ask the knowledge base over the catalog. Also, we had to make sure source names and URLS are stripped from replies, and strip filler like “the book” from catalog lookups so “Tell me about the book The House in the Pines” searches the real title instead of a phrase that isn’t in the catalog.



I know I'll still be tinkering with it, but I'm currently really happy with today's Ask Everlogue.

Sanity Project Details

  • Project ID: 3h0o1unw
  • Dataset: production (private)
  • Organization Context endpoint: Everlogue Book Knowledge (everlogue-book-knowledge)

The dataset contains reader information, so I am sharing the project ID rather than making the dataset public. The Context endpoint uses a server-side organization token with Context → Viewer permission.

Agent Session

I worked with Codex & Cursor to turn the reading experience into implementation rules, connect the MCP endpoint, verify retrieval, and test edge cases. The most useful parts of that process were tracing where an answer came from and deciding what the companion should do when information was missing.

Credits

Built with Sanity Content Lake, GROQ, Sanity Studio, Sanity Context, next-sanity, the Vercel AI SDK MCP client, OpenAI gpt-5.4-mini, Clerk, and Next.js.

Top comments (0)