How CultureRoute works

Planning a day out for a mixed group is two hard problems at once. Taste: a 9-year-old, a teenager and a grandparent rarely want the same museum. Access: one step-free entrance, a quiet room or an accessible toilet decides whether the day works at all. Generic chatbots answer with the five most famous attractions and no way to know what this group likes or which doors they can get through.

CultureRoute is an agent that solves both together. It uses Qloo's taste graph as its knowledge of what people like, Qloo's place tags and OpenStreetMap as its evidence about access, and explicit planning rules for fairness, walking limits and timing.

The agent's steps

  1. Find the city and understand each person. The city is resolved with Qloo /search over localities (so "Edinburgh" means Scotland, not Indiana). Every interest is looked up with /search (films, shows, artists, books, video games, people, podcasts, brands) and mapped onto Qloo place topics: "Minecraft" becomes the video game entity, and its own Qloo tags (sandbox, voxel) point to science places; "dinosaurs" becomes places Qloo tags with interests:qloo:paleontology. Weak or missing matches are shown, not hidden.
  2. Find candidate places. Several /v2/insights calls inside Qloo's boundary for the city (filter.type=urn:entity:place, filter.location=<locality id>, filter.hours for the chosen day): the best-known museums, galleries, castles, zoos and gardens; places Qloo links to the group's combined taste (signal.interests.entities); one pass per topic the group cares about (filter.tags, for example palaeontology, rail museums, archaeology); and, if anyone needs step-free access, museums that carry Qloo's wheelchair-accessible-entrance tag (operator.filter.tags=intersection).
  3. Score every place for every person. For each member who named a film, show, artist or game, /v2/insights with filter.results.entities ranks the same shortlist against only that person's entities and age band. That Qloo affinity is combined with topic-tag matches and a small popularity prior into a person × place matrix: the core of the fairness check.
  4. Check access before taste. Each need maps to evidence: wheelchair or pushchair users need a verified step-free entrance; accessible toilets and hearing loops come from Qloo accessibility tags; sensory needs use Qloo ambience tags ("Quiet", "Relaxing" vs "Lively", "Crowded") and popularity as a crowd signal. Places with a verified "no" are excluded; places with no data go on a call-ahead list instead of being presented as accessible.
  5. Choose a fair, compact set. A beam search over sets of stops keeps them within the group's walking range and picks the day that maximises the worst-off person's best stop, plus overall quality, minus distance and legs beyond the walking limit. Everyone gets at least one stop chosen for them.
  6. Cross-check and self-correct. Chosen stops are looked up on OpenStreetMap (wheelchair=*, toilets:wheelchair=*). If OpenStreetMap says a place is not wheelchair accessible, the agent swaps it for the next best place and tells you why.
  7. Lunch and timing. A final Qloo call finds restaurants open that day within walking distance of the route (filter.location=POINT(…), filter.location.radius), ranked by rating, diets, access and distance. The route is ordered to minimise travel; walking speed and maximum leg length depend on the group's needs; long legs become "step-free transport" legs; rest breaks are added for older people and sensory needs; and the busiest stop goes first at opening time when someone needs quiet.

Every plan includes the full trace ("How the agent decided"): each step, its reasoning and the exact Qloo requests made. A typical plan makes 15-25 Qloo calls (throttled to the hackathon key's 5 requests per second); Qloo responses are cached privately for 24 hours and whole plans for 6 hours. If Qloo can't be reached, London and New York plans fall back to clearly labelled sample data.

What it does not claim

Use CultureRoute from your own agent (MCP)

CultureRoute is also an MCP server using the Streamable HTTP transport, so Claude, ChatGPT-style clients or your own agent framework can call it as a tool:

https://cultureroute.adamhaleworks.workers.dev/mcp
ToolWhat it does
plan_accessible_outingFull plan: city, date, start time, members with interests, needs and diets → timed itinerary, fairness scores, access evidence, call-ahead list.
check_place_accessLooks up one place in Qloo and reports each access need as verified / likely / unknown / not met, with sources.
resolve_interestsShows how everyday interests map onto Qloo entities and the Qloo place topics the planner searches.

Try it from a terminal:

curl -s https://cultureroute.adamhaleworks.workers.dev/mcp -H 'Content-Type: application/json' -d '{
  "jsonrpc": "2.0", "id": 1, "method": "tools/call",
  "params": { "name": "plan_accessible_outing", "arguments": {
    "city": "London", "date": "2026-11-07", "stops": 3,
    "members": [
      { "name": "Maya", "age": "child", "interests": ["dinosaurs", "Minecraft"] },
      { "name": "Rose", "age": "senior", "interests": ["Bridgerton"], "needs": ["wheelchair"] }
    ] } } }'

Or the plain JSON API: POST https://cultureroute.adamhaleworks.workers.dev/api/plan with the same arguments object.

Built with

Qloo Insights, Search and Tags APIs · Cloudflare Workers · OpenStreetMap Overpass API · optional Cloudflare Workers AI (Llama 3.3) for turning a free-text description into a group and writing the plan's intro from verified facts. The planner itself is deterministic and works without the language model. Source code: https://gitlab.com/adam-hale-works/cultureroute (MIT).