Skip to main content
Glama
CarlDog
by CarlDog

plex-mcp

code confidence · claude-opus-4-8[1m] · 2026-07-07 · подробности

MCP-сервер для Plex Media Server, упакованный в Docker-контейнер. Позволяет MCP-клиенту (Claude Desktop и т. д.) просматривать и искать в ваших библиотеках Plex.

Инструменты

Tool

Описание

plex_list_libraries

Список всех библиотек (разделов) на сервере

plex_search

Поиск по всем библиотекам

plex_hub_search

Поиск через эндпоинт hub-search в Plex, включая коллекции (в отличие от plex_search)

plex_recently_added

Недавно добавленные элементы, опционально по разделам

plex_on_deck

Элементы «on deck» (частично просмотренные / следующие); опциональный section_id ограничивает одну секцию библиотеки

plex_get_item

Метаданные для элемента по rating key. Передайте minimal=true, чтобы убрать громоздкие массивы актёров/съёмочной группы/изображений (~80% уменьшение размера для фильмов с большим актёрским составом) с сохранением информации о дорожках субтитров; передайте fields=[...] для явной проекции

plex_browse

Список элементов в секции библиотеки (постранично, опциональный фильтр по типу, опциональный фильтр по названию коллекции, опциональная разреженная fields проекция)

plex_list_collections

Список коллекций в секции библиотеки (тонкая обёртка над типом коллекции из plex_browse)

plex_get_children

Дочерние элементы элемента (сериал→сезоны, сезон→эпизоды, артист→альбомы)

plex_now_playing

Текущие сеансы воспроизведения на сервере

plex_history

Записи истории воспроизведения (постранично, сначала новые)

plex_mark_watched

Отметить элемент как просмотренный (обратимо)

plex_mark_unwatched

Отметить элемент как непросмотренный (обратимо)

plex_rate_item

Установить пользовательскую рейтинговую оценку элемента от 0 до 10; опустите rating, чтобы вернуть его к неоценённому состоянию

plex_list_playlists

Список всех плейлистов (обычные + умные)

plex_get_playlist_items

Список содержимого плейлиста

plex_create_playlist

Создать обычный плейлист, начинающийся с одного элемента

plex_add_to_playlist

Добавить элемент в конец обычного плейлиста

plex_remove_from_playlist

Удалить элемент по playlistItemID

plex_delete_playlist

Удалить плейлист (только метаданные — медиа не затрагивается)

plex_hubs

Курируемые Plex серверные хабы (Continue Watching, Recently Released и т.д.)

plex_section_hubs

Курируемые хабы, ограниченные одной секцией библиотеки

plex_related

Курируемые Plex хабы «похожие» для элемента (сгруппированные по источнику)

plex_similar

Алгоритмическая рекомендательная аналога для элемента (плоский список)

plex_refresh_metadata

Повторно получить метаданные для элемента из его текущего агента (опционально force)

plex_get_matches

Список возможных совпадений для элемента (TMDB / TVDB / и т.д.); опциональные переопределения title/year/agent/language

plex_apply_match

Применить выбранное совпадение (guid/name) к элементу; перезаписывает привязку агента

plex_edit_metadata

Переопределить скалярные поля метаданных (title, summary, year и т.д.) с блокировкой на уровне полей

plex_unmatch

Отвязать элемент от привязки агента (вернуть в состояние без совпадения); заблокированные поля сохраняются

plex_refresh_section

Запустить обновление метаданных для целой секции библиотеки (инкрементальное или полное)

plex_split_item

Разделить элемент Plex обратно на составляющие его медиа-варианты как N отдельных элементов

plex_merge_items

Объединить другие элементы в целевой элемент (исходные поглощаются; целевой сохраняется)

plex_get_image

Получить байты постера/арта/баннера/clearLogo для элемента как MCP-блок изображения (чтобы клиенты со зрительными возможностями могли видеть картинку); опциональные max_width/max_height направляются через транскодер Plex

plex_save_image

Та же входная поверхность, что у plex_get_image, но ЗАПИСЫВАЕТ байты на диск в MCP_IMAGE_SAVE_DIR (по умолчанию /data/images/) и возвращает путь + размер. Примонтируйте bind-mount хост-каталога в этот путь, чтобы связать его с последующим конвейером (ImageMagick, consumer filesystem-mcp и т.д.) без визуальной отрисовки.

plex_download_logs

Получить собственный пакет диагностических журналов Plex Media Server (ZIP) и записать его на диск в MCP_LOG_SAVE_DIR (по умолчанию /data/logs/)

plex_list_posters

Список всех кандидатов на постер для элемента (предоставленные агентом, локально отсканированные, ранее загруженные), включая тот, который сейчас активен

plex_set_poster

Выбрать существующего кандидата в постеры как активного по его собственному poster_rating_key из plex_list_posters (не имеет обратного)

plex_upload_poster

Добавить новый постер с внешнего URL (Plex его загружает) или локального файла в MCP_IMAGE_SAVE_DIR. По умолчанию автоматически выбирает его; select=false добавляет его без изменения текущего отображаемого постера

Related MCP server: Plex Assistant MCP

Конфигурация

Две переменные окружения, обе обязательные:

Var

Example

Notes

PLEX_URL

http://192.168.1.50:32400

Базовый URL вашего Plex-сервера

PLEX_TOKEN

(см. ниже)

Токен аутентификации Plex

Чтобы найти токен Plex, см. руководство Plex Поиск токена аутентификации.

Необязательные переменные окружения

У всех есть рабочие значения по умолчанию; задавайте их только для переопределения.

Var

Default

Notes

MCP_FETCH_TIMEOUT_MS

30000

Таймаут для каждого исходящего запроса к Plex, кроме загрузки логов

MCP_IMAGE_MAX_BYTES

4194304 (4 MiB)

Максимальный размер для plex_get_image/plex_save_image

MCP_LOG_MAX_BYTES

52428800 (50 MiB)

Максимальный размер для plex_download_logs

MCP_LOG_FETCH_TIMEOUT_MS

120000 (2 мин)

Таймаут для plex_download_logs — отдельно от MCP_FETCH_TIMEOUT_MS, поскольку ZIP-архив логов имеет иной профиль размера/задержки

MCP_SESSION_IDLE_TIMEOUT_MS

3600000 (1 ч)

Вытесняет MCP-сессию в HTTP-режиме после такого периода бездействия

LOG_LEVEL, MCP_ALLOWED_HOSTS/MCP_ALLOWED_ORIGINS и HOST_IMAGE_DIR/HOST_LOG_DIR описаны в отдельных разделах ниже (журналирование, усиление HTTP-транспорта, развертывание в Portainer), поскольку каждому из них нужно больше, чем однострочное примечание.

Plex на том же хосте, что и контейнер? Используйте PLEX_URL=http://host.docker.internal:32400. В compose-файле host.docker.internal сопоставляется со шлюзом хоста Docker через extra_hosts, поэтому контейнер может обратиться к серверу Plex, работающему на хосте. Собственное имя хоста (например, my-nas) не будет резолвиться из контейнера без такого сопоставления.

Режимы транспорта

Mode

Когда использовать

Как запустить

stdio (по умолчанию)

Прямой вызов из Claude Desktop / MCP-клиентов

docker run -i --rm ... plex-mcp (без MCP_PORT)

Streamable HTTP

Долгоживущее развертывание (Portainer, Compose, k8s)

Задайте MCP_PORT=3000 (уже сделано в docker-compose.yml)

В HTTP-режиме сервер предоставляет:

  • POST/GET/DELETE /mcp — конечная точка MCP Streamable HTTP (по спецификации)

  • GET /health — проверка живости (используется docker healthcheck)

В HTTP-режиме нет аутентификации вызывающей стороны — TLS (см. ниже) шифрует трафик, но не идентифицирует вызывающего. Привязывайте только к частной сети. Полагайтесь на межсетевой экран хоста или изоляцию LAN. Не открывайте доступ в публичный интернет без добавления авторизации через bearer-токен.

Включение HTTPS

HTTPS включается по желанию. Порядок разрешения при запуске:

  1. Свой сертификат — задайте и MCP_TLS_CERT_FILE, и MCP_TLS_KEY_FILE, указав пути к PEM-файлам. Используйте этот вариант при завершении TLS для Let's Encrypt или внутреннего УЦ. Сервер читает их при запуске; перезапустите контейнер, чтобы подхватить обновленные файлы.

  2. Самоуправляемый сертификат (рекомендуется для настроек только в LAN) — задайте MCP_TLS=auto. Сервер генерирует самоподписанный сертификат ECDSA P-256 при первом запуске, записывает его в MCP_TLS_DIR (по умолчанию /data/certs) и использует его повторно при последующих запусках. Когда до истечения срока действия сертификата останется менее 30 дней, он автоматически пересоздается.

  3. В противном случае сервер остается на обычном HTTP (текущее поведение по умолчанию).

Var

Default

Notes

MCP_TLS

не задано

auto / true / on / 1 для включения самоуправляемого режима

MCP_TLS_DIR

/data/certs

Где находятся server.crt / server.key. Смонтируйте том для сохранения.

MCP_TLS_SAN

DNS:localhost,IP:127.0.0.1

Имена субъектов (SAN). Разделенные запятыми записи DNS: / IP:.

MCP_TLS_CN

первый DNS SAN, иначе plex-mcp

Общее имя сертификата.

MCP_TLS_DAYS

365

Срок действия. Сертификат ротируется, когда остается <30 дней.

MCP_TLS_CERT_FILE

не задано

Свой сертификат (PEM). Переопределяет MCP_TLS=auto, если задан вместе с ключом.

MCP_TLS_KEY_FILE

не задано

Свой ключ (PEM).

При запуске сервер логирует SHA-256 отпечаток сертификата и notAfter. Закрепите отпечаток на стороне клиента или доверьтесь сертификату в хранилище ключей ОС для браузеров и CLI-инструментов.

Когда TLS включен, healthcheck в compose требует флаг --no-check-certificate — обновите строку test: до ["CMD", "wget", "--no-check-certificate", "-q", "-O-", "https://localhost:3000/health"].

Настройка mcp-remote на HTTPS-конечную точку

Для самоподписанного сертификата либо закрепите файл сертификата через CA-бандл Node, либо отключите проверку на клиенте (только для 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

Альтернатива через обратный прокси

Встроенный TLS удобен, если у вас уже нет контроллера входящего трафика. Если перед вашими домашними сервисами стоит Caddy, Traefik или nginx, более идиоматичный подход — завершать TLS на прокси (с автоматическим Let's Encrypt), а plex-mcp оставлять на обычном HTTP за ним. Оба подхода взаимозаменяемы — выбирайте тот, который соответствует вашей существующей настройке.

Авторизация OAuth 2.1 по bearer-токену (опционально, пока практически неприменима)

Поддержка на стороне кода для защиты ресурсов OAuth 2.1 существует (согласование с ChatGPT Apps SDK, этап 2 — полный план см. в docs/CHATGPT-APPS-SDK.md), но это пока нельзя реально включить и использовать: нужен настоящий поставщик удостоверений OAuth 2.1, выпускающий токены, а для этого развертывания он не предусмотрен (это этап 3, не начат). Здесь описано для полноты, а не как инструкция.

Var

Notes

MCP_OAUTH_ISSUER

URL эмитента IdP. Установка этого параметра включает аутентификацию — если не задано (по умолчанию), аутентификация отсутствует, как и сегодня.

MCP_OAUTH_AUDIENCE

Обязательно, если задан MCP_OAUTH_ISSUER. Ожидаемое значение claim aud — должно равняться каноническому публичному URL этого сервера. Сервер отказывается запускаться, если параметр отсутствует.

MCP_OAUTH_REQUIRED_SCOPES

Через запятую. По умолчанию plex:read.

Когда включено, каждый запрос /mcp должен содержать Authorization: Bearer <jwt> — выданный настроенным IdP, с правильной аудиторией и областью. /health не затрагивается (это отдельный маршрут, и собственный healthcheck Docker не имеет возможности прикрепить bearer-токен). /.well-known/oauth-protected-resource обслуживается автоматически согласно RFC 9728.

Запуск с Docker (stdio, по требованию)

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

Запуск с Docker Compose (HTTP, долгоживущий)

Compose-файл тянет образ ghcr.io/carldog/plex-mcp:latest (мультиархитектурный: linux/amd64 + linux/arm64), публикуемый CI при каждом пуше в main.

# 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

Конечная точка MCP будет доступна по адресу http://<host>:${HOST_PORT}/mcp.

Чтобы пересобрать из исходников вместо скачивания образа:

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

Развертывание через Portainer (Stack из Git)

  1. В Portainer: Стеки → Добавить стек → Репозиторий.

  2. URL репозитория: https://github.com/CarlDog/plex-mcp

  3. Путь к Compose-файлу: docker-compose.yml

  4. Переменные окружения: задайте PLEX_URL, PLEX_TOKEN, MCP_ALLOWED_HOSTS, HOST_IMAGE_DIR и HOST_LOG_DIR — все обязательны (см. ниже); опционально HOST_PORT.

  5. Разверните. Healthcheck становится зеленым примерно через 10 секунд.

MCP_ALLOWED_HOSTS обязателен в HTTP-режиме

Список значений заголовка Host, разделенных запятыми, которые сервер принимает на /mcp — например, nas.local:3001 (должен совпадать с фактическим host:port, который использует клиент, включая проброшенный HOST_PORT). Без него сервер отказывается запускаться в HTTP-режиме, и docker compose config также завершается ошибкой, если он не задан — оба случая намеренно завершаются до запуска контейнера, а не запускаются в состоянии, незаметно лишенном защиты.

Это сделано потому, что привязка 0.0.0.0 внутри контейнера не является реальной границей доступа, в отличие от привязки к loopback на обычном хосте: страница, загруженная в браузере в любом месте LAN, может выполнить DNS-ребендинг — указав собственное имя хоста на IP этого контейнера — и использовать инструменты (включая операции записи, такие как plex_delete_playlist) в роли запутанного посредника, полностью обходя "только-LAN, без bearer-токена" как модель безопасности. Список разрешенных Host закрывает эту брешь без необходимости полной аутентификации. MCP_ALLOWED_ORIGINS (необязательно, по умолчанию пусто) делает то же самое для заголовка Origin — оставьте его незаданным, если только браузерный клиент действительно не должен вызывать этот сервер напрямую; небраузерные клиенты (мост mcp-remote, прямой fetch) никогда не отправляют заголовок Origin, поэтому пустое значение по умолчанию отвергает только ту форму запроса, которую реально отправляет DNS-ребендинговая атака.

HOST_IMAGE_DIR и HOST_LOG_DIR обязательны — относительного значения по умолчанию нет

Оба host-пути для томов заданы как ${VAR:?...} в compose-файле: запасного значения по умолчанию нет, поэтому docker compose up / повторное развертывание в Portainer быстро завершится с понятной ошибкой, если какой-либо из параметров не задан, а не запустится в нерабочем состоянии.

Раньше здесь использовалось мягкое значение по умолчанию ${VAR:-./data/images}, которое безопасно только для локального docker compose up из стабильного клона. В стеке Portainer из git это ловушка: каждое повторное развертывание клонирует репозиторий в свежую директорию для конкретного коммита (/data/compose/<stack-id>/<commit>/), где относительного пути вроде ./data/images не существует. Docker отклонял bind-mount, и контейнер оставался в состоянии created — он так и не запускался. Это также затрагивало автоматические повторные развертывания (обновление образа, git-поллинг), поэтому ранее здоровый стек падал без ручного вмешательства; единственным симптомом был контейнер в состоянии created. Из-за этого развернутый стек простоял около 10 часов 2026-07-31 — см. правило №10 в docker-deployments.md и урок для флота 2026-07-31-relative-compose-volume-defaults-break-portainer-git-stacks. Теперь compose-файл делает это требование структурным, а не просто соглашением из документации.

Задайте обе как абсолютные пути на хосте в переменных окружения стека:

  • HOST_IMAGE_DIR — каталог вывода для plex_save_image. Рекомендуется: каталог на хосте, обеспечивающий монтирование /media/_mcp-scratch для filesystem-mcp — например, /volume1/Media/_mcp-scratch на Synology NAS — так конвейер plex_search → plex_save_image → filesystem-mcp остаётся в одном общем каталоге.

  • HOST_LOG_DIR — каталог вывода для plex_download_logs, хранящийся отдельно от HOST_IMAGE_DIR, поскольку диагностический ZIP не является медиафайлом — например, /volume1/docker/plex-mcp/logs на Synology NAS (в соответствии с принятым в этом флоте правилом appdata для каждого контейнера).

Убедитесь, что оба каталога существуют на хосте до первого развёртывания: Docker не создаёт отсутствующий источник bind-mount автоматически, он просто отказывается запускать контейнер.

Использование с Claude Desktop

stdio (локальный вызов)

{
  "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 (удалённый MCP-сервер)

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

(Требуется Claude Desktop или клиент, поддерживающий удалённый MCP по HTTP.)

Локальная разработка

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

Логирование

Сервер отправляет структурированные логи в stderr (в stdio-режиме stdout — это транспорт для протокола MCP, и его нельзя засорять). Формат:

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

Настройте детализацию через переменную окружения LOG_LEVEL (по умолчанию info):

| error | Только ошибки | | warn | + Ответы Plex с кодом ошибки 4xx | | info (по умолчанию) | + Вызовы и завершения инструментов | | debug | + каждый вызов Plex API с методом, путём, статусом, ms | | trace | (зарезервировано) | | Level | Shows |

| ---------------- | --------------------------------------------------- | | error | Errors only | | warn | + 4xx Plex responses | | info (default) | + Tool invocations and completions | | debug | + Every Plex API call with method, path, status, ms | | trace | (reserved) |

Logging

Container logs are collected by Docker's json-file and rotated automatically (10MB × 3 files = ~30MB cap; oldest deleted on rotation). View with docker ls or docker ps.

Security

  • The container runs as a non-root user (plexmcp).

  • The Plex token is passed via env var — never bake it into the image.

  • A .githooks/pre-commit runs gitleaks on every commit. Activate it once per clone: git config core.hooksPath .githooks

Each section and definition has been translated, keeping all technical identifiers (HOST_IMAGE_DIR, HOST_LOG_DIR, plex_save_image, filesystem-mcp, /media/_mcp-scratch, /volume1/Media/_mcp-scratch, Synology NAS, plex_download_logs, /volume1/docker/plex-mcp/logs, Claude Desktop, stdio, GXP5, GXP6, GXP7, GXP8, LOG_LEVEL, etc.) unchanged. The list structure, tables, and markdown emphasis are preserved. This translation replaces the English source and returns only the Russian text as output.* HOST_IMAGE_DIR — каталог вывода для plex_save_image. Рекомендуется: каталог на хосте, обеспечивающий монтирование /media/_mcp-scratch для filesystem-mcp — например, /volume1/Media/_mcp-scratch на Synology NAS — так конвейер plex_search → plex_save_image → filesystem-mcp остаётся в одном общем каталоге.

  • HOST_LOG_DIR — каталог вывода для plex_download_logs, хранящийся отдельно от HOST_IMAGE_DIR, поскольку диагностический ZIP не является медиафайлом — например, /volume1/docker/plex-mcp/logs на Synology NAS (в соответствии с принятым в этом флоте правилом хранения данных контейнеров).

Убедитесь, что оба каталога существуют на хосте до первого развёртывания: Docker не может автоматически создать отсутствующий bind-mount источник, он просто откажется запускать контейнер.

Использование с Claude Desktop

stdio (локальная отправка)

{
  "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 (удалённый MCP-сервер)

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

(Требуется Claude Desktop или клиент, поддерживающий удалённый MCP по HTTP.)

Локальная разработка

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

Логирование

Lighthouse | сервер выводит структурированные логи в stderr (в stdio-режиме stdout является транспортным каналом MCP и не должен загрязняться). Формат:

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

Настройка подробности через переменную окружения LOG_LEVEL (по умолчанию — info):

Уровень

Показывает

error

Только ошибки

warn

+ ответы Plex с кодом 4xx

info (по умолчанию)

+ вызовы и завершение инструментов

debug

+ каждый вызов API Plex с методом, путём, статусом, мс

trace

(зарезервировано)

Логи контейнеров сохраняются драйвером json-file Docker и ротируются автоматически (10MB × 3 файла = ~30MB; самый старый удаляется при ротации). Просмотр — docker logs plex-mcp или docker logs -f.

Безопасность

  • Контейнер запускается от непривилегированного пользователя (plexmcp).

  • Токен Plex передаётся через переменную окружения — никогда не вшивайте его в образ.

  • .githooks/pre-commit запускает gitleaks при каждом коммите. Активируйте его один раз для каждого клона: git config core.hooksPath .githooks

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityActive
ResponsivenessWithin a week

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

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
    B
    maintenance
    MCP server for reelgrep - browse and search your local video library from any MCP client.
    11
    MIT

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/CarlDog/plex-mcp'

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