plex-mcp
plex-mcp
·
claude-opus-4-8[1m] · 2026-07-07 · подробности
MCP-сервер для Plex Media Server, упакованный в Docker-контейнер. Позволяет MCP-клиенту (Claude Desktop и т. д.) просматривать и искать в ваших библиотеках Plex.
Инструменты
Tool | Описание |
| Список всех библиотек (разделов) на сервере |
| Поиск по всем библиотекам |
| Поиск через эндпоинт hub-search в Plex, включая коллекции (в отличие от |
| Недавно добавленные элементы, опционально по разделам |
| Элементы «on deck» (частично просмотренные / следующие); опциональный |
| Метаданные для элемента по rating key. Передайте |
| Список элементов в секции библиотеки (постранично, опциональный фильтр по типу, опциональный фильтр по названию коллекции, опциональная разреженная |
| Список коллекций в секции библиотеки (тонкая обёртка над типом коллекции из |
| Дочерние элементы элемента (сериал→сезоны, сезон→эпизоды, артист→альбомы) |
| Текущие сеансы воспроизведения на сервере |
| Записи истории воспроизведения (постранично, сначала новые) |
| Отметить элемент как просмотренный (обратимо) |
| Отметить элемент как непросмотренный (обратимо) |
| Установить пользовательскую рейтинговую оценку элемента от 0 до 10; опустите |
| Список всех плейлистов (обычные + умные) |
| Список содержимого плейлиста |
| Создать обычный плейлист, начинающийся с одного элемента |
| Добавить элемент в конец обычного плейлиста |
| Удалить элемент по |
| Удалить плейлист (только метаданные — медиа не затрагивается) |
| Курируемые Plex серверные хабы (Continue Watching, Recently Released и т.д.) |
| Курируемые хабы, ограниченные одной секцией библиотеки |
| Курируемые Plex хабы «похожие» для элемента (сгруппированные по источнику) |
| Алгоритмическая рекомендательная аналога для элемента (плоский список) |
| Повторно получить метаданные для элемента из его текущего агента (опционально |
| Список возможных совпадений для элемента (TMDB / TVDB / и т.д.); опциональные переопределения title/year/agent/language |
| Применить выбранное совпадение ( |
| Переопределить скалярные поля метаданных (title, summary, year и т.д.) с блокировкой на уровне полей |
| Отвязать элемент от привязки агента (вернуть в состояние без совпадения); заблокированные поля сохраняются |
| Запустить обновление метаданных для целой секции библиотеки (инкрементальное или полное) |
| Разделить элемент Plex обратно на составляющие его медиа-варианты как N отдельных элементов |
| Объединить другие элементы в целевой элемент (исходные поглощаются; целевой сохраняется) |
| Получить байты постера/арта/баннера/clearLogo для элемента как MCP-блок изображения (чтобы клиенты со зрительными возможностями могли видеть картинку); опциональные max_width/max_height направляются через транскодер Plex |
| Та же входная поверхность, что у |
| Получить собственный пакет диагностических журналов Plex Media Server (ZIP) и записать его на диск в |
| Список всех кандидатов на постер для элемента (предоставленные агентом, локально отсканированные, ранее загруженные), включая тот, который сейчас активен |
| Выбрать существующего кандидата в постеры как активного по его собственному |
| Добавить новый постер с внешнего URL (Plex его загружает) или локального файла в |
Related MCP server: Plex Assistant MCP
Конфигурация
Две переменные окружения, обе обязательные:
Var | Example | Notes |
|
| Базовый URL вашего Plex-сервера |
| (см. ниже) | Токен аутентификации Plex |
Чтобы найти токен Plex, см. руководство Plex Поиск токена аутентификации.
Необязательные переменные окружения
У всех есть рабочие значения по умолчанию; задавайте их только для переопределения.
Var | Default | Notes |
|
| Таймаут для каждого исходящего запроса к Plex, кроме загрузки логов |
|
| Максимальный размер для |
|
| Максимальный размер для |
|
| Таймаут для |
|
| Вытесняет 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-клиентов |
|
Streamable HTTP | Долгоживущее развертывание (Portainer, Compose, k8s) | Задайте |
В HTTP-режиме сервер предоставляет:
POST/GET/DELETE /mcp— конечная точка MCP Streamable HTTP (по спецификации)GET /health— проверка живости (используется docker healthcheck)
В HTTP-режиме нет аутентификации вызывающей стороны — TLS (см. ниже) шифрует трафик, но не идентифицирует вызывающего. Привязывайте только к частной сети. Полагайтесь на межсетевой экран хоста или изоляцию LAN. Не открывайте доступ в публичный интернет без добавления авторизации через bearer-токен.
Включение HTTPS
HTTPS включается по желанию. Порядок разрешения при запуске:
Свой сертификат — задайте и
MCP_TLS_CERT_FILE, иMCP_TLS_KEY_FILE, указав пути к PEM-файлам. Используйте этот вариант при завершении TLS для Let's Encrypt или внутреннего УЦ. Сервер читает их при запуске; перезапустите контейнер, чтобы подхватить обновленные файлы.Самоуправляемый сертификат (рекомендуется для настроек только в LAN) — задайте
MCP_TLS=auto. Сервер генерирует самоподписанный сертификат ECDSA P-256 при первом запуске, записывает его вMCP_TLS_DIR(по умолчанию/data/certs) и использует его повторно при последующих запусках. Когда до истечения срока действия сертификата останется менее 30 дней, он автоматически пересоздается.В противном случае сервер остается на обычном HTTP (текущее поведение по умолчанию).
Var | Default | Notes |
| не задано |
|
|
| Где находятся |
|
| Имена субъектов (SAN). Разделенные запятыми записи |
| первый DNS SAN, иначе | Общее имя сертификата. |
|
| Срок действия. Сертификат ротируется, когда остается <30 дней. |
| не задано | Свой сертификат (PEM). Переопределяет |
| не задано | Свой ключ (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 |
| URL эмитента IdP. Установка этого параметра включает аутентификацию — если не задано (по умолчанию), аутентификация отсутствует, как и сегодня. |
| Обязательно, если задан |
| Через запятую. По умолчанию |
Когда включено, каждый запрос /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)
В Portainer: Стеки → Добавить стек → Репозиторий.
URL репозитория:
https://github.com/CarlDog/plex-mcpПуть к Compose-файлу:
docker-compose.ymlПеременные окружения: задайте
PLEX_URL,PLEX_TOKEN,MCP_ALLOWED_HOSTS,HOST_IMAGE_DIRиHOST_LOG_DIR— все обязательны (см. ниже); опциональноHOST_PORT.Разверните. 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-commitruns 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):
Уровень | Показывает |
| Только ошибки |
| + ответы Plex с кодом 4xx |
| + вызовы и завершение инструментов |
| + каждый вызов API Plex с методом, путём, статусом, мс |
| (зарезервировано) |
Логи контейнеров сохраняются драйвером 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.
This server cannot be installed
Maintenance
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
Search events, conference weeks, cities, venues and artist schedules via remote MCP.
Search and browse every MCP server in the Model Context Protocol registry.
The official Planning Center MCP server for interacting with your ministry's data.
Reddit MCP server: search posts, subreddit feeds, comments & user profiles as JSON. No API key.
Related MCP Servers
- FlicenseAqualityFmaintenanceA Python-based MCP server that integrates with Plex Media Server API to search for movies and manage playlists in your Plex media library.96-
- AlicenseNot gradedqualityDmaintenanceEnables 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
- AlicenseNot gradedqualityBmaintenanceMCP server for reelgrep - browse and search your local video library from any MCP client.11MIT
- AlicenseAqualityCmaintenanceMCP server for Plex Media Server, focused on media discovery, search, library management, and playback control.25MIT
Appeared in Searches
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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