Skip to main content
Glama

mcp-phish

CI License: MIT Python MCP

Ein MCP-Server, der die APIs api.phish.net v5 und phish.in v2 hinter einer einheitlichen, typisierten Tool-Oberfläche zusammenfasst. Zwölf Tools für Setlisten, Songs, Jam-Charts, Rezensionen und Audio. Jede Antwort wird durch fixierte Pydantic-Modelle geformt, sodass das Übertragungsformat auch bei Änderungen der zugrunde liegenden APIs stabil bleibt.

Aufgebaut auf FastMCP mit Streamable HTTP-Transport. Entwickelt für den Betrieb in einem vertrauenswürdigen LAN oder hinter einem Tailscale-ACL — es gibt keine integrierte Authentifizierung auf MCP-Ebene.

Warum

Heutzutage besteht das Phish.net + phish.in-Ökosystem aus einer kleinen Menge ungepflegter Wrapper und Einmalskripte. Niemand kombiniert beides sauber. mcp-phish bietet jedem MCP-fähigen Client (Claude Code, Claude Desktop, benutzerdefinierte Agenten) eine fokussierte, gut typisierte Oberfläche für die Fragen, die Fans tatsächlich stellen: Setliste für ein Datum, Song-Debüt und -Lücke, Audio-URL für einen Track, Jam-Chart-Hits für eine Tour.

Die Quelle kann sich ändern (Live-API → zwischengespeichert → Vault). Die Pydantic-Formen, die an MCP-Clients zurückgegeben werden, tun dies nie.

Schnellstart

docker run --rm \
  -p 3705:3705 \
  -e STUB_MODE=true \
  ghcr.io/pete-builds/mcp-phish:latest

Der Server startet standardmäßig im Stub-Modus. Er liefert realistische Mock-Daten und benötigt keinen Netzwerkzugriff oder API-Schlüssel. Registrieren Sie ihn bei Claude Code:

claude mcp add phish --transport http --scope user --url http://localhost:3705/mcp

Fragen Sie dann Claude: "Was war die Setliste am 30.12.95?" und Sie sollten das Madison Square Garden-Konzert mit dem Mike's > Simple > Weekapaug-Groove erhalten.

Um die echten APIs zu nutzen, registrieren Sie einen kostenlosen Schlüssel unter api.phish.net/keys/ und schalten Sie den Stub-Modus aus:

docker run --rm \
  -p 3705:3705 \
  -e STUB_MODE=false \
  -e PHISHNET_API_KEY=<your-key> \
  ghcr.io/pete-builds/mcp-phish:latest

Tool-Referenz

Tool

Quelle

Was es tut

search_shows

phish.net

Shows nach Jahr + Veranstaltungsort + Stadt/Bundesland/Land suchen.

get_show

phish.net

Vollständige Show: Setliste, Bewertungen, Anzahl der Rezensionen, Veranstaltungsort.

recent_shows

phish.net

N aktuellste Shows, beginnend mit der neuesten.

search_songs

phish.net

Songkatalog nach Titelfragment durchsuchen.

get_song

phish.net

Ein Song-Datensatz: Debüt, letztes Spiel, Lücke, Gesamtanzahl.

song_history

phish.net

Jede Aufführung eines Songs, beginnend mit der neuesten.

jam_chart

phish.net

Redaktionell markierte bemerkenswerte Jams.

get_reviews

phish.net

Benutzerrezensionen für eine Show.

get_audio

phish.in

Trackliste + MP3-URLs + Dauer für eine Show.

get_track

phish.in

Ein Audiotrack nach ID.

search_audio_tracks

phish.in

Jede aufgenommene Version eines Song-Slugs.

health

meta

Serverstatus, Drosselungsstatus, Cache-Statistiken.

Jedes Tool gibt einen JSON-String mit dem Standard-Envelope zurück:

{"data": <typed payload>}

oder bei einem Fehler:

{
  "error": "human-readable message",
  "code": "UPSTREAM_DOWN | NOT_FOUND | INVALID_INPUT | RATE_LIMITED | INTERNAL",
  "details": { "...": "..." }
}

Die Pydantic-Modelle in src/mcp_phish/models.py (ShowSummary, Show, SetlistEntry, Song, Performance, NotableJam, Review, Track, ShowAudio, Health) sind der öffentliche Vertrag. Sie sind mit extra="forbid" fixiert, sodass jede Änderung der Upstream-API zu einem Validierungsfehler führt, anstatt zu einer stillschweigenden Änderung der Datenstruktur.

Stub-Modus vs. Real-Modus

Modus

Verwendung

Verhalten

Stub (STUB_MODE=true, Standard)

Entwicklung, Demos, noch kein API-Schlüssel

Realistische Mock-Payloads für eine kleine Auswahl kanonischer Shows (30.12.95 MSG, 17.11.97 Denver, 31.12.24 MSG). Jedes Tool gibt die gleiche Pydantic-Form zurück wie im Real-Modus.

Real (STUB_MODE=false)

Produktion mit einem phish.net API-Schlüssel

Spricht HTTPS mit api.phish.net v5 und phish.in v2. Erfordert PHISHNET_API_KEY; PHISHIN_API_KEY ist optional.

Der Wechsel der Modi ist eine Konfigurationsänderung, keine Codeänderung. Dieselben zwölf Tools, dieselben Antwortformen.

Caching

mcp-phish unterhält einen undurchsichtigen Key-Value-Cache auf der Festplatte (/data/phish-cache.db, aiosqlite), der mit (endpoint, params_hash) indiziert ist. Ein einzelner TTL steuert jeden Eintrag (CACHE_TTL_SECONDS, Standard 86400 = 24h). Bei einem Treffer erfolgt kein Upstream-Aufruf.

Dieser Cache ist kein normalisierter Datenspeicher. Er enthält lediglich rohe JSON-Antworten, um die Upstream-Ratenbegrenzungen einzuhalten und wiederholte LLM-gesteuerte Erkundungen schnell zu machen. Betrachten Sie ihn als flüchtig.

Drosselung (Throttling)

Jeder Upstream-Aufruf durchläuft einen Token-Bucket pro Instanz mit einer konfigurierbaren Steady-State-Rate:

Variable

Standard

Hinweise

THROTTLE_PHISHNET_RPS

5

api.phish.net v5 Anfragen pro Sekunde.

THROTTLE_PHISHIN_RPS

10

phish.in v2 Anfragen pro Sekunde.

Der Bucket ist prozessintern. Mehrere Container koordinieren sich nicht. Der Token-Status wird in health() offengelegt, sodass eine Claude Code-Sitzung sehen kann, was noch übrig ist.

Konfiguration

Die gesamte Konfiguration wird aus Umgebungsvariablen (und einer .env-Datei, falls vorhanden) gelesen. Pydantic validiert beim Start und schlägt bei ungültigen Werten sofort fehl.

Variable

Typ

Standard

Erforderlich

Hinweise

STUB_MODE

bool

true

nein

Wenn false, sind Real-Modus-Anmeldedaten erforderlich.

PHISHNET_API_KEY

string

""

nur im Real-Modus

Kostenlos unter api.phish.net/keys/.

PHISHIN_API_KEY

string

""

nein

Optional; erhöht Ratenbegrenzungen.

PHISHNET_BASE_URL

string

https://api.phish.net/v5

nein

Überschreibung zum Testen.

PHISHIN_BASE_URL

string

https://phish.in/api/v2

nein

Überschreibung zum Testen.

CACHE_DB_PATH

string

/data/phish-cache.db

nein

aiosqlite-Dateipfad.

CACHE_TTL_SECONDS

int

86400

nein

24h Standard.

THROTTLE_PHISHNET_RPS

float

5.0

nein

Stetige Rate pro Sekunde.

THROTTLE_PHISHIN_RPS

float

10.0

nein

Stetige Rate pro Sekunde.

MCP_HOST

string

0.0.0.0

nein

Bind-Adresse.

MCP_PORT

int

3705

nein

Port für eingehende Verbindungen.

LOG_LEVEL

enum

INFO

nein

Einer von DEBUG, INFO, WARNING, ERROR, CRITICAL.

LOG_FORMAT

enum

json

nein

json für Produktion, text für lokale Entwicklung.

Ein vollständiges Beispiel befindet sich in .env.example.

MCP-Client-Einrichtung

Claude Code

claude mcp add phish --transport http --scope user --url http://<host>:3705/mcp

Claude Desktop

{
  "mcpServers": {
    "phish": {
      "transport": "streamable-http",
      "url": "http://<host>:3705/mcp"
    }
  }
}

Generische Konfiguration

Streamable HTTP unter http://<host>:3705/mcp. Jeder MCP-Client, der das Streamable HTTP-Transportprotokoll unterstützt, kann eine Verbindung herstellen.

Architektur

+---------------------+     Streamable HTTP     +---------------------+
|  MCP Client         |  -------------------->  |  mcp-phish          |
|  (Claude Code, etc) |  <--------------------  |  (FastMCP server)   |
+---------------------+                         +----+--------------+-+
                                                     |              |
                                                     |              |
                                                     v              v
                                          +----------+--+   +-------+--------+
                                          | api.phish.net|   | phish.in/api/v2|
                                          |     v5       |   |                |
                                          +--------------+   +----------------+

                                                     ^
                                                     |
                                          +----------+----------+
                                          | aiosqlite KV cache  |
                                          |  /data/phish-cache  |
                                          +---------------------+

mcp-phish ist ein schlanker asynchroner Proxy mit einem kleinen Cache: Er übersetzt MCP-Tool-Aufrufe in Upstream-REST-Aufrufe, speichert rohe Antworten für den konfigurierten TTL zwischen und projiziert sie in die öffentliche Pydantic-Form. Er speichert keinen Zustand über diesen Cache hinaus. Er ruft keine anderen Cloud-Dienste auf als die beiden Phish-APIs.

Sicherheitshinweise

  • Betreiben Sie mcp-phish in einem vertrauenswürdigen LAN, über Tailscale oder hinter einem Reverse-Proxy mit Authentifizierung. Der Server selbst authentifiziert MCP-Clients nicht.

  • API-Schlüssel befinden sich nur in der Umgebung des Containers. Sie werden niemals protokolliert, niemals in Antworten wiederholt und niemals auf die Festplatte geschrieben.

  • Der Container läuft als UID 1000, ohne Shell, ohne Home-Verzeichnis, mit einem schreibgeschützten Root-Dateisystem (/tmp ist tmpfs) und no-new-privileges.

  • Das /data-Cache-Volume ist der einzige beschreibbare Pfad.

  • Python-Abhängigkeiten werden mit pip --require-hashes aus einer hash-gesperrten requirements.lock installiert. Das Basis-Image wird vor der ersten getaggten Version per Digest fixiert.

  • Veröffentlichte Images sind Multi-Arch (amd64/arm64) mit Build-Provenienz und SBOM via docker/build-push-action.

Für Schwachstellenberichte siehe SECURITY.md.

Entwicklung

Erfordert Python 3.13+ und Docker.

# Clone + install dev deps
git clone https://github.com/pete-builds/mcp-phish.git
cd mcp-phish
python -m venv .venv && source .venv/bin/activate
pip install --require-hashes -r requirements-dev.lock
pip install -e . --no-deps

# Run the test suite
pytest

# Lint and format
ruff check src tests
ruff format src tests

# Type check (mypy strict)
mypy src/mcp_phish

# Run the server locally in stub mode
python -m mcp_phish.server

# Or build the image yourself
cp docker-compose.example.yml docker-compose.yml
docker compose up --build

Aktualisieren von Abhängigkeiten

Die Dateien requirements.lock und requirements-dev.lock sind hash-fixiert. Bearbeiten Sie die entsprechende .in-Datei und generieren Sie sie dann neu:

uv pip compile requirements.in --output-file requirements.lock --generate-hashes --python-version 3.13
uv pip compile requirements-dev.in --output-file requirements-dev.lock --generate-hashes --python-version 3.13

Dependabot öffnet wöchentliche PRs für Updates auf requirements.in-Ebene, das Docker-Basis-Image und GitHub Actions-Versionen.

Roadmap

Dieser Server ist Phase 1 eines größeren Phish-Datenprojekts. Der oben dokumentierte Pydantic-Vertrag bleibt über die zukünftigen Phasen hinweg Byte-identisch.

  • Phase 2 — Postgres-Vault + nächtliche ETL-Hydrierung.

  • Phase 3 — Vault-gestützter Lesepfad für dieses MCP. Hot-Window-Fallthrough liest aktuelle Shows live; ältere Lesevorgänge kommen aus dem Vault.

  • Phase 4 — Setlisten-Vorhersagespiel (separates Repo).

  • Phase 5 — Chat + Dashboard-UI über MCP (separates Repo).

Der Phasenstatus befindet sich unter https://github.com/pete-builds/mcp-phish/issues.

Danksagungen

Danke an die Betreiber von phish.net und phish.in, dass sie das Korpus öffentlich und maschinenlesbar halten. Dieser Wrapper ist mit keinem der beiden Projekte verbunden. Bitte respektieren Sie deren Ratenbegrenzungen und Nutzungsbedingungen.

Lizenz

MIT.

Mitwirken

Issues und Pull Requests sind willkommen. Bevor Sie einen PR öffnen:

  1. Stellen Sie sicher, dass ruff check, ruff format --check und mypy src/mcp_phish sauber sind.

  2. Fügen Sie Tests hinzu oder aktualisieren Sie diese; halten Sie die Abdeckung bei 80% oder höher.

  3. Führen Sie pytest lokal aus und bestätigen Sie, dass die Suite besteht.

  4. Aktualisieren Sie CHANGELOG.md unter einer [Unreleased]-Überschrift.

A
license - permissive license
-
quality - not tested
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pete-builds/mcp-phish'

If you have feedback or need assistance with the MCP directory API, please join our Discord server