Live demo: https://tastematch.livingagentic.me Source, MIT licensed: https://github.com/NoBanks/qloo-mcp
The problem I actually have
I have released over 600 tracks and spent eighteen years behind a camera. Every independent artist I know, myself included, sells to "people who like this kind of thing" and has no way to say who those people actually are. You can ask a generic LLM and it will guess, confidently, from nothing.
Qloo does not guess. Its taste graph links 250M+ artists, films, books, brands and places to real affinity data, demographics and locations. That is the missing half of every "who is my audience" conversation, and it is exactly the kind of knowledge an agent cannot invent.
What I built
qloo-mcp is an MCP server that hands any AI agent the Qloo taste graph as tools, plus Taste Match, an agent that turns one description of a print or a song into a usable audience report.
Seven tools, each validating input with Pydantic and returning JSON:
| Tool | Qloo endpoint |
|---|---|
search_entities |
GET /search, resolve names to Qloo IDs across nine entity types |
search_tags |
GET /v2/tags, resolve genre, style or keyword names to tag IDs |
list_audiences |
GET /v2/audiences |
get_insights |
GET /v2/insights, taste-based recommendations from entity, tag, age, gender, audience and location signals |
get_demographics |
GET /v2/insights urn:demographics, age and gender affinity |
get_taste_analysis |
GET /v2/insights urn:tag, the tags that describe a taste |
taste_match |
all of the above, composed |
Give Taste Match a title, a description and optionally some influences, and it returns the artists, films, books and brands that audience already loves, the places in a chosen city where those people actually go, the age and gender shape of that audience, the words that describe the taste, and a plain-text pitch you can send.
How it works
- Plan. Artist-supplied seeds always win. If an OpenAI-compatible LLM is configured it suggests more influences and keywords; without one, a deterministic keyword extractor fills in. The agent degrades to useful rather than failing.
- Resolve. Every seed is looked up in Qloo in parallel to get real IDs. No made-up entities ever reach the insight calls.
- Fan out. Seven parallel Qloo insight calls: artists, places restricted to the chosen city, brands, books, movies, demographics and taste tags.
- Synthesize. Seeds are removed from the results, demographics are averaged into an audience profile, and a pitch is written from the top matches.
One failing branch becomes a note in the result instead of failing the whole match. That was a deliberate decision: an audience report that is six-sevenths complete is still useful to an artist, and a traceback is not.
What was hard
Resolving free text to a taste graph. An artist says "ukiyo-e meets cyberpunk" and Qloo needs entity and tag IDs. The fix was to treat resolution as its own parallel stage and to let the artist's own seeds outrank anything a model suggested, so the output stays theirs.
Making failure legible. Every error returns a structured code, invalid_input,
missing_api_key, qloo_api_error, unknown_tool, never a traceback. An agent consuming these
tools has to be able to reason about what went wrong, and a stack trace is not an answer.
What I am proud of
22 tests, all HTTP mocked with respx, so the suite runs with no API key and no network. The tooling I build for my own work has to survive being used on a deadline, and tests are how I know it will.
What is next
Multi-city comparison, so an artist can see where a piece lands hardest before booking a show. Saved audience profiles across a catalog. And exposing Taste Match itself as a single MCP tool so another agent can call it as one step inside a larger workflow.
Built With
- ai-agents
- asyncio
- cloudflare
- docker
- fastapi
- httpx
- mcp
- pydantic
- python
- qloo
- uvicorn
Log in or sign up for Devpost to join the conversation.