Try it (about 3 minutes)

  1. Open https://homestand-6az.pages.dev/#/check/portland-me. It's a sample club (Portland, Maine) with the season already checked.
  2. Tap any card to flip it and see why it got that rating. Get fresh data asks Qloo again.
  3. Hit Fix. Tear the pack, look at each swap next to the night it replaces, and approve or reject it.
  4. Hit Send to download the new calendar (CSV or .ics) and a one-page memo.
  5. Go back, choose Use your own, pick a sport, search your own town (any US or Canadian city), press Load an example and run it. A city nobody has tried yet gets scored live with Qloo right there.
  6. Basketball sample: https://homestand-6az.pages.dev/#/check/boise, a made-up team in Boise with a November-to-April season.
  7. Concert venue sample: https://homestand-6az.pages.dev/#/check/raleigh, a made-up summer series at a sample amphitheatre.
  8. Open The Study, make your own call, then see what 385 real 2025 nights showed.
  9. From an AI assistant: add https://homestand-api.ramenprotokol.workers.dev/mcp as a custom connector in Claude and ask "Check the Portland sample and fix the weak nights." Or list the tools from a terminal: npx @modelcontextprotocol/inspector --cli https://homestand-api.ramenprotokol.workers.dev/mcp --transport http --method tools/list

Inspiration

Minor League clubs run dozens of theme nights every season, and most of them are sold to sponsors. Directors pick them from staff ideas and fan surveys. Nothing tells a club whether its own town likes Bluey more than Margaritaville. That's exactly the question Qloo can answer for a location, so I built the tool a promotions director would actually open in October, when next season gets planned.

What it does

Homestand turns a club's season into a deck of foil baseball cards, one card per theme night, and works in three steps: Check, Fix, Send. It runs for any city in the US (50 states and DC) or Canada, and for baseball, basketball, hockey or soccer. Pick the sport and the words, season and proven promos follow: ballpark becomes arena, first pitch becomes tip-off or puck drop. The scoring doesn't change by sport, because it only asks what the town likes.

Check. Every night is rated Strong fit, Average fit or Weak fit compared with the town's other themes. If the raw gap behind a Strong or Weak label is under 0.01, the card says Leans strong or Leans weak instead, and any swap for it is optional. Qloo's own docs say a gap like 0.91 vs 0.92 usually means similar relevance, so I don't push those.

  • Tap a card and it flips to one plain sentence, like "Biloxi likes Star Wars less than its other themes." The Qloo entities, the comparison with 40 other towns and the raw numbers sit behind "Show the numbers".
  • A name like "Elvis and the Beatles Night" makes the agent ask the director which one they mean. It never guesses.
  • Proven promos (fireworks, dollar dogs, heritage nights) are marked "Proven promo (not graded)" and left alone.

Fix. For unlocked nights that are a weak fit, the agent proposes a swap with up to two alternates. A swap has to keep either the kind of night or its audience.

  • A kids' or family night only ever gets a kids' or family theme. Star Trek or pro wrestling never replaces a Bluey Day. If nothing fits, it says "Could not fix" instead of forcing something.
  • When the theme list has nothing strong for families, the agent scores 46 family films and shows at the ballpark against their spread across 40 markets. A title is offered as a "Local favorite" only if it stands out here and is big enough to actually run: Biloxi gets The Lion King, Akron gets The Lego Movie 2. Some towns get none, and the app says so.
  • A locked night is never swapped. Instead the agent asks Qloo's taste graph what fans of that theme near the ballpark also like ("Fans of Country music near Albuquerque also like Kenny Chesney") and turns it into a small sponsor idea.
  • Nothing changes until the director approves. Every step (name matches, each Qloo call, each rule check, each model call, every approval) is one tap away.

Send. Export the new calendar as CSV or ICS, plus a one-page memo for sponsors. The memo says plainly that it describes local taste, not an attendance forecast.

The Study, and why it says NOT PROVEN

Before building the app, I ran a pre-registered test on 385 real 2025 Minor League theme nights at 106 clubs. The question was simple: at the same ballpark, did the theme with the stronger local Qloo lean draw the bigger crowd?

  • Result: not proven. Local taste called 49.1% of 521 same-ballpark pairs (95% interval 43.2% to 54.9%). The pass line I set beforehand was 55%. An AI guess with no local data scored 50.6%, mostly from ties.
  • What it did show. For 5 of the 9 themes, the AI guess gave the same answer at every club. Qloo's readings changed from town to town (98 to 101 distinct readings per theme across 120 clubs).
  • So I don't sell Homestand as an attendance predictor. It's a reasoned, cited read of local taste. The app shows the result openly, after asking you to make your own call first.

How I used Qloo

  • Entity resolution. /search maps each of the 25 library themes to a small, declared bundle of Qloo entities by exact name (and release year for films). No fuzzy matching. Star Wars = A New Hope + The Mandalorian.
  • Local affinity. One /v2/insights call per entity type with filter.results.entities, signal.location=POINT(lon lat) at the ballpark, signal.location.radius=80000, and filter.release_year.min=1900 on movies. Without that floor, Qloo returns nothing for older films like Star Wars (1977). Finding that was my Day-1 test.
  • Discovery. Asking Qloo for top family titles near a city gives nearly the same national list everywhere. So a one-off script built a pool of family animated films and shows (filter.tags family + animation with operator.filter.tags=intersection) and scored it at 40 reference ballparks. At runtime, two calls score the pool at the new city.
  • Taste graph for locked nights. signal.interests.entities (the locked theme) plus signal.location ranks what fans of that theme nearby also like.
  • Market-relative index. Each theme is compared with the identical request at 40 reference markets (a z-score), then centred on the market's own average, because some markets score lower on everything. I checked that the same entity at the same place returns the same value alone, in lists of 6, 10 or 12, two days later, and on a repeat call.
  • Budget and caching. A new city costs seven Qloo calls plus one per locked night, and every call is listed as saved or live. Responses are cached server-side for 120 days, never committed to the public repo, and the key never reaches the browser.
  • MCP. The same agent is an MCP server (/mcp, Streamable HTTP) with check_calendar, propose_swaps, explain_night and sample_teams, under the same quotas and rules as the website.

Beyond baseball

The method isn't baseball-specific, so there's a second kind of calendar: a made-up summer series at a sample amphitheatre in Raleigh, NC. The dates are touring acts, some locked, most tentative holds. In Raleigh the Journey date is a clear weak fit, so the app suggests sending the offer to Rainbow Kitten Surprise, a local favorite Qloo found standing out near Raleigh. The band formed in Boone, North Carolina, and nobody told Qloo that. Locked headliners get support-act ideas from the taste graph: fans of Phish near Raleigh also like Billy Strings.

How I built it

  • Front end: Vite and vanilla TypeScript on Cloudflare Pages.
  • API: a Cloudflare Worker runs the agent, with a KV cache, a Durable Object for usage counters, rate limits and daily caps. It also serves the MCP endpoint.
  • Model: Llama 3.3 70B on Workers AI does two narrow jobs: matching theme names the alias table can't place (checked against real ids), and writing the one-sentence taste comparison for each swap. Code does all the scoring, rule checks and ranking. If the model is slow or says something unusable, the app falls back to template text and says so.
  • The Study: the pre-registration was committed before any Qloo request, then five dated amendments. Scores were frozen by SHA-256 before any attendance data was opened, and the analysis ran once.
  • Tests: 551 unit and contract tests, plus Playwright runs at desktop and phone width: 120 on synthetic data, 26 on real Qloo data and 26 against the live site.
  • Built with AI coding assistants, credited in BUILD_LOG.md.

Challenges I ran into

  • Qloo silently dropped older films until I found the release-year floor.
  • Some big titles (Toy Story, PAW Patrol) return no local signal at all. I drop them openly instead of swapping in look-alikes.
  • Very popular entities sit near an affinity of 1 everywhere, so the differences between towns are tiny. Country is the hardest case.

Accomplishments that I'm proud of

The study missed its pass line, and I put that in the product instead of hiding it. Every request-shape decision was written down before the results could influence it.

What I learned

Local taste data is great at explaining what a town likes. Whether it moves turnout is a separate question, and at this sample size the honest answer is "not detected".

Who it's for

Promotions directors at the 120 affiliated Minor League clubs, plus G League, hockey and soccer teams and concert venues that run the same kind of sponsored calendar. Most theme nights are sold to sponsors; Altoona's GM puts it at about 80% of promotions (Altoona Mirror, June 2024). The planned price is $1,500 per club per season, less than half of one sponsored night: a business pays about $3,500 for one theme night at a North Carolina minor league club (Durham Voice, April 2025). Clubs plan next season and renew sponsors in the off-season, which is exactly when they need a reason for every night.

What's next for Homestand

  • An MCP resource for the memo, so an assistant can hand it straight to a sponsor.
  • Festival lineups, arena calendars, and real venue holds imported from a booking system.
  • A multi-season replication of the study.

Homestand isn't affiliated with any team, league, artist or brand in its examples. A theme's fit describes local taste, not an artist's draw.

Built With

  • cloudflare-pages
  • cloudflare-workers
  • durable-objects
  • llama
  • mcp
  • playwright
  • qloo
  • typescript
  • vite
  • vitest
  • workers-ai
Share this project:

Updates

Submission history