PlexBLOCK
MCP Server for Plex to allow LLMs to converse with Plex.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
A powerful Model-Context-Protocol (MCP) server for interacting with Plex Media Server. It provides a standardized JSON-based interface for automation, AI agents (like Claude), and custom integrations.
Features
- Standardized API: Unified JSON responses for all Plex operations.
- Multiple Transports: Supports both
stdioandSSE(Server-Sent Events). - Comprehensive Control: Manage libraries, media, collections, playlists, clients, and users.
- Remote Ready: Built-in OAuth 2.1 support for integration with remote AI platforms like Claude.ai.
- Admin Tools: Access logs, monitor bandwidth, and run Butler tasks.
Installation
Option 1: Using uv (Recommended)
Run directly without installation:
uvx plex-mcp-server --transport stdio --plex-url http://your-server:32400 --plex-token your-token
Option 2: Install via pip
pip install plex-mcp-server
Option 3: Development / Source
git clone https://github.com/vladimir-tutin/plex-mcp-server.git cd plex-mcp-server pip install -e .
Configuration
Set your Plex server URL and Token using one of these methods:
1. Command Line Arguments
plex-mcp-server --plex-url "http://192.168.1.10:32400" --plex-token "ABC123XYZ"
2. Environment Variables (.env)
Create a .env file in the current directory or ~/.config/plex-mcp-server/.env:
PLEX_URL=http://localhost:32400 PLEX_TOKEN=your-authentication-token MCP_OAUTH_ENABLED=false
or with OAuth Enabled
PLEX_URL=http://localhost:32400 PLEX_TOKEN=your-authentication-token MCP_OAUTH_ENABLED=true MCP_OAUTH_ISSUER=https://auth.example.com/application/o/plexmcp-oauth/ MCP_SERVER_URL=https://plexmcp.example.com
3. MCP Client Config
Example for Claude Desktop (%APPDATA%/Claude/claude_desktop_config.json):
{
"mcpServers": {
"plex": {
"command": "uvx",
"args": [
"plex-mcp-server",
"--transport",
"stdiob6cf27ea262eOBSERVED · 2026-10-07Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add plex-mcp-server --env MCP_OAUTH_ENABLED=${MCP_OAUTH_ENABLED} --env MCP_OAUTH_ISSUER=${MCP_OAUTH_ISSUER} --env MCP_OAUTH_JWKS_CACHE_TTL=${MCP_OAUTH_JWKS_CACHE_TTL} --env PLEX_TOKEN=${PLEX_TOKEN} -- uvx plex-mcp-server{
"mcpServers": {
"plex-mcp-server": {
"command": "uvx",
"args": [
"plex-mcp-server"
],
"env": {
"MCP_OAUTH_ENABLED": "${MCP_OAUTH_ENABLED}",
"MCP_OAUTH_ISSUER": "${MCP_OAUTH_ISSUER}",
"MCP_OAUTH_JWKS_CACHE_TTL": "${MCP_OAUTH_JWKS_CACHE_TTL}",
"PLEX_TOKEN": "${PLEX_TOKEN}"
}
}
}
}Exposed tools (55)
38 read · 12 write · 5 destructive. Blast radius: 5 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
client_control_playback | read | Control playback on a specified client. |
client_get_details | read | Get detailed information about a specific Plex client. |
client_get_timelines | read | Get the current timeline information for a specific Plex client. |
client_list | read | List all available Plex clients including idle players. |
client_navigate | read | Navigate a Plex client interface. |
client_set_streams | write | Set audio, subtitle, or video streams for current playback on a client. |
client_start_playback | write | Start playback of media on a specified client. |
collection_add_to | write | Add items to an existing collection. |
collection_create | write | Create a new collection with specified items. |
collection_delete | destructive | Delete a collection. |
collection_edit | write | Comprehensively edit a collection |
collection_list | read | List all collections on the Plex server or in a specific library. |
collection_remove_from | destructive | Remove items from a collection. |
library_get_contents | read | Get the filtered and paginated contents of a specific library. |
library_get_details | read | Get detailed information about a specific library, including folder paths and settings. |
library_get_recently_added | read | Get recently added media across all libraries or in a specific library. |
library_get_stats | read | Get statistics for a specific library. |
library_list | read | List all available libraries on the Plex server. |
library_refresh | read | Refresh a specific library or all libraries. |
library_scan | read | Scan a specific library or part of a library. |
media_delete | destructive | Delete a media item from the Plex library. |
media_edit_metadata | write | Edit metadata for a specific media item. |
media_get_artwork | read | Get images for a specific media item. |
media_get_details | read | Get detailed information about a specific media item using PlexAPI |
media_list_available_artwork | read | List all available artwork for a specific media item. |
media_search | read | Search for media across all libraries. |
media_set_artwork | write | Set artwork for a specific media item. |
playlist_add_to | write | Add items to a playlist. |
playlist_copy_to_user | read | Copy a playlist to another user account. |
playlist_create | write | Create a new playlist with specified items. |
playlist_delete | destructive | Delete a playlist. |
playlist_edit | write | Edit a playlist |
playlist_get_contents | read | Get the contents of a playlist. |
playlist_list | read | List all playlists on the Plex server. |
playlist_remove_from | destructive | Remove items from a playlist. |
playlist_upload_poster | write | Upload a poster image for a playlist. |
server_clean_bundles | read | Clean unused media bundles. |
server_empty_trash | read | Empty trash for a specific library or all libraries. |
server_get_alerts | read | Get real-time alerts from the Plex server by listening on a websocket. |
server_get_bandwidth | read | Get bandwidth statistics from the Plex server. |
server_get_butler_tasks | read | Get information about Plex Butler tasks. |
server_get_current_resources | read | Get resource usage information from the Plex server. |
server_get_info | read | Get detailed information about the Plex server. |
server_get_plex_logs | read | Get Plex server logs. |
server_optimize_database | read | Optimize the Plex database. |
server_run_butler_task | write | Manually run a specific Plex Butler task now. |
sessions_get_active | read | Get information about current playback sessions, including IP addresses. |
sessions_get_media_playback_history | read | Get playback history for a specific media item. |
user_get_continue_watching | read | Get items the user has partially watched and can continue. |
user_get_info | read | Get detailed information about a specific Plex user. |
user_get_on_deck | read | Get on deck (in progress) media for a specific user. |
user_get_statistics | read | Get statistics about user watch activity over different time periods. |
user_get_watch_history | read | Get recent watch history for a specific user. |
user_list_all_users | read | List all users (owner, home users, and shared users) with their IDs and types. |
user_search_users | read | Search for users with names, usernames, or emails containing the search term, or list all users if no search term is provided. |
Trust audit
BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (2 observation(s))
- Network
- declared (7 observation(s))
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (6)
verify = False if base_url.startswith('https') else Trueverify = False if base_url.startswith('https') else Trueprint(f"[OAuth] Token present: {bool(token)}")collection_delete, collection_remove_from, media_delete, playlist_delete, playlist_remove_from
plex-mcp-server --plex-url "http://192.168.1.10:32400" --plex-token "ABC123XYZ"
Gates applied: no_behavioural_pass, no_license.
b6cf27ea262efull audit observations/trust-audit/mcp-server/vladimir-tutin__plex.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-07 | b6cf27ea262e | BLOCK | D | 69 | first audit |
Questions
What is the Plex MCP server?
MCP Server for Plex to allow LLMs to converse with Plex.
What tools does Plex expose?
55 in total: 38 read-only, 12 that write, and 5 that can delete or overwrite (collection_delete, collection_remove_from, media_delete, playlist_delete, playlist_remove_from). Every one is listed on this page with its risk.
Is Plex safe to connect to an agent?
No — not without reading the findings first. The audit graded it D (69/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 5 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does Plex need?
It reads MCP_OAUTH_ENABLED, MCP_OAUTH_ISSUER, MCP_OAUTH_JWKS_CACHE_TTL and PLEX_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does Plex run?
It speaks stdio, so it runs as a local process your client starts. It is published on PyPI as plex-mcp-server.
How current is this page?
The grade is for one exact copy of the source (b6cf27ea262e), read on 2026-10-07. The repository is watched and re-audited when it changes.