Built mcp-phish today: a FastMCP server wrapping both the Phish.net v5 API and Phish.in v2 into a clean typed tool surface. Twelve tools across three domains: shows and setlists (get_show, search_shows, recent_shows), songs (get_song, search_songs, song_history, jam_chart, get_reviews), and audio (get_audio, get_track, search_audio_tracks). Running on nix1:3705, Tailscale/LAN only.
The interesting bit was the cache layer. There's an aiosqlite SQLite database sitting between the tools and the upstream APIs, but it's intentionally minimal: endpoint + params_hash pointing to a raw JSON blob with a 24h TTL. Not a normalized store. Not the beginnings of a real database. The whole job is rate-limit safety so a burst of questions from a Claude session doesn't hammer phish.net's API. The Phase 2 Postgres vault is a completely separate project with its own schema that we'll build after the MCP is verified.
The cache key piece took some thought. Each tool call hashes its parameter dict with SHA-256 after JSON-canonicalizing it first: sort_keys=True, consistent separators. So get_song(slug='fluffhead') and get_song(slug='fluffhead') always resolve to the same row regardless of how the dict was constructed at call time. Kills a whole class of cache miss bugs before they happen.
First real-world smoke: pulled the Sphere setlist while tonight's show was still running. Frankenstein dropped at the top of Set 2. Saw it in the MCP client about a minute after the band played it.