Data & analysis

setlist-fpx

Try it

Query and update setlist.fm from a shell without running the setlist-mcp server — search/read concert setlists, artists, venues, cities, and users via plain curl against the public REST API (an x-api-key header), and toggle "I was there" attendance on a setlist via the authenticated website, using an fpx-captured session cookie. Use when you want setlist.fm data or want to mark/unmark attendance without the MCP, in a script, or on a machine where the MCP isn't installed.

What it does

Query and update setlist.fm from a shell without running the setlist-mcp server — search/read concert setlists, artists, venues, cities, and users via plain curl against the public REST API (an x-api-key header), and toggle "I was there" attendance on a setlist via the authenticated website, using an fpx-captured session cookie. Use when you want setlist.fm data or want to mark/unmark attendance without the MCP, in a script, or on a machine where the MCP isn't installed.

The skill document

setlist.fm via curl + fpx (no MCP)

setlist.fm is hybrid: reads and writes use two different surfaces.

  • Reads — a documented public REST API (api.setlist.fm/rest) keyed by an x-api-key header. Plain curl, no browser, no fpx.
  • Writes — the only mutation setlist.fm offers is the site's "I was there" attendance toggle, and it exists only on the logged-in website (www.setlist.fm, server-rendered Apache Wicket), not the REST API. There's no login form to script — the credential is your browser's session cookie. fpx lifts that cookie out of your signed-in tab once; every actual request afterward is plain curl carrying it. No bridge round-trip per call.

This is the same data/actions the setlist_* MCP tools expose, reached with curl instead of a running server.

Part 1 — reads (curl + API key)

One-time setup

Apply for a free key at , non-commercial use only (see API terms below), then:

export SETLIST_API_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Core call

curl -s 'https://api.setlist.fm/rest/1.0/search/artists?artistName=Radiohead' \
  -H "x-api-key: $SETLIST_API_KEY" -H 'Accept: application/json' \
  | jq '.artist[] | {name, mbid, url}'

Accept: application/json is required — the API serves XML otherwise. Optional Accept-Language: en|es|fr|de|pt|tr|it|pl localizes city/country names. Standard tier is ~2 req/sec, 1440/day — a 429 means slow down.

Dates are dd-MM-yyyy on the wire (NOT ISO) for date search params and lastUpdated (yyyyMMddHHmmss); eventDate comes back the same way in responses — convert both directions yourself (the MCP does this for you via dmyToIso/isoToDmy; a shell one-liner: date -j -f '%Y-%m-%d' '+%d-%m-%Y' on macOS).

The full request catalog (all 15 read endpoints, params, and jq projections) is in references/rest-api.md.

The one rule: chain ids, don't guess them

Every entity is keyed by an id you get from a search: artists by mbid (MusicBrainz id), setlists by setlistId, venues by venueId, cities by geoId. Search first, then feed the id into the matching get/setlists endpoint. Got a setlist.fm URL instead of an id? The id is the trailing hex token before .html, e.g. .../setlist/.../...-4ba8a766.html4ba8a766 — no fetch needed.

Attribution (compliance, not optional)

The API terms require a followable link to setlist.fm wherever this data is shown. Every artist/setlist/venue object has a url — surface it as a clickable link (no nofollow) when you present the data. Also: no persistent caching (fetch live each time, don't build a local store) and non-commercial use only on the free key.

There is no API for this — it's the logged-in website's Wicket AJAX control, so you need your own www.setlist.fm session cookie.

One-time setup

npm install -g @fetchproxy/cli                      # provides `fpx`
fpx profile add setlist --domain setlist.fm          # apex scope
fpx pair -p setlist                                  # prints a pair code → approve in Transporter

Requirements: the Transporter extension installed, an open, signed-in www.setlist.fm tab, and Chrome Site access allowing setlist.fm. Pairing persists after the first approval.

The session cookie (JSESSIONID) is HttpOnly — only fpx cookies (which uses chrome.cookies.get, not page JS) can read it:

COOKIE=$(fpx cookies -p setlist --domain www.setlist.fm \
  | jq -r '[.JSESSIONID, .RememberMeCookie, .["aws-waf-token"]]
           | map(select(. != null)) | join("; ")')

JSESSIONID (Wicket session) or RememberMeCookie (remembered login) must be present — if both are empty you're not signed in on that tab. COOKIE is now a ready-to-send Cookie: header value; every curl below reuses it. A browser-like User-Agent is required too — the bare curl default trips the site's bot heuristics:

UA='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36'

Toggle attendance

Full walkthrough (resolve the setlist URL, fetch the page, parse the toggle control, replay it, verify) is in references/attendance-write.md — it's several steps, not a one-liner, because the control is a per-render Wicket AJAX anchor you must parse out of the page HTML first.

Always dry-run first: read the page, check the control's current state, and only send the AJAX toggle if it doesn't already match what you want. Never trust the toggle's response status as proof — always re-fetch the page afterward and re-check the control's state.

Exit codes / failure modes

  • Read path (curl): a non-2xx from api.setlist.fm is a normal HTTP error — 403 on a valid-looking key usually means a bad/revoked key, not "no key" (that's a 401).
  • Write path (fpx): fpx cookies exit codes — 2 bridge unavailable (extension not connected / not paired → fpx pair -p setlist), 3 bot wall, 4 upstream non-2xx. Once you have COOKIE, subsequent curl failures are yours to diagnose (see "session expired" below) — fpx is out of the loop.
  • Session expired mid-session: a page fetched with your cookie renders logged out (a href="/signin" or /login link instead of the attendance control) — re-run the cookie capture (re-approve in Transporter if needed) and retry.

Notes

  • Reads need no session at all — keep SETLIST_API_KEY and the fpx cookie capture on completely separate paths, same as the MCP does.
  • fpx health -p setlist shows bridge connection state if the cookie capture fails outright.
  • This project is developed and maintained by AI (Claude).

Related skills

Look up concert setlists and live-music history via setlist.fm. Use when the user asks what songs an artist played at a show, their tour setlists, what was performed at a venue or on a date, or wants to find concerts by artist, venue, city, or year. Triggers on phrases like "what did Radiohead play at...", "Phish setlist for...", "shows at Red Rocks", "what songs were played on this tour", or any request about concert setlists, gigs, tours, or live performances. Requires setlist-mcp installed and the setlist server registered (see Setup below).

1 installs

Look up concert setlists and live-music history via setlist.fm. Use when the user asks what songs an artist played at a show, their tour setlists, what was p...

12 installs

Query and act on Resy (resy.com restaurant reservations) from a shell without running the resy-mcp server — search venues, check slot availability, book/cancel reservations, and manage favorites/Priority Notify with curl against api.resy.com, using the fpx CLI (@fetchproxy/cli) only for the one-time token bootstrap when you have no RESY_EMAIL/RESY_PASSWORD. Use when you want Resy data or actions without the MCP, in a script, or on a machine where the MCP isn't installed.

Query etix.com (event ticketing) from a shell with the fpx CLI (@fetchproxy/cli) instead of running the etix-mcp server — search events, venues, and performers, and pull event/venue detail, via one-shot calls through a signed-in browser tab. Use when you want Etix discovery data without the MCP, in a script, or on a machine where the MCP isn't installed.

1 installs

Query musescore.com (sheet music search, score/license metadata, official download links) from a shell with the fpx CLI (@fetchproxy/cli) instead of running the musescore-mcp server — one-shot HTTP calls through a signed-in browser tab. Use when you want MuseScore data without the MCP, in a script, or on a machine where the MCP isn't installed.

1 installs

Query and manage OpenTable (opentable.com) restaurant reservations from a shell with the fpx CLI (@fetchproxy/cli) instead of running the opentable-mcp server — search restaurants, check slot availability, list reservations/favorites, and book/modify/cancel a table via one-shot GraphQL + REST calls through a signed-in browser tab. Use when you want OpenTable data or actions without the MCP, in a script, or on a machine where the MCP isn't installed.

1 installs