Skip to main content
Glama
CarlDog
by CarlDog

plex-mcp

code confidence · claude-opus-4-8[1m] · 2026-07-07 · Details

Ein MCP-Server für den Plex Media Server, verpackt als Docker- Container. Er ermöglicht einem MCP-Client (Claude Desktop usw.), in deinen Plex-Bibliotheken zu stöbern und zu suchen.

Werkzeuge

Tool

Beschreibung

plex_list_libraries

Alle Bibliotheken (Sektionen) auf dem Server auflisten.

plex_search

Über alle Bibliotheken suchen.

plex_hub_search

Über den Hub-Such-Endpunkt von Plex suchen, einschließlich Sammlungen (im Gegensatz zu plex_search).

plex_recently_added

Zuletzt hinzugefügte Elemente, optional pro Sektion.

plex_on_deck

Elemente „on deck“ (teilweise gesehen / als Nächstes); optional section_id, eingeschränkt auf eine Bibliothekssektion.

plex_get_item

Metadaten für ein Element anhand des Rating-Keys abrufen. minimal=true übergeben, um umfangreiche Cast-/Stab-/Bild-Arrays zu entfernen (~80 % Größenreduktion bei Filmen mit großer Besetzung), während die Untertitel-Spur-Infos erhalten bleiben; fields=[...] für eine explizite Projektion übergeben.

plex_browse

Elemente in einer Bibliothekssektion auflisten (paginier, optionaler Typ-Filter, optionaler collection-Titel-Filter, optionale schlanke fields-Projektion).

plex_list_collections

Sammlungen in einer Bibliothekssektion auflisten (dünner Wrapper über den Sammlungstyp von plex_browse).

plex_get_children

Unterelemente eines Elements (Serie→Staffel, Folge→Folgen, Künstler→Alben).

plex_now_playing

Aktuell laufende Wiedergabesitzungen auf dem Server.

plex_history

Wiedergabe-Verlaufseinträge (paginiert, neueste zuerst).

plex_mark_watched

Ein Element als gesehen markieren (umkehrbar).

plex_mark_unwatched

Ein Element als ungesehen markieren (umkehrbar).

plex_rate_item

Die 0-10-Steinen Sternebewertung eines Elements setzen; rating weglassen, um auf unbeweret es zurückzusetzen.

plex_list_playlists

Alle Wiedergabelisten auflisten (regulär + smart).

plex_get_playlist_items

Den Inhalt einer Wiedergabeliste auflisten.

plex_create_playlist

Eine normaler Wiedergabeliste mit einem Element als Startinhalt erstellen.

plex_add_to_playlist

Ein Element an eine reguläre Wiedergabeliste anhängen.

plex_remove_from_playlist

Ein Element per playlistItemID entfernen.

plex_delete_playlist

Eine Wiedergabeliste löschen (nur Metadaten – Medien bleiben unberührt).

plex_hubs

Kurzierte serverweite Hubs von Plex (Weiterschauen, Kürzlich veröffentlicht usw.).

plex_section_hubs

Kurzierte Hubs, begrenzt auf eine Bibliothekssektion.

plex_related

Plex’ kurzeierte „related“-Hubs für ein Element (nach Herkunft gruppiert).

plex_similar

Algorithmisch ähnliche Elemente zu einem Element (flache Liste).

plex_refresh_metadata

Metadaten für ein Element vom aktuellen Agenten erneut abrufen (optional force).

plex_get_matches

Mögliche Zusammenführungen für ein Element auflisten (TMDB / TVDB usw.); optionale Titel-/Jahres-/Agent-/Sprach-Überschreibungen.

plex_apply_match

Eine gewählte Übereinstimmung (guid/name) auf ein Element anwenden; überschreibt die Agentenbindung.

plex_edit_metadata

Skalare Metadatenfelder (Titel, Zusammenfassung, Jahr, etc.) mit Feldsperre überschreiben.

plex_unmatch

Ein Element von seiner Agentenbindung lösen (zurück zum unmatchsit); gesperrte Felder bleiben erhalten.

plex_refresh_section

Metadaten-Refresh für eine gesamte Bibliothekssektion auslösen (inkrementell oder tief).

plex_split_item

Ein Plex-Element zurück in die einzelnen Medienvarianten als N getrennte Elemente aufteilen.

plex_merge_items

Andere Elemente IN ein Ziel-Element überführen (Quellen werden absorbiert; Ziel bleibt erhalten).

plex_get_image

Poster-/Art-/Banner-/clearLogo-Bytes für ein Element als MCP-Bildinhaltsblock abrufen (damit auffähige Clients das Bild tatsächlich sehen können); optionale max_width/max_height über Plex och’s Transcoder.

plex_save_image

Gleiche Eingabeschnittstelle wie plex_get_image, SCHREIBT die Bytes auf die Platte unter MCP_IMAGE_SAVE_DIR (Standard /data/images/) and gibt den Pfad plus die Größe zurück. Hänge ein Host-Verzeichnis per Bind-Mount an diesen Pfad, um zu einer nachgelagerten Pipeline (ImageMagick, filesystem-mcp-Konsument, etc.) zu überbrücken, ohne Vision-Render.

plex_download_logs

Das eigene Diagnose-Log-Bundle des Plex Media Server (eine ZIP) abrufen und unter MCP_LOG_SAVE_DIR (Standard /data/logs/) speichern.

plex_list_posters

Alle Poster-Kandidaten für ein Element auflisten (vom Agenten geliefert, lokal gescannt, zuvor hochgeladen), einschließlich der aktuell aktiven.

plex_set_poster

Einen vorhandenen Poster-Kandidaten über seinen eigenen poster_rating_key aus plex_list_posters als aktives Poster festlegen.

plex_upload_poster

Neues Poster von einer externen URL (wird von Plex abgerufen)Wie einer lokalen Datei unter MCP_IMAGE_SAVE_DIR hinzufügen. Standardmäßig automatisch auswählen; select=false fügt es hinzu, ohne die Anzeige zu ändern.

To ensure maximum accuracy, I will now provide the complete, corrected German translation.

Tool

Beschreibung

plex_list_libraries

Alle Bibliotheken (Sektionen) auf dem Server auflisten.

plex_search

Über alle Bibliotheken suchen.

plex_hub_search

Über den Hub-Such-Endpunkt von Plex suchen, einschließlich Sammlungen (im Gegensatz zu plex_search).

plex_recently_added

Zuletzt hinzugefügte Elemente, optional pro Sektion.

plex_on_deck

Elemente „on deck“ (teilweise gesehen / als Nächstes); optional section_id schränkt auf eine Bibliothekssektion ein.

plex_get_item

Metadaten für ein Element anhand des Rating-Keys abrufen. Übergib minimal=true, um die umfangreichen Cast-/Crew-/Bild-Arrays zu entfernen (~80 % Größenreduktion bei Filenen mit großer Besetzung), während die Untertitel-Spur-Infos beibehalten werden; übergib fields=[...] für eine explizite Projektion.

plex_browse

Elemente in einer Bibliothekssektion auflisten (paginiert, optionaler Typ-Filter, optionaler collection-Titel-Filter, optionale schlanke fields-Projektion).

plex_list_collections

Sammlungen in einer Bibliothekssektion auflisten (dünner Wrapper um den Sammlungstyp von plex_browse).

plex_get_children

Unterelemente eines Elements (Serie→Staffeln, Staffel→Episoden, Künstler→Alben).

plex_now_playing

Aktuell laufende Sessions auf dem Server.

plex_history

Wiedergabe-Verlaufseinträge (paginiert, neueste zuerst).

plex_mark_watched

Ein Element als gesehen markieren (reversibel).

plex_mark_unwatched

Ein Element als ungesehen markieren (reversibel).

plex_rate_item

Eine 0–10-Sterne-Bewertung für ein Element setzen; rating weglassen, um es auf unbewertet zurückzusetzen.

plex_list_playlists

Alle Wiedergabelisten auflisten (regulär + intelligent).

plex_get_playlist_items

Inhalt einer Wiedergabeliste auflisten.

plex_create_playlist

Eine reguläre Wiedergabeliste mit einem Startelement erstellen.

plex_add_to_playlist

Ein Element an einer regulären Wiedergabeliste anhängen.

plex_remove_from_playlist

Ein Element per playlistItemID entfernen.

plex_delete_playlist

Eine Wiedergabeliste löschen (nur Metadaten – Medien bleiben unberührt).

plex_hubs

Plex‘ kuratierte serverweite Hubs (Weiterschauen, kürzlich veröffentlicht, usw.).

plex_section_hubs

Kuratierte Hubs, begrenzt auf eine Bibliothekssektion.

plex_related

Plex‘ kuratierte „related“-Hubs für ein Element (herkunftsgruppiert).

plex_similar

Algorithmisch ähnliche Elemente zu einem Element (flache Liste).

plex_refresh_metadata

Metadaten für ein Element vom aktuellen Agenten erneut abrufen (optional force).

plex_get_matches

Kandidaten für ein Element auflisten (TMDB / TVDB etc.); optionale Überschreibungen für Titel/Jahr/Spot Agent/Sprache.

plex_apply_match

Eine gewählte Übereinstimmung (guid/name) auf ein Element anwenden; überschreibt die Bindung an den Agenten.

plex_edit_metadata

Skalare Metadatenfelder (Titel, Zusammenfassung, Jahr, etc.) mit Sperre auf Feldebene überschreiben.

plex_unmatch

Ein Element von seiner Agentenbindung lösen (zurück in den Status „Nicht zugeordnet“); gesperrte Felder bleiben erhalten.

plex_refresh_section

Metadaten-Refresh für eine gesamte Bibliothekssektion auslösen (inkrementell or tief.

plex_split_item

Ein Plex-Element wieder in seine einzelnen Medienvarianten als n separate Elemente Aufteilen.

plex_merge_items

Andere Elemente IN ein Ziel-Element überführen (Quellen werden absorbiert; Ziel bleibt erhalten).

plex_get_image

Poster-/Art-/Banner-/clear-Logo-Bytes für ein Element als MCP-Bildinhaltsblock abrufen (damit Visions-fähige Clients das Bild tatsächlich sehen können); optionale max_width/max_height leiten über den Transcoder von Plex.

plex_save_image

Gleiche Eingabefläche wie plex_get_image, aber SCHREIBT die Bytes unter MCP_IMAGE_SAVE_DIR (Standard: /data/images/) auf die Platte und gibt den Pfad und die Größe zurück. Binde ein Host-Verzeichnis per Bind-Mount an diesen Pfad an, um zu einer nachstehenden Pipeline (ImageMagick, filesystem-mcp-Konsument usw.) zu gelangen, ganz ohne Vision-Render.

plex_download_logs

Das Diagnose-Protokoll-Paket des Plex Media Server selbst (eine ZIP) abrufen und unter MCP_LOG_SAVE_DIR (Standard: /data/logs/) auf Disk schreiben.

plex_list_posters

Alle Poster-Kandidaten für ein Element auflisten (vom Agenten geliefert, lokal gescannt, zuvor hochgeladen), einschließlich des aktuell aktiven.

plex_set_poster

Einen vorhandenen Poster-Kandidaten über dessen eigenen poster_rating_key aus plex_list_posters als aktives Poster festlegen.

plex_upload_poster

Ein neues Poster aus einer externen URL (Plex ruft sie ab) oder einer lokalen Datei unter MCP_IMAGE_SAVE_DIR hinzufügen. Standardmäßig wird es automatisch ausgewählt; select=false fügt es ohne Änderung des Anzeige hinzu.

Related MCP server: Plex Assistant MCP

Konfiguration

Zwei Umgebungsvariablen, beide erforderlich:

Variable

Beispiel

Hinweise

PLEX_URL

http://192.168.1.50:32400

Basis-URL Ihres Plex-Servers

PLEX_TOKEN

(siehe unten)

Plex-Authentifizierungs-Token

Um Ihr Plex-Token zu finden, siehe die Plex-Anleitung zum Finden eines Authentifizierungstokens.

Optionale Umgebungsvariablen

Alle haben funktionierende Standardwerte; setzen Sie sie nur, um diese zu überschreiben.

Variable

Standard

Hinweis

MCP_FETCH_TIMEOUT_MS

30000

Timeout für jede ausgehende Plex-Anfrage außer Log-Downloads

MCP_IMAGE_MAX_BYTES

4194304 (4 MiB)

Größenlimit für plex_get_image/plex_save_image

MCP_LOG_MAX_BYTES

52428800 (50 MiB)

Größenlimit für plex_download_logs

MCP_LOG_FETCH_TIMEOUT_MS

120000 (2 Min.)

Timeout für plex_download_logs – getrennt von MCP_FETCH_TIMEOUT_MS, da ein Log-ZIP ein anderes Größen-/Latenzprofil hat

MCP_SESSION_IDLE_TIMEOUT_MS

3600000 (1 Std.)

Verwird eine MCP-Sitzung im HTTP-Modus nach dieser Inaktivitätsdauer

LOG_LEVEL, MCP_ALLOWED_HOSTS/MCP_ALLOWED_ORIGINS sowie HOST_IMAGE_DIR/HOST_LOG_DIR werden weiter unten in eigenen Abschnitten behandelt (Logging, HTTP-Transport-Härtung, Portainer-Deployment), da jede Variable mehr als eine einzeilige Anmerkung benötigt.

Plex auf demselben Host wie der Container? Verwenden Sie PLEX_URL=http://host.docker.internal:32400. Die Compose-Datei bildet host.docker.internal über extra_hosts auf das Docker-Host-Gateway ab, sodass der Container einen auf dem Host laufenden Plex-Server erreichen kann. Der eigene Hostname des Hosts (z. B. my-nas) lässt sich ohne dieses Mapping aus dem Container heraus nicht auflösen.

Transportmodi

Modus

Verwendung

So starten Sie

stdio (Standard)

Direkter Aufruf durch Claude Desktop / MCP-Clients

docker run -i --rm ... plex-mcp (ohne MCP_PORT)

Streamable HTTP

Dauerhaftigkeit längerer Betrieb (Portainer, Compose, k8s)

MCP_PORT=3000 setzen (in docker-compose.yml bereits erledigt)

Im HTTP-Modus stellt der Server Folgendes bereit:

  • POST/GET/DELETE /mcp – MCP-Streamable-HTTP-Endpunkt (gemäß Spezifikation)

  • GET /health – Liveness-Probe (wird vom Docker-Healthcheck verwendet)

Der HTTP-Modus hat keine Authentifizierung des Aufrufers – TLS (weiter unten) verschlüsselt den Datenverkehr, identifiziert den Aufrufer aber nt. Binden Sie nur an ein privates Netzwerk. Verlassen Sie sich auf die Host-Firewall oder LAN-Isolierung. Setzen Sie es nicht dem öffentlichen Internet aus, ohne zuerst eine Bearer-Token-Authentifizierung hinzuzufügen.

HTTPS aktivieren

HTTPS ist optional (opt-in). Auflösungsreihenfolge beim Start:

  1. Bring-your-own-Zertifikat – Setzen Sie sowohl MCP_TLS_CERT_FILE als also MCP_TLS_KEY_FILE auf PEM-Dateipfade. Verwenden Sie dies, wenn Sie Let's Encrypt oder eine interne CA terminieren. Der Server liest die Dateien beim Start; starten Sie den Container neu, um erneuerte Dateien zu übernehmen.

  2. Selbstverwaltetes Zertifikat (empfohlen für reine LAN-Setups) – Setzen Sie MCP_TLS=auto. Der Server erstellt beim ersten Start ein selbst signiertes ECDSA-P-256-Zertifikat, schreibt es in MCP_TLS_DIR (Standard /data/certs) und verwendet es auch bei späteren starts weiter. Wenn das Zertifikat noch weniger als 30 Tage gültig bleibt, wird es automatisch neu erstellt.

  3. Andernfalls bleibt der Server bei einfachem HTTP (heutiges Standardverhalten).

Variable

Standard

Anmerkungen

MCP_TLS

nicht gesetzt

auto / true / on / 1, um den selbstverwalteten Modus zu aktivieren

MCP_TLS_DIR

/data/certs

Wo server.crt / server.key liegen. Mounten Sie ein Volume, um sie dauerhaft zu sichern.

MCP_TLS_SAN

DNS:localhost,IP:127.0.0.1

Subject Alternative Names. Kommagetrennte DNS:-/IP:-Einträge.

MCP_TLS_CN

erste DNS-SAN, sonst plex-mcp

Allgemeiner Name (Common Name) des Zertifikats.

MCP_TLS_DAYS

365

Gültigkeitsdauer. Das Zertifikat rotiert, wenn weniger als 30 Tage verbleiben.

MCP_TLS_CERT_FILE

nicht gesetzt

Eigenes Zertifikat (PEM). Überschreibt MCP_TLS=auto, wenn es zusammen mit dem Schlüssel gesetzt ist.

MCP_TLS_KEY_FILE

nicht gesetzt

Eigener Schlüssel (PEM).

Beim Start protokolliert der Server den SHA-256-Fingerabdruck des Zertifikats und notAfter. Führen Sie den Fingerabdruck clientseitig fest (Pinning) oder hinterlegen Sie das Zertifikat im Zertifikatsspeicher Ihres Betriebssystems, damit Browser und CLI-Tools ihm vertrauen.

Wenn TLS eingeschaltet ist, benötigt der Compose-Healthcheck das --no-check-certificate-Flag – aktualisieren Sie die test:-Zeile auf ["CMD", "wget", "--no-check-certificate", "-q", "-O-", "https://localhost:3000/health"].

mcp-remote auf einen HTTPS-Endpunkt ausrichten

Für ein selbst signiertes Zertifikat: entweder die Zertifikatdatei über das CA-Bundle von Node pinnen oder die Verifizierung am Client überspringen (nur LAN):

# Trust the server's self-signed cert (preferred):
NODE_EXTRA_CA_CERTS=./server.crt \
  npx -y mcp-remote https://nas.local:3443/mcp

# Or skip verification for quick testing (LAN-only):
NODE_TLS_REJECT_UNAUTHORIZED=0 \
  npx -y mcp-remote https://nas.local:3443/mcp

Reverse-Proxy-Alternative

TLS im selben Prozess ist praktisch, wenn Sie keinen Ingress-Controller betreiben. Wenn Sie Caddy, Traefik oder nginx vor Ihre Heimdienste geschaltet haben, ist das idiomatische Muster, TLS am Proxy zu terminieren (mit automatischem Let's Encrypt) und dieses plex-mcp dahinter mit reinem HTTP zu betreiben. Beide Ansätze sind austauschbar – wählen Sie den, der zu Ihrer bestehenden Umgebung passt.

OAuth-2.1-Bearer-Token-Authentifizierung (opt-in, noch nicht praktisch nutzbar)

Code-seitige Unterstützung für die Authentifizierung geschützter Ressourcen im OAuth-2.1-Bereich existiert (ChatGPT-Apps-SDK, Alignment Phase 2 – siehe docs/CHATGPT-APPS-SDK.md für den vollständigen Plan), ist aber noch nicht so etwas, das Sie tatsächlich einschalten und nutzen können: Dafür ist ein echter OAuth-2.1-Identity-Provider erforderlich, die Token ausstellt, und für diese Bereitstellung ist keiner vorgesehen (das ist Phase 3, noch nicht gestartet). Es wird der Vollständigkeit halber dokumentiert, nicht als Anleitung.

Variable

Anmerkung

MCP_OAUTH_ISSUER

Aussteller-URL des IdP. Wenn gesetzt, aktiviert dies die Authentifizierung – nicht gesetzt (Standard) bedeutet keine Authentifizierung, identisch zum bisherigen Verhalten.

MCP_OAUTH_AUDIENCE

Erforderlich, sobald MCP_OAUTH_ISSUER gesetzt ist. Erwarteter aud-Claim – sollte der kanonischen öffentlichen URL dieses Servers entsprechen. Wenn er fehlt, verweigert der Server den Start.

MCP_OAUTH_REQUIRED_SCOPES

Durch Kommata getrennt. Standard: plex:read.

Wenn aktiviert, benötigt jede /mcp-Anfrage Authorization: Bearer <jwt> – ausgestellt vom konfigurierten IdP, mit der richtigen Audience und Scope. /health ist nie. gefüllt/d be affected: eine eigene Route, und der Docker-Healthcheck kann keine Token anhängen. /.well-known/oauth-protected-resource wird automatisch gemäß RFC 9728 ausgeliefert.

Mit Docker ausführen (stdio, auf Abruf)

docker build -t plex-mcp .
docker run -i --rm \
  -e PLEX_URL=http://192.168.1.50:32400 \
  -e PLEX_TOKEN=your-token \
  plex-mcp

Mit Docker Compose ausführen (HTTP, dauerhaft)

Die Compose-Datei zieht ghcr.io/carldog/plex-mcp:latest (Multi-Arch: linux/amd64 + linux/arm64), die bei jedem Push auf main von der CI veröffentlicht wird.

# Required env vars (or use a .env file):
export PLEX_URL=http://192.168.1.50:32400
export PLEX_TOKEN=your-token
export MCP_ALLOWED_HOSTS=nas.local:3001  # required — see below
export HOST_PORT=3001  # optional, defaults to 3001

docker compose up

Der MCP-Endpunkt befindet sich unter http://<host>:${HOST_PORT}/mcp.

Um statt der Pulls den Container aus dem Quellcode neu zu bauen:

docker build -t ghcr.io/carldog/plex-mcp:latest .
docker compose up

Bereitstellung über Portainer (Stack aus Git)

  1. In Portainer: Stacks → Add Stack → Repository.

  2. Repository-URL: https://github.com/CarlDog/plex-mcp

  3. Compose-Pfad: docker-compose.yml

  4. Umgebungsvariablen: Setzen Sie PLEX_URL, PLEX_TOKEN, MCP_ALLOWED_HOSTS, HOST_IMAGE_DIR und HOST_LOG_DIR – alle erforderlich (siehe unten); optional HOST_PORT.

  5. Bereitstellen. Der Healthcheck wird innerhalb von ~10 Sekunden grün.

MCP_ALLOWED_HOSTS ist im HTTP-Modus erforderlich

Durch Kommaregeln getrennte Liste von Werten des Host-Headers, die der Server auf /mcp akzeptiert – z. B. nas.local:3001 (muss mit der Host:Port übereinstimmen, die ein Client tatsächlich aufgerufen hat, einschließlich des abgebildeten HOST_PORT). Der Server verweigert im HTTP-Modus ohne Liste den Start zu starten, und docker compose config schlägt auf dieselbe Weise fehl, wenn sie nicht gesetzt ist – in dem Fall beides nonsensense, bevor der Container steht, bewusst, statt in einen instsill schweigend geschützten Zustand übergeht.

Der Grund besteht darin, dass die Bindung an 0.0.0.0 im Inneren eines Containers keine echte Zugriffsgrenze ist, wie die Loopback-Bindung auf einem wil ein Host. Ein im Browser irgendwo im LAN geladenes Seite kann DNS-Unverbindung durchführen – den eigenen Hostnamen auf das dieser IP setzen – und Tools wie Schreiboperationen wie plex_delete_playlist als verwirrter Stellvertreter steuern, wobei die Sicherheitshaltung "nur LAN, das gesetzte Bearer-Token" vollständig umgangen wird. Die Host-Allowlist schließt diese Lücke, ohne eine vollständige Authentifizierung zu verlangen. MCP_ALLOWED_ORIGINS (optional, Standardwert leer) bewirkt dasselbe für den Origin-Header – lassen Sie ihn unbesetzt, es sei denn, ein Browser-basierter Client muss tatsächlich direkt von hier aus den Server aufrufen.: Browser-basierte Clients die Brücke mcp-remote, ein direkter fetch senden nie einen Origin-Header, daher lehnt der leere Standard nur die Anfrageform ab, die ein DNS-Rebinding-Angriff tatsächlich sendet.

HOST_IMAGE_DIR und HOST_LOG_DIR sind erforderlich – kein relativer Standardwert

Beide Host-Pfade für Volumes sind in der Compose-Datei ${VAR:?...} angegeben: Es gibt keinen Fallback-Standard, daher schlägt der docker compose up oder ein Portainer-Redeployment bei nicht gesetzter Variable schnell mit einer eindeutigen Meldung fehl, statt starten in einen broken Zustand zu starten.

Früher gab es einen weichen Standardwert ${VAR:-./data/images}, der nur bei einem lokalen docker compose up aus einem stabilen Klon. Bei Portainer Git Stack wird hat es dort als Falle: Jedes redeploy klert das Repo in ein neues Verzeichnis in (z. B. /data/docker/<stack-id>/<commit>/, also) ein relativer Pfad wie ./data/images nicht existiert. Docker verweigerte den Bind-Mount-Zutritt und das Container blieb im Zustand created – er wurde nie gestartet. Das betraf auch automatische Redeploye (Image-Update, Git-Poll) getroffen, sodass ein zuvor gesunder Stack ohne manuellen Eingriff ausfiel und das einzige Symptom dazu nur noch created war. Dadurch nachweisbar einen ausgeführten Stack am 2026-07-31 für ~10 Stunden aus fallen – siehe docker-deployments.md Regel #10 und Fleet-Lektion 2026-07-31-relative-compose-volume-defaults-break-portainer-git-stacks. Die Compose-Datei macht diese Anforderung jetzt strukturell und ist nicht als convention.

So setzen Sie beide in den Umgebungsvariablen des Stacks absolute Host-Pfade:

  • HOST_IMAGE_DIR — das Ausgabeverzeichnis von plex_save_image. Empfohlen: das Host-Verzeichnis, das den Mount /media/_mcp-scratch von filesystem-mcp bereitstellt — z. B. /volume1/Media/_mcp-scratch auf einer Synology NAS — sodass die Pipeline plex_search → plex_save_image → filesystem-mcp in einem gemeinsamen Verzeichnis bleibt.

  • HOST_LOG_DIR — das Ausgabeverzeichnis von plex_download_logs, getrennt von HOST_IMAGE_DIR gehalten, da eine Diagnose-ZIP kein Medienartefakt ist — z. B. /volume1/docker/plex-mcp/logs auf einer Synology NAS (gemäß der Konvention dieser Flotte für Appdata pro Container).

Stellen Sie sicher, dass beide Verzeichnisse auf dem Host vor dem ersten Deployment vorhanden sind. Docker erzeugt eine fehlende Bind-Mount-Quelle nicht automatisch, sondern verweigert den Start des Containers.

Verwendung mit Claude Desktop

stdio (lokaler Aufruf)

{
  "mcpServers": {
    "plex": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "PLEX_URL", "-e", "PLEX_TOKEN",
        "plex-mcp"
      ],
      "env": {
        "PLEX_URL": "http://192.168.1.50:32400",
        "PLEX_TOKEN": "your-token"
      }
    }
  }
}

HTTP (Remote-MCP-Server)

{
  "mcpServers": {
    "plex": {
      "url": "http://nas.local:3001/mcp"
    }
  }
}

(Erfordert Claude Desktop oder einen Client, der Remote-MCP über HTTP unterstützt.)

Lokale Entwicklung

npm install
cp .env.example .env  # then edit
PLEX_URL=... PLEX_TOKEN=... npm run dev               # stdio
MCP_PORT=3000 MCP_ALLOWED_HOSTS=localhost:3000 PLEX_URL=... PLEX_TOKEN=... npm run dev # HTTP

Protokollierung

Der Server schreibt strukturierte Logs nach stderr (stdout ist das MCP-Wire-Protokoll im stdio-Modus und darf nicht verunreinigt werden). Format:

2026-04-29T15:30:00.000Z INFO [tool:plex_browse] invoke section_id=7 type=show limit=2
2026-04-29T15:30:00.337Z INFO [tool:plex_browse] ok ms=337

Konfigurieren Sie die Ausführlichkeit über die Umgebungsvariable LOG_LEVEL (Standard: info):

Level

Zeigt

error

Nur Fehler

warn

+ 4xx-Plex-Antworten

info (Standard)

+ Tool-Aufrufe und -abschlüsse

debug

+ Jeden Plex-API-Aufruf mit Methode, Pfad, Status, ms

trace

(reserviert)

Container-Logs werden vom json-file-Treiber Docker erfasst und automatisch rotiert (10MB × 3 Dateien = ~30MB Limit; die ältesten werden bei der Rotation gelöscht). Anzeigen mit docker logs plex-mcp oder docker logs -f.

Sicherheit

  • Der Container läuft als Nicht-Root-Benutzer (plexmcp).

  • Das Plex-Token wird über eine Umgebungsvariable übergeben — niemals in das Image einbauen.

  • Ein .githooks/pre-commit-Hook führt bei jedem Commit gitleaks aus. Aktivieren Sie ihn einmal pro Clone: git config core.hooksPath .githooks

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables users to manage and control their Plex media library through natural language commands in MCP-compatible AI clients. It supports searching content, managing playlists, tracking library statistics, and monitoring live viewing sessions.
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for reelgrep - browse and search your local video library from any MCP client.
    10 npm
    MIT