mcp server
sidestage
Qloo-powered venue scouting for independent music nights. Compare cultural fit across a lineup, inspect the evidence, and build a lead sheet.
Set up
Runs on your computer. Pick your agent and operating system.
This project does not publish an install method we can turn into a config. Follow the README instead.
README
synced Oct 28, 2026Sidestage
Find the room for your sound. A venue scouting tool for independent music promoters, powered by Qloo.
Public source · Review deployment (currently owner-private; external judging access is pending).
An artist lineup has a cultural identity. A generic venue list ignores it, and a combined taste query can hide which artist a venue really suits. Sidestage discovers music rooms in a city, compares the same candidate pool separately for every reference artist, and prioritises the room with the strongest weakest position. It produces a research shortlist, not an attendance forecast or a confirmed booking.
Product
- Search Qloo’s artist directory and choose one to three references.
- Scout live music venues and live music bars in a city; optionally include other bars.
- Validate returned category tags and resolved locality IDs. Drop recorded-closed places and duplicates.
- If the combined pool is small, discover candidates for each artist without silently changing city or categories.
- Ask Qloo to rank the same pool for each artist, then minimise the worst artist rank. Break ties by mean rank and discovery order. Compare this with first-artist-only order.
- Inspect request parameters, per-artist positions, raw affinity values and the workflow log. Raw affinity values from different queries are never averaged.
- Save leads and personal verification checklists in browser storage; export a CSV lead sheet.
- Give a model-driven agent the same workflow through the included stdio MCP server.
There are no mocked venue cards, canned recommendation responses, invented capacity figures, attendance probabilities or availability claims. The initial example bills are artist-name inputs; they resolve and run against the live API.
Run locally
Use Node.js 22.19+ and install dependencies:
npm ci
For a preview with credentials kept in process memory:
npm run dev:secure
The terminal asks for one JSON line (input is hidden):
{"key":"YOUR_QLOO_HACKATHON_KEY"}
Open http://127.0.0.1:5173. A loopback-only gateway on port 5174 holds the key and signs allowed Qloo GET requests. The local Worker never receives the real key. Stop the preview with Ctrl+C. No key file is created.
Without credentials, npm run dev renders the interface; live lookups require the secure launcher. Do not confuse the unconfigured interface with a functional API demo.
For hosted deployment, configure QLOO_API_KEY as a secret runtime environment variable in Sites. Never put it in client variables, .openai/hosting.json, source code or a public repository. The Qloo host is fixed to https://hackathon.api.qloo.com.
Agent tool
The stdio MCP server supports protocol version 2025-03-26, initialization, ping, tool listing, tool calls and JSON-RPC batches. It exposes:
find_reference_artists: resolve names and return disambiguation choices.scout_venues_for_lineup: run the same validated scouting workflow used by the visual app.
Start node scripts/mcp.mjs from an MCP client with QLOO_API_KEY supplied in the child process environment. Example configuration (replace the path; provision the secret privately):
{
"mcpServers": {
"sidestage": {
"command": "node",
"args": ["/absolute/path/to/sidestage/scripts/mcp.mjs"]
}
}
}
The visual interface runs a bounded, deterministic tool workflow; it does not use an LLM. An external model-driven agent can discover and call its MCP tools. The app never books, contacts a venue or sends messages.
Qloo request flow
| Stage | Qloo request | Purpose |
|---|---|---|
| Resolve artists | GET /search, types=urn:entity:artist | Obtain real entity IDs and show identity choices |
| Resolve categories | GET /v2/tags | Find live music category IDs rather than guessing tags |
| Discover | GET /v2/insights | Place results from lineup signals, chosen tags and strict city boundary |
| Adapt | Repeat discovery per artist when the pool has fewer than eight candidates | Expand the cultural candidate pool, keeping scope fixed |
| Compare | GET /v2/insights, filter.results.entities | Rank one common pool separately for each artist |
| Decide | Local minimax ordinal ranking | Prevent one strong artist match masking another weak one |
The UI’s Scout log provides the exact request parameter values for each completed run, with no key. Open a venue’s ranking evidence to inspect IDs and returned raw affinity values. Generate these through a live run; provider response fixtures are deliberately not committed.
Verification
npm test
npx tsc --noEmit
npm run build
Nine unit/protocol checks cover weakest-artist ranking, missing evidence, duplicate/invalid inputs, unsafe URLs, authentication errors, locality/category/closure validation, MCP discovery and an actual stdio handshake.
With the secure preview running, node scripts/qa-browser.mjs uses Playwright for a live end-to-end run: artist resolution, scouting, alternate ranking order, saved leads after reload, personal checklists, CSV download, dialogs and mobile search/layout. Install Playwright’s Chromium if it is not already available (npx playwright install chromium). The script uses an existing Windows Chromium cache when present, otherwise Playwright’s configured browser. Screenshots and downloads stay in ignored .private/.
Limits and data handling
- Affinities describe aggregate cultural relationships. They do not establish personal preferences, local fan counts, footfall, conversion or ticket demand.
- Venue category and recorded closure status are Qloo data, not a fresh manual verification. Directly confirm capacity, current operating status, private hire, fees, backline, age policy and access.
- Geographic and category coverage vary. Empty results stay empty; the app does not fill gaps with invented rooms.
- The first candidate pool is bounded at 24. Results are relative to that pool, not a city-wide exhaustive ranking.
- A partially returned artist ranking is incomplete evidence and cannot outrank a complete comparison. Missing values remain unknown.
- The server caches successful requests in memory for 15 minutes (maximum 160 entries). Per-process request limiting is a modest quota guard, not a global distributed limiter. Public deployment at scale needs shared quota management.
- Artist IDs, venue IDs and a city go to Qloo. Artist name queries are used for resolution. Attendee identities are unnecessary. Saved leads/checklists are browser-local and are not sent to a venue.
- Exported CSVs are private research artifacts. Qloo response data, keys and raw mailbox messages must not be committed to public source.
Architecture
React + TypeScript on the supplied Vinext/Vite Sites starter, with a Cloudflare Worker backend. lib/scout.mjs owns provider requests, validation, adaptation and ranking; browser routes and MCP reuse it. The browser API streams real workflow events as newline-delimited JSON. MIT-licensed original source; Qloo data and third-party assets retain their own rights.
References and assets
- Qloo hackathon kit and safe-use guidance
- Qloo API parameter reference
- Affinity score interpretation
- MCP tool protocol
- Hero mood photograph: Unsplash image source. It is illustrative and is not presented as a recommended venue. Venue photos appear only when supplied by live Qloo results.
- Type: DM Sans and Barlow Condensed via Google Fonts. Icons: Lucide.
Created by Gbolahan Lawal for the Qloo Agentic Hackathon. No competition outcome, venue relationship or customer adoption is claimed.