plex-mcp
plex-mcp
·
claude-opus-4-8[1m] · 2026-07-07 · detalles
Un servidor MCP para Plex Media Server, empaquetado como un contenedor Docker. Permite que un cliente MCP (Claude Desktop, etc.) explore y busque en tus bibliotecas de Plex.
Herramientas
工具 | 描述 |
| 列出服务器上的所有媒体库(分区) |
| 在所有媒体库中搜索 |
| 通过 Plex 的集线器搜索端点进行搜索,包括收藏集(不同于 |
| 最近添加的项目,可选项按分区筛选 |
| “正在播放”(部分观看 / 下一个)的项目;可选的 |
| 通过评分键获取某一项目的元数据。传递 |
| 列出媒体库分区中的项目(分页,可选类型筛选,可选 |
| 列出媒体库分区中的收藏集(对 |
| 某项目的子项(剧季→剧集,季→剧集,艺术家→专辑) |
| 服务器上当前播放中的会话 |
| 播放历史记录(分页,最新的在前) |
| 将项目标记为已观看(可撤销) |
| 将项目标记为未观看(可撤销) |
| 设置项目的 0-10 分用户评分;省略 |
| 列出所有播放列表(常规 + 智能) |
| 列出播放列表的内容 |
| 创建以单个项目为种子的常规播放列表 |
| 将项目追加到常规播放列表 |
| 通过 |
| 删除播放列表(仅元数据——媒体文件不受影响) |
| Plex 策划的服务器范围中心(继续观看、最近发布等) |
| 限定到某一个媒体库分区的策划中心 |
| Plex 针对某一项目的“相关”策划中心(按来源分组) |
| 某项目的算法推荐相似项目(平面列表) |
| 从当前代理重新拉取项目的元数据(可选 |
| 列出项目(TMDB / TVDB 等)的候选匹配;可选标题/年份/代理/语言覆盖 |
| 将选定的匹配( |
| 覆盖标量元数据字段(标题、简介、年份等),带字段级锁定 |
| 将项目从代理绑定中分离(恢复未匹配状态);上锁的字段不受影响 |
| 对整个媒体库分区触发元数据刷新(增量或深层) |
| 将 Plex 项目拆分为其组成媒体变体,作为 N 个单独项目 |
| 将其他项目合并到目标项目中(来源被并入;目标项目保留) |
| 获取某个项目的海报/封面/背景图/透明图字节,作为 MCP 图像内容块(可让视觉型客户端真正看到图片);可选 max_width/max_height 经由 Plex 转码器的路径路由 |
| 与 |
| 获取 Plex Media Server 自身的诊断日志包(ZIP),写入 |
| 列出某个项目的所有候选海报(由代理提供、本地扫描、之前上传的),包括当前生效的是哪一个 |
| 从 |
| 从外部 URL(Plex 获取)或 |
Related MCP server: Plex Assistant MCP
Configuración
Dos variables de entorno, ambas obligatorias:
Variable | Ejemplo | Notas |
|
| URL base de tu servidor Plex |
| (ver más abajo) | Token de autenticación de Plex |
Para encontrar tu token de Plex, consulta la guía de Plex sobre cómo encontrar un token de autenticación.
Variables opcionales
Todas tienen valores predeterminados; configúralas solo para anularlos.
Variable | Predeterminado | Notas |
|
| Tiempo de espera para cada solicitud saliente de Plex, excepto descargas de registros. |
|
| Límite máximo para |
|
| Límite máximo para |
|
| Tiempo de espera para |
|
| Expulsa una sesión MCP en modo HTTP después de esta inactividad. |
LOG_LEVEL, MCP_ALLOWED_HOSTS/MCP_ALLOWED_ORIGINS y
HOST_IMAGE_DIR/HOST_LOG_DIR se tratan en sus propias secciones
a continuación (Registro, endurecimiento del transporte HTTP, despliegue de Porttainer), ya que cada una
necesita más de una nota de una línea.
¿Plex en el mismo host que el contenedor? Usa
PLEX_URL=http://host.docker.internal:32400. El archivo de compose mapeahost.docker.internala la puerta de enlace del host de Docker víaextra_hosts, para que el contenedor pueda alcanzar un servidor Plex ejecutándose en el host. El propio nombre de host (p. ej.mi-nas) no se resolverá desde dentro del contenedor sin ese mapeo.
Modos de transporte
Modo | Cuándo usarlo | Cómo iniciarlo |
stdio (predeterminado) | Invocación directa por Claude Desktop / clientes MCP |
|
HTTP transmisible | Despliegue de larga duración (Portainer, Compose, k8s) | Configurar |
En modo HTTP, el servidor expone:
POST/GET/DELETE /mcp— punto de conexión HTTP transmisible de MCP (según especificación)GET /health— sonda de vida (usada por Docker healthcheck)
El modo HTTP no tiene autenticación de llamador — TLS (más abajo) cifra el tráfico pero no identifica al llamador. Vincula solo a una red privada. Confía en el cortafuegos del host o aislamiento de LAN. Esto no no debe exponerse a internet pública sin agregar primero autenticación de token portador.
Habilitando HTTPS
HTTPS es opcional. Orden de resolución en el arranque:
Trae tu propio certificado — configura tanto
MCP_TLS_CERT_FILEcomoMCP_TLS_KEY_FILEcon rutas de archivo PEM. Úsalo al terminar Let's Encrypt o una CA interna. El servidor los lee en el arranque; reinicia el contenedor para recoger archivos renovados.Certificado autogestionado (recomendado solo para LAN) — configura
MCP_TLS=auto. El servidor genera un certificado ECDSA P-256 autofirmado en el primer arranque, lo escribe enMCP_TLS_DIR(predeterminado/datos/certs) y lo reutiliza en los siguientes arranques. Cuando el certificado está dentro de los 30 días de su caducidad se vuelve a generar automáticamente.De lo contrario, el servidor permanece en HTTP simple (predeterminado actual).
Variable | Predeterminado | Notas |
| sin establecer |
|
|
| Dónde viven |
|
| Nombres alternativos de sujeto. Entradas separadas por comas |
| primer DNS SAN, si no | Nombre común del certificado. |
|
| Período de validez. Se rota cuando quedan <30 días Kuando quedan <30 días. |
| sin definir | Certificado BYO (PEM). Reemplaza |
| sin definir | Clave BYO (PEM). |
En el arranque, el servidor registra la huella SHA-256 del cert y
notAfter. Fija la huella en el lado del cliente; o confía en el certificado en
el almacén de claves de tu sistema operativo para navegadores y herramientas CLI.
Cuando TLS está activado, el healthcheck de compose necesita la
--no-checar-certificado. Actualizar la línea test: a
["CMD", "wget", "--no-check-certificate", "-q", "-O-", "https://localhost:3000/health"].
Apuntando mcp-remote a un endpoint HTTPS
Para un certificado autofirmado, puedes fijar el archivo de certificado de Node (bundle CA) o omitir la verificación en el cliente (solo 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/mcpAlternativa de proxy inverso
TLS en el proceso es conveniente cuando no tienes un controlador de ingreso
ya. Si tienes Caddy, Plex/Plex, o nginx delante de tu
servicio/servicio en el hogar, el patrón más idiomático es terminar TLS en
el proxy (con Let's Encrypt automático) y mantener plex-mcp en
HTTP simple detrás. Ambos enfoques son intercambiables — elige
El que coincida con tu configuración existente.
Autenticación OAuth 2.1 bearer-token (opt-in, aún no práctica)
Sopungojo.
The text "Soporte de código para autenticación..." etc.
Let's translate.
Need include "es eso" etc.
"### Autenticación OAuth 2.1 bearer-token (opt-in, aún no práctica)
El soporte de código para la autenticación de recursos protegidos OAuth 2.1 existe (Alineación de SDK de ChatGPT ...) (ver docs/CHATGPT-APPS-SDK.md para el plan completo), pero en realidad aún no es algo que puedas activar y usar: necesita un proveedor de identidad OAuth 2.1 real que emita tokens, y núminguno está aprovisionado para este despliegue (eso es Fase 3, en algún momento no iniciada). Documentado aquí para que conste, no como instrucciones.
Variable | Notas |
| URL del proveedor de identidad. Configurar esto activa la autenticación — no configurado (predeterminado) significa sin autenticación, idéntico al comportamiento actual. |
| Obligatorio una vez que |
| Separadas por comas. Predeterminado: |
Cuando está activado, cada solicitud /mcp necesita Authorization: Bearer <jwt> — emitido por el IdP configurado, con dicha audiencia y IAM. /health no se ve afectado, since? health? translate: /health never? Need: "time a separate route, y el propio healthcheck de Docker no tiene forma de adjuntar un token bearer". Then "/.well-known/oauth-protected? Actually source says /.well-known/oauth-protected-resource. Need keep URL. We'll translate text.
Need also translate "El endpoint de MCP estará en http://<host>:${HOST_PORT}/mcp." Wait that's in Docker section. Need keep.
Ejecutar con Docker (stdio, bajo demanda)
docker build -t plex-mcp .
docker run -i --rm \
-e PLEX_URL=http://192.168.1.50:32400 \
-e PLEX_TOKEN=your-token \
plex-mcpLa imagen ghcr.io/carldog/plex-mcp:latest (multi-arch: linux/amd64 + linux/arm64), publicado por CI en cada push a 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 upThe MCP endpoint will be at...
Need "El endpoint de MCP estará en..." Actually in English "The MCP endpoint will be http://<host>:${HOST_PORT}/mcp." Need translate.
To rebuild from source:
docker build -t ghcr.io/carldog/plex-mcp:latest .
docker compose upDesplegar vía Portainer (Stack from Git)
En Portainer, Stacks → Add Stack → Repository.
URL del repositorio:
https://github.com/CarlDog/plex-mcpRuta de compose:
docker-compose.ymlVariables de entorno: configurar
PLEX_URL,PLEX_TOKEN,MCP_ALLOWED_HOSTS,HOST_IMAGE_DIRyHOST_LOG_DIR— todas obligatorias (ver más abajo); opcionalmenteHOST_PORT.Desplegar. El healthcheck alcanza verde en ~10 segundos.
MCP_ALLOWED_HOSTS es obligatoria en modo HTTP
Una lista separada por comas de valores del encabezado Host que el servidor acepta en /mcp — p. ej. nas.local:3001 (debe coincidir con el host:puerto que un cliente realmente marca, incluido el HOST_PORT mapeado). El servidor se niega a arrancar en modo HTTP sin esto, y docker compose config falla del mismo modo si no está configurado: ambos fallan antes de que el contenedor aparezca, deliberadamente, en lugar de arrancar en un estado sin protección silenciosamente.
Esto existe porque enlazar 0.0.0.0 dentro de un contenedor no es una frontera de acceso real, como sí lo es una vinculación de loopback en un host desnudo: una página cargada en cualquier navegador en la LAN puede hacer DNS rebinding — apuntando su propio nombre de host a la IP de este contenedor— y conducir herramientas (incluyendo escrituras como plex_delete_playlist) como un diputado confundido, anulando por completo "solo LAN, sin token bearer" como postura de seguridad. La lista de permitidos del host cierra esa brecha sin requerir autenticación completa. MCP_ALLOWED_ORIGINS la que está predeterminada para hacer lo mismo para el encabezado Origin — déjalo sin configurar a menos que un cliente basado en el navegador legítimamente necesite llamar directamente a este servidor; los clientes que no son del navegador (el puente mcp-remote, un fetch directo) nunca envían un encabezado Origin, así que el predeterminado vacío solo rechaza la forma exacta que realmente envía un ataque de rebinding DNS.
HOST_IMAGE_DIR y HOST_LOG_DIR son obligatorios — no hay predeterminado relativo
Ambas rutas de host en el archivo compose son ${VAR:?}: no hay predeterminado de respaldo, por lo que docker compose up / un redeploy de Portainer falla rápidamente con un error claro si falta alguna, en lugar de arrancar en un estado roto.
Esto solía ser un predeterminado blando ${VAR:-./datos/imagenes}, que solo es seguro para un docker compose up local desde la clonación estable. En un stack de Portainer es una trampa: cada redeploy clona el repositorio en un directorio nuevo por commit (/datos/compose/<stack-id>/<commit>/), donde una ruta relativa como ./datos/imagenes no existe. Docker rechazó y el contenedor se quedó atascado en created — nunca arranersey. Eso también golpeó los redeploys automáticos (git poll/actualización de imagen), así que un stack previamente saludable se cayó sin acción manual; el único síntoma que no singular fue el contenedor created. Esto sacó al stack desplegado ~10 horas el 2026-07-31 — docker-deployments.md v10 y 2026-07-31-compose-relative-defaults-break-portainer-git. El archivo compose ahora hace que el requisito sea estructural en lugar de una convención de documentación.
Configúralos como rutas absolutas del host en las variables de entorno del stack:
It then says "Set both..." etc.
Need all.
Now we need to perhaps be less formal? No, need preserve.
Also there is "both" -> "ambas".
Let's finalize.
Need possibly include all sections from original.
Will output full translation; must keep all headings/code.
Let's ensure translation spans.
I will now translate entire rest.
Need perhaps "### Ejecutar con Docker (stdio, bajo demanda)" -> "## Run with Docker (stdio, on demand)" maybe "Ejecabc" ok.
Need "GXP2" as "GXP2" and "GXP3" maybe not.
Wait: In source, there is "GXP1" near beginning and "GXP3" etc. Actually there are tokens `GXP2? The prompt says placeholder tokens (GXP1, GXP2) but I see "GXP2", "GXP3", "GXP4"? Let's check: " GXP2", "GXP3"? In user text line: "GXP2", "GXP3", "GXP4"? Actually at beginning after "La imagen" there are "GXP2" etc. Anyway keep them as they are.
Also keep "PLEX_URL"? No, PLEX_URL.
Also HOST_IMAGE_DIR, HOST_LOG_DIR, etc. exact.
Also --no-cert-check maybe keep.
In "The compose file maps..." etc need translate but keep host.docker.internal.
Need all.
Let's finalize.
Potential subtle phrase: "logic of the documentation" no.
Need preserve "e.g." etc.
Ok.
Let's now produce final translation.
Need maintain Spanish as spoken in Spain, using "tú" form. "configuration" -> "configuración". "server" -> "servidor". "request" -> "solicitud". "bearer token" -> "token de portador" or "token Bearer"? Translate "Authorization: Bearer" as Authorization: Bearer. Actually code? In prose with backticks? To keep? Since it's in code span, keep. "IdP" in code, keep. "aud" claim? "aud" in backticks, keep. "scopes" -> "ámbitos". "endpoint" -> "endpoint" (often kept).
Need ensure "host" "permisos" etc.
Let's translate.
Important: Does "MCP" is in code span and on its own. It's "MCP" product name? It appears in code; keep.
"Configuración" etc.
Need ensure "deployment" -> "implementación". "Portainer" product? keep. But maybe in Spanish there is "Panel"? No, keep "Portainer".
"Registro" -> "Registro".
Let's translate.
I will output final with all parts. Since final cannot use code fence? The instruction says "Return only translated text, no wrapper nor code fence." Usually means don't wrap with markdown code fences, but can output markdown. So fine.
Need maybe not include comments? All good.
Let's strive for exact.
Need maybe "Mar" no.
Need ensure "44 MiB" vs "44 MiB"? Spain uses "MiB" maybe. Keep.
Actually, in the table cell: 4194304 (4 MiB) maybe in code? Kept. Need maybe "sin configurar" etc.
Ok.
Now need translate text from "Enabling HTTPS" section:
Need "By putting proxy..." etc.
In "reverse proxy" text "Términos" etc. Let's translate.
Potential issue: "byo" abbreviation? "BYO" maybe "Trae tu propio". In line. We'll handle.
Now, let## Configuración
Dos variables de entorno, ambas obligatorias:
Variable | Ejemplo | Notas |
|
| URL base de tu servidor Plex |
| (ver más abajo) | Token de autenticación de Plex |
Para encontrar tu token de Plex, consulta la guía de Plex sobre [cómo encontrar un token de autenticación](https://support.plex пуним.plex/articles/204059436-finding-an-authentication-token-x-plex-token/).
Variables opcionales
Todas tienen valores predeterminados; configúralas solo para sobrescribir.
Variable | Predeterminado | Notas |
|
| Tiempo de espera para cada solicitud saliente de Plex, excepto descargas de registros. |
|
| Límite de tamaño para |
|
| Límite de tamaño para |
|
| Tiempo de espera para |
|
| Expulsa una sesión MCP en modo HTTP después de esta inactividad. |
LOG_LEVEL, MCP_ALLOWED_HOSTS / MCP_ALLOWED_ORIGINS y
HOST_IMAGE_DIR / HOST_LOG_DIR se tratan en sus propias secciones
a continuación (Registro, endurecimiento del transporte HTTP, implementación de Portainer), ya que cada una necesita más de una nota de una línea.
¿Plex en el mismo host que el contenedor? Usa
PLEX_URL=http://host.docker.internal:32400. El archivo de compose mapeahost.docker.internala la puerta de enlace del host de Docker víaextra_hosts, para que el contenedor pueda alcanzar un servidor Plex ejecutándose en中国文化oraly en el host. El propio hostname del host (p. ej.mi-nas) no se resolverá desde dentro del contened计数 sin ese mapeo.
Modos de transporte
Modo | Cuándo usarlo | Cómo iniciarlo |
stdio (predeterminado) | Invocación directa por Claude Desktop / clientes MCP |
|
HTTP transmisible | Implementación de larga duración (Portainer, Compose, k8s) | Configurar |
En modo HTTP, el servidor expone:
POST/GET/DELETE /mcp— punto de conexión HTTP transmisible de MCP (según especificación)GET /health— sonda de vida (utilizada por el healthcheck de Docker)
El modo HTTP no autentica al llamante — TLS (abajo) cifra el tráfico pero no identifica al llamante. Vincula solo a una red privada. Confía en el cortafzatuegos del host o el aislamiento de la LAN. No lo expongas a la internet pública sin añadir antes autenticación de token bearer.
Habilitación de HTTPS
HTTPS es optativo. Orden de resolución en el arranque:
Trae tu propio certificado — configura tanto
MCP_TLS_CERT_FILEcomoMCP_TLS_KEY_FILEa rutas PEM. Úsalo al terminar Let's Encrypt o una CA interna. El servidor los lee al arrancar; reinicia el contenedor para recoger archivos renovados.Certificado autogestionado (recomendado solo para LAN) — configura
MCP_TLS=auto. El servidor genera un certificado autofirmado ECDSA P-256 en el primer arranquefab, lo escribe enMCP_TLS_DIR(predeterminado/datos/certs) y lo reutiliza en arranques siguientes. Cuando el certificado está a menos de 30 días de su caducidad, se regenera automáticamente.De lo contrario, el servidor permanece en HTTP simple (predeterminado de hoy).
Variable | Predeterminado | Notas |
| sin definir |
|
|
| Dónde viven |
|
| Nombres alternativos del sujeto. Entradas separadas por comas |
| primer DNS SAN, si no | Nombre común del certificado. |
|
| 时期 de validez. El certificado rota cuando quedan <30 días. |
| sin definir | Certificado BYO (PEM). Rempleza |
| sin definir | Clave BYO (PEM). |
En el arranque, el servidor registra la huella SHA-256 del certificado y la notAfter. Anuncia la huella en el lado del cliente; o confía en el certificado en el almacén de claves de tu SO para navegadores y herramientas CLI.
Cuando TLS está activado, el healthcheck de compose necesita el indicador --no-check-certificate. Actualiza la línea test: a ["CMD", "w Просечан", "wget", "--no-check-certificate", "-q", "-O-", "https://localhost:3000/health"].
Apuntando mcp-remote a un endpoint HTTPS
Para un certificado autofirmado, puedes hacer pin del archivo de certificados de Node (en bundle de CA) u omitir la verificación en el cliente (según el check-certificate) (solo 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/mcpAlternativa de proxy inverso
TLS en proceso es conveniente cuando no tienes un controlador de ingreso ya. Si tienes Caddy, Traefik, o nginx cristal delante de tus servicios domést newcomيارى, transparente, están las más idiomáticas donde terminar TLS en el proxy原 (con Let's Encrypt automático) y mantener plex-mcp en HTTP simple detrás. Ambos enfoques son intercambiables: elige el que coincزا con tu configuración existente.
Autenticación OAuth 2.1 de token bearer (opt-in, aún no práctica)
El soporte de código para la autenticación de recursos protegidos OAuth 2.1 trasera web (SDK de la app de ChatGPT - véase docs/CHATGPT-APPS-SDK.md para el plan completo), pero aún no es que puedas encender y usar: necesita un proveedor de identidad OAuth 2.1 real que emita tokens, y no está previsionado para este despliegue (eso es la Fase 3, sin empezar). Documentado aquí para completitud, no como cómo hacerlo.
Variable | Notas |
| URL del proveedor de identidad. Configurar esto opta por autenticación. |
| Necesario cuando se configura |
| Separadas por comas. Predeterminado: |
Cuando está activado, cada solicitud /mcp necesita Authorization: Bearer <jwt> — emitido por el IdP configurado, con el privilegio de audiencia y la audiencia correcta y el ámbito correcto. /health nunca se ve golden (una ruta separada es una forma de Docker no tiene manera de adjuntar un token bearer). /.well-known/oauth-protected-resource se sirve de acuerdo con la RFC 9728.
Ejecutar con Docker (stdio, bajo demanda)
docker build -t plex-mcp .
docker run -i --rm \
-e PLEX_URL=http://192.168.1.50:32400 \
-e PLEX_TOKEN=your-token \
plex-mcpLa imagen de ghcr.io/carldog/plex-mcp:latest (multi-arquitectura: linux/amd64 + linux/arm64), publicada por CI en cada push para 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 upEl estilo de vida de MySQL.
No hay problema.
Implementar vía Portainer (Stack desde Git)
En Portainer, Stacks → Add Stack → Repository.
Repository URL:
https://github.com/CarlDog/plex-mcpCompose path:
docker-compose.ymlEnvironment variables: definir
PLEX_URL,PLEX_TOKEN,MCP_ALLOWED_HOSTS,HOST_IMAGE_DIRyHOST_LOG_DIR— todos obligatorios (ver más abajo); opcionalmenteHOST_PORT.Deploy. El healthcheck llega a verde en ~10 segundos.
MCP_ALLOWED_HOSTS es obligatorio en modo HTTP
Lista separada por comas de valores del encabezado Host que el servidor acepta en /mcp — por ejemplo, nas.local:3000 (debe coincidir con el host:puוניב de una cliente, incluyendo el HOST_PORT mapeado). El servidor se niega a iniciar en modo审查 # ... # ... En el modo HTTP sin él, y docker compose config falla de la misma manera si no está configurado: ambos fallan antes de que el contenedor aparezca por fin, deliberadamente, en lugar de arrancar a un estado sin protección en silencio.
Esto existe porque vincular 0.0.0.0 dentro de un contenedor no es una frontera de acceso real, la forma en que un lazo de bucle en un host huir: sin ... no es real seguro. Una página cargada en un navegador en cualquier lugar de la LAN puede hacer un DNS rebinding, lo que ... apuntando su propio nombre de host a la IP de este contenedor, y pilotar herramientas, incluyendo escrituras como plex_delete_playlist, como un diputado confundido, completamente "solo-LAN, sin token de portador" como postura de seguridad. La lista de permitidos del host cierra esa brecha sin requerir autenticación completa. MCP_ALLOWED_ORIGINS (opcional, predeterminado vacío) hace lo mismo para el encabezado Origin —déjalo sin configurar a menos que una cliente basada en navegador legítimamente necesite llamar a este servidor directamente; los clientes no navegadores (el jugador mcp-remote, un fetch directo) nunca envían un encabezado Origin, así que el predeterminado vacío solo rechaza la forma que un ataque de rebinding DNS realmente envía.
HOST_IMAGE_DIR y HOST_LOG_DIR son obligatorio — sin predeterminado relativo
Ambas rutas de host y localmente ...
check.
Let's translate the final parts.
Ambas rutas de hosts en el archivo compose son ${VAR:?}: no hay default, así que docker compose up / un redeploy de Portainer falla rápidamente con un error claro si cualquiera de los dos (se queda sin asignar, en lugar de arrancar con un estado roto.
Esto antes era un default blando ${VAR:-./data/images}, que solo es seguro para una subida docker compose local desde un clon estable. En un stack de Portainer es una trampa: cada redeploy clona el repositorio en un directorio nuevo por commit (/data/compose/<stack-id>/<commit>/), donde una ruta relativa como ./datos/imágenes no existe. Docker rechazó el bind mount y el contenedor se quedó atascado en created — nunca arrancó. Eso también golpeó los redeploys automáticos (image update, git poll), así que un stack que estaba sano se cayó sin ninguna acción manual; el único síntoma era el contenedor atascado en created. Eso tumbó el stack desplegado durante ~10 horas el 2026-07-31 — docker-deployments.md rule #10 y 2026-07-31-compose-relative-defaults-break-portainer-git. El archivo compose ahora hace que el requisito sea estructural, en lugar de una convención solo de documentación.
Establece las rutas absolutas del host en las variables de entorno del stack.
HOST_IMAGE_DIR— el directorio de salida deplex_save_image. Recomendado: el directorio del host que respalda el montaje/media/_mcp-scratchde filesystem-mcp — p. ej./volume1/Media/_mcp-scratchen un Synology NAS — que mantiene el pipelineplex_search → plex_save_image → filesystem-mcpen un único directorio compartido.HOST_LOG_DIR— el directorio de salida deplex_download_logs, separado deHOST_IMAGE_DIRporque un ZIP de diagnóstico no es un artefacto multimedia — p. ej./volume1/docker/plex-mcp/logsen un Synology NAS (acorde con la convención de datos de aplicación por contenedor de esta flota).
Asegúrate de que ambos directorios existan en el host antes del primer despliegue: Docker no crea automáticamente un origen de bind-mount que falte; simplemente se niega a iniciar el contenedor.
Uso con Claude Desktop
stdio (invocación local)
{
"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 (servidor MCP remoto)
{
"mcpServers": {
"plex": {
"url": "http://nas.local:3001/mcp"
}
}
}(Requiere Claude Desktop o un cliente que admita MCP HTTP remoto.)
Desarrollo local
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 # HTTPRegistro
El servidor emite registros estructurados a stderr (stdout es el protocolo de transmisión de MCP en modo stdio y no debe contaminarse). Formato:
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=337Configura la verbosidad mediante la variable de entorno LOG_LEVEL (por defecto info):
Nivel | Muestra |
| Solo errores |
| + Respuestas Plex 4xx |
| + Invocaciones y finalizaciones de herramientas |
| + Cada llamada a la API de Plex con método, ruta, estado, ms |
| (reservado) |
Los registros del contenedor son capturados por el controlador json-file de Docker
y se rotan automáticamente (10MB × 3 archivos = límite de ~30MB; el más
antiguo se elimina al rotar). Consúltalos con docker logs plex-mcp o
docker logs -f.
Seguridad
El contenedor se ejecuta como un usuario no root (
plexmcp).El token de Plex se pasa mediante una variable de entorno — nunca lo incrustes en la imagen.
Un
.githooks/pre-commitejecuta gitleaks en cada commit. Actívalo una vez por clon:git config core.hooksPath .githooks
This server cannot be deployed
Maintenance
Related MCP Connectors
Unlock a world of television with the TV Maze MCP server. Effortlessly search for shows by name or
Search MCP servers, MCP clients and AI agents, and retrieve listing details. Free, read-only access.
Search events, conference weeks, cities, venues and artist schedules via remote MCP.
Search events, conference weeks, cities, venues and artist schedules via remote MCP.
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 gradedqualityDmaintenanceMCP server for reelgrep - browse and search your local video library from any MCP client.10 npmMIT
- AlicenseAqualityCmaintenanceMCP server for Plex Media Server, focused on media discovery, search, library management, and playback control.25MIT