NotOnQ
by T04435
README.md
# NotOnQ
NotOnQ fills in artists for the [Qloo](https://qloo.com) taste API from open sources, in Qloo's own shape, with a source
on every value. It caches each answer and counts how often each artist we filled in is asked for, so the artists
developers actually ask for can be ranked for import.
Built for the Qloo Agentic Hackathon 2026. Works with the Qloo API; not affiliated with or endorsed by Qloo.
> **Scope: artists only.** For the hackathon, NotOnQ fills in music artists (`urn:entity:artist`), where it is
> measured. Every other entity type, and every request Qloo can answer, passes straight through to Qloo unchanged.
## What it proves
Every number on [`/proof`](src/app/proof/page.tsx) is counted from runs in the Ledger, and links to them:
- **Live traffic:** every artist lookup through Ask, the drop-in API and the Qloo harness.
- **The benchmark batch** (`scripts/benchmark.mts`): real Ask questions and `/q` calls run through the app, labelled
as the app `benchmark` (Proof's app filter shows it on its own). It compares artists with a release in the last 14 days
against Last.fm's chart artists (usable in Qloo, new to Qloo, or not yet a taste signal), then asks five questions
about each artist we filled in: who and where from, genre, similar artists, where they're popular, and what ages
listen. Run it against the deployment whose Proof it feeds, with `NOTONQ_BENCHMARK_TOKEN` set on both sides.
## Two ways in
1. **Ask** (`/`, the home page): a question run through Qloo's own MCP harness, straight to Qloo first; NotOnQ then checks that answer, asks Qloo again if it falls short, and only then fills in the rest from open sources. The page turns into a chat: the run log streams beside what was found, then the answer, a table of every artist (where it came from, kept or removed and why), the sources, a link to the run in the Ledger, and a follow-up box.
2. **Drop-in REST and MCP** (`/q/*`): the same paths and parameters as the Qloo API, with your own `X-Api-Key`.
Qloo's results come first, unchanged; NotOnQ's artists are added after them in exactly Qloo's shape, with UUID IDs
and a "Not in Qloo" label in `short_description`. For MCP, run the official Qloo harness unchanged:
`QLOO_BASE_URL=https://notonq.vercel.app/q/app/my-app QLOO_TRUSTED_BASE_URL=https://notonq.vercel.app/q/app/my-app qloo mcp`.
Docs live at `/docs` (REST and MCP reference), `/openapi.json`, and for agents `/llms.txt` and `/llms-full.txt`.
## Inside Qloo
NotOnQ is a proof of concept for a feature Qloo could build in. It shows the behaviour, not the data pipeline: the open
sources here stand in for whatever Qloo would use. Built into Qloo, the same flow would run on Qloo's own licensed
sources and taste graph: fill in the artist, label it, answer taste questions through similar artists, and step aside once
the artist is in the catalogue. The Ledger shows which artists we filled in that people actually ask for. Artists first, for this
hackathon; the same pattern fits other entity types.
## No raw Qloo responses on our pages
The drop-in API returns Qloo's answer to its caller unchanged. NotOnQ's own pages (Ask, the Ledger, replays) show results
derived from Qloo, such as artist names, but never Qloo's raw API responses: those are redacted on the server by type
(`[redacted string]`, `[redacted uuid]`…) before anything reaches a browser or is stored. NotOnQ's own data is shown in full.
## How it fills in an artist
1. **Qloo first.** If Qloo knows the artist, its response passes through untouched.
2. **Who could it be?** MusicBrainz, Last.fm and Deezer matches are merged. Only one confident exact MusicBrainz match
continues by itself; otherwise every candidate is listed and you choose one by its ID.
3. **Open data** for facts: MusicBrainz, Wikidata, Wikipedia, Last.fm, Deezer.
4. **Stand-ins:** similar artists Qloo *does* know become the taste signal, so affinities, heatmaps and demographics
still come from Qloo, labelled as coming from the stand-ins.
5. **Research (tier 3):** for fields open data didn't cover, a web research agent returns claims with a URL and an exact quote.
Plain code re-fetches every page and keeps only quotes it finds there.
6. **Cache, demand and replay:** every answer is cached, and every request is recorded in the Ledger (`/ledger`): live through Neon Realtime (pause any time), calls grouped into visits per app (or per `X-NotOnQ-Trace`), filters and pages in the URL so any view can be shared, each call replayable step by step; a filter by artist puts the most asked one click away, and
the artists panel ranks every artist, most asked first. It holds IDs and demand only, never copied data.
Anything else is marked `unavailable`. Nothing is invented.
## Run it locally
Requirements: Node 22+, pnpm 11.
```bash
pnpm install
cp .env.example .env.local # then add your own keys
pnpm dev # http://localhost:3400
```
The live Ledger uses Neon Realtime: Neon pushes each new call to open pages, and nothing polls. It needs
`NEON_REALTIME_URL` and `NEON_REALTIME_SECRET` from the branch's Realtime settings, and the page's origin in
Realtime's allowed origins. Local development uses the Neon dev branch (`.env.development.local`); the app refuses the
production database outside Vercel production.
Quality gates (run before every push):
```bash
pnpm typecheck && pnpm lint && pnpm test
```
## Data sources and credits
- [MusicBrainz](https://musicbrainz.org) core data, CC0
- [Wikidata](https://www.wikidata.org), CC0
- [Wikipedia](https://en.wikipedia.org) summaries, CC BY-SA 4.0 (linked on every use)
- [Wikimedia Commons](https://commons.wikimedia.org) images, per-file licences (linked)
- [Last.fm](https://www.last.fm) API, powered by AudioScrobbler, used with each caller's own key
- [Deezer](https://developers.deezer.com) API (non-commercial use)
- [OpenStreetMap](https://www.openstreetmap.org/copyright) via Nominatim: the place at a point, © OpenStreetMap contributors, ODbL
- [Spotify](https://developer.spotify.com/documentation/embeds) public oEmbed: an artist's name for a Spotify ID (nothing else from Spotify is used)
- [ListenBrainz](https://listenbrainz.org) fresh releases (the proof sample)
- Researched facts: the page cited per value, with the quote checked on that page
- [Qloo](https://qloo.com) API, with each caller's own key. No Qloo response data is stored in this repo.
## Licence
MIT
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues