This is a submission for the Sanity Challenge, Path One: Ship an Agent That Queries Real Content
Author: Ravi Saxena (@ravi_saxena_6fd4d0ef1c9cb) — solo submission. No teammates.
What I Built
TrueStay is a resort-fee desk, not a hotel blog.
A guest types one question. The desk answers what is mandatory on top of the room rate, tonight, for this guest. It does that by loading dated feeClaim documents from Sanity and applying waiver rules. It does not search the web.
Demo hotel: Bellagio Las Vegas.
Search fails here because three official pages stay live at the same time:
- The booking calendar says the shown rate excludes the daily resort fee, next to “no hidden fees.”
- The property FAQ treats a daily resort fee as a real guest cost.
- MGM Rewards says the fee is waived for Gold+ only when the stay is booked direct.
Google that mix and you get $55, $0, and “no hidden fees” in one blob. TrueStay stores each sentence as its own claim (amount, mandatory, effectiveFrom / effectiveUntil, sourceUrl, exact quote). GROQ loads claims that are still in force. The desk then:
- adds the resort fee unless Gold+ and booked direct
- adds self-parking only if the guest said they will park
- never invents a room rate
- shows both source quotes when two current official claims disagree
If you delete amount, mandatory, or effectiveFrom from the documents, the desk cannot answer. That is the Path one test.
Demo
Live desk: https://truestay-five.vercel.app
Studio (same project): https://truestay-five.vercel.app/studio
Judge question (leave this as-is, then click Ask with GROQ):
I'm not MGM Rewards Gold. One night at Bellagio Las Vegas, I will self-park. What is mandatory on top of the room rate?
Expected:
| Extra | Amount | Why |
|---|---|---|
| Daily resort fee | $55 / night | Guest is not Gold+. Waiver does not apply. |
| Self-parking | $20 / 24h | Guest said they will self-park. Not inside the resort fee. |
| Mandatory extras total | $75 | Room rate is still whatever the calendar shows. |
Then click Gold+ guest and Ask again:
I am MGM Rewards Gold. One night at Bellagio Las Vegas, booked direct, I will self-park. What is mandatory on top of the room rate?
Expected: resort fee $0 (waiver + direct). Parking stays $20.
Conflict cards still show the calendar quote vs the FAQ vs the FTC total-price example vs the Gold waiver. Both sides stay visible. The desk does not pick a winner by keyword.
No login is required on the public desk.
Code
GitHub: https://github.com/Ravi-Saxena-kronos/truestay
Stack: Next.js 14 App Router, next-sanity, embedded Studio at /studio, one POST route at /api/ask.
The important files:
-
src/sanity/schemaTypes/hotel.tsandfeeClaim.ts— the model -
src/sanity/lib/queries.ts— current-claims GROQ -
src/app/api/ask/route.ts— parse the guest, fetch claims, refuse if the dataset is empty -
src/lib/solveStay.ts— Gold+ / direct / parking rules -
scripts/seed.mjs— Bellagio + 5 official claims -
docs/sanity-context-mcp.md— how to point a hosted agent at the same content through Sanity Context
.env.local is gitignored. Write tokens are not in this repo and not in this post.
How I Used Sanity
I modeled the problem as atomic claims, not pages.
hotel is a name, brand, city, official URL.
feeClaim is one dated fact about that hotel:
-
feeType— resort, self-park, waiver, advertised-rate-excludes-fees, or law-total-price -
amount,currency,per -
mandatory,includedInAdvertisedRate -
bookingChannel(direct/ota/any) minLoyaltyTier-
effectiveFrom/effectiveUntil -
sourceName,sourceUrl,quote,observedOn
GROQ used by the desk:
*[_type == "feeClaim"
&& (
hotel._ref == $hotelId
|| hotel->name == $hotel
|| hotel->name match $hotelPattern
)
&& (!defined(effectiveUntil) || effectiveUntil >= $stayDate)
] | order(feeType asc) {
_id, feeType, amount, currency, per, mandatory,
includedInAdvertisedRate, bookingChannel, minLoyaltyTier,
condition, effectiveFrom, effectiveUntil,
sourceName, sourceUrl, quote,
"hotelName": hotel->name
}
That query is why this is not search. Search can find the words “Gold” and “$55” on the same page. It cannot filter “still in force on the stay date,” follow hotel._ref, or apply “waiver only if Gold+ and booked direct.”
Seeded Knowledge Base sources (re-checked against the live URL on ingest day 19 Sep 2026):
- https://www.mgmresorts.com/en/mgm-rewards/daily-resort-fee-waiver.html
- https://bellagio.mgmresorts.com/en/faq.html
- https://bellagio.mgmresorts.com/en/amenities/parking.html
- https://bellagio.mgmresorts.com/book-room/dates/
- https://www.ftc.gov/business-guidance/resources/rule-unfair-or-deceptive-fees-frequently-asked-questions
The same URLs are the ingest list for a Sanity Knowledge Base / Context MCP endpoint (initial_context, then groq_query with the filter above). The public judge demo is the GROQ desk so anyone can click Ask without installing an MCP client.
Honest limit: fee amounts can change. The desk answers from the dated quote we stored, not from a live scrape. If MGM updates the FAQ, edit the claim in Studio. That is the point of structured content.
Sanity Project Details
- Project ID:
7i0vhp5u - Dataset:
production(public so judges can inspect documents) - Types:
hotel,feeClaim - Studio: https://truestay-five.vercel.app/studio
- Live desk: https://truestay-five.vercel.app
One hotel document (hotel.bellagio) and five feeClaim documents:
_id |
Type | Amount |
|---|---|---|
claim.bellagio.resort |
resort | 55 / night |
claim.bellagio.waiver |
waiver | 0 (Gold+, direct, max 2 rooms) |
claim.bellagio.parking |
parking_self | 20 / 24h |
claim.bellagio.calendar |
advertised_rate_excludes_fees | calendar is room-only |
claim.ftc.total |
law_total_price | advertised total must include mandatory fees |
Agent Session
Optional native upload is not attached yet. Design thread (no tokens):
User: Path one hotel topic that wins — structured claims, not search.
Agent: Official sources disagree on resort fees. Calendar excludes the fee, FAQ treats it as a cost, Gold+ waiver is only for direct booking. Demo: Bellagio. Schema: hotel + feeClaim with amount, dates, sourceUrl, quote.
User: Scaffold it.
Agent: Seeded resort $55, waiver $0 Gold+ direct, self-park $20. Non-Gold + park → $55+$20. Gold+ → resort $0, parking $20. Delete amount / mandatory / effectiveFrom and the desk cannot answer.
Top comments (0)