Inspiration

Most plans for two people end the same way: one person picks, the other goes along. Recommendation apps make it worse, because they optimise for one profile at a time. We wanted an agent that takes two different tastes seriously and can prove that its plan is fair to both people.

What it does

TasteBridge is a planning agent with taste. Two people finish work with very different tastes: where do they eat, where do they go after, and what do they watch at home? Each person enters one cultural favorite (an artist, film, book, show or game).

Tonight's plan builds the whole evening:

  • Dinner that fits both people, filtered by cuisine and mood (romantic, cozy, lively, quiet, chill) and budget, preferring places that are open at that time.
  • A second stop a short walk away, with the walking time.
  • Live music or a show nearby. Qloo has no event listings, so each venue links to its own programme.
  • A film for home, chosen because it sits closest to an even split between both tastes.

Quick shortlist gives four fair places for one occasion (dinner, drinks, coffee, culture or a night out).

Every pick has a photo, Qloo rating, price level, map and website links, and a share bar (for example "48% Spirited Away / 52% Daft Punk") computed from Qloo explainability, so nobody's taste quietly wins. Use my location plans around where you are (rounded to about 10 m in the browser, never stored). The agent's reasoning streams live, and the web app installs like an app on iPhone and Android.

TasteBridge is also a remote MCP server (https://tastebridge.trackingport.com/mcp) with plan_evening, find_common_ground and resolve_favorite. Add it to Claude, ChatGPT or any MCP client: "My partner loves Wes Anderson films, I love Arctic Monkeys. Plan us a cozy evening in London from 6 pm, Italian food, not too expensive."

How we built it

The agent loop runs on Qloo's Hackathon API:

  1. Understand. Qloo Search resolves each favorite. Names with several readings (an album, a TV show and a book all called "Harry Potter") are ranked by the entity types that carry the most taste signal.
  2. Check the evidence. Qloo Insights with feature.explainability shows how much each favorite drives the combined results. If one favorite is "silent" (some Qloo entities carry almost no taste data), the agent switches to that favorite's next reading. For example, "Stranger Things" first matches a film with almost no taste data; the agent notices and switches to the TV show, which gives a 49/51 plan. When nothing works, it tells the user honestly.
  3. Search. In each round there are three Insights calls: person A, person B, and both together. They are filtered by occasion tag (urn:tag:category:place:*), city, radius and quality.
  4. Refine. If fewer than three strong places are found, the agent widens the radius, relaxes the quality filter, and then drops the occasion filter. It keeps the best round.
  5. Rank for fairness. A reciprocal-rank score rewards places that rank well for both people (min(a,b)·6 + (a+b)·0.8 + joint·1.3). It also down-weights:

    • places outside the requested city (Qloo can read "New York" as the whole state);
    • places whose main Qloo category does not fit the occasion (a museum with a bar is not a drinks spot);
    • the most generic landmarks.
  6. Plan the evening. Dinner searches combine Qloo category, cuisine and ambience tags; if too few places fit, the agent lets the mood guide the ranking instead of filtering, then widens the area. The second stop and the show are searched around the dinner's coordinates and ranked by fairness, walking distance, opening hours (when Qloo lists them) and budget. Adult entertainment venues are never suggested.

The app is plain JavaScript with no dependencies. It is a Workers-style fetch handler served by Node behind Caddy on AWS EC2. It includes NDJSON streaming for live steps, a stateless MCP endpoint, a queue that keeps at most 3 Qloo calls in flight, 429 retries with backoff, a 10-minute cache, per-client rate limits, an installable PWA (manifest, service worker, icons), and 20 unit tests against a mocked Qloo API.

Challenges we ran into

  • Rate limits. The hackathon key allows only a few requests in flight, so we built a request queue with backoff.
  • City matching. "New York" brought in Niagara Falls and Rochester, and "Hanoi" did not match "Hà Nội". We now match accent-insensitive and space-insensitive city names.
  • A loose occasion filter. Qloo's bar tag also matched museums and cinemas, so we now check each place's main category.
  • Silent entities. Some entities produce no taste signal at all. Detecting this from explainability and recovering automatically became the most "agentic" part of the project.

Accomplishments that we're proud of

  • Fairness you can see: every recommendation shows each person's share, taken directly from Qloo explainability.
  • An agent that notices weak evidence and changes course, instead of returning a confident but one-sided answer.
  • One engine behind two surfaces: a polished web app for people and an MCP tool for AI assistants.

What we learned

Taste data is most useful when it is explainable. The explainability scores turned an ordinary recommender into something that can justify a compromise. They also showed us when the input itself was the problem.

What's next

  • Groups of three or more, with a share bar for each person.
  • Booking links and real event listings for the chosen venues.
  • A "veto and re-plan" loop, where either person can reject a pick and the agent rebalances.
  • More taste domains: music for the evening, and books to swap.

Built With

Share this project:

Updates

Submission history