tmp-ozazfiq0al

内容来源:clawhub · 原始地址 · 查看安装指南

原始内容


name: setlist-fpx description: >- 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.

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 https://www.setlist.fm/settings/api, 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.

Part 2 — the attendance write (fpx-captured cookie + curl)

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.

Capture the session cookie (once per shell session)

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).