plex-mcp-server
Provides comprehensive integration with Plex Media Server, exposing one MCP tool per documented Plex API operation plus curated tools for library browsing and statistics, cross-library media search, media metadata editing and artwork, playlists and collections, live sessions and watch history, server info/bandwidth/Butler tasks/preferences, client inventory and playback control, shared/home user management, per-user analytics, watch-history-based recommendations, the account watchlist and Discover search with local-library cross-checks, subtitle lookup and spoiler-free dialogue extraction up to a playback position, and direct-play/transcode stream URLs. Supports multi-server cross-server search, read-only mode, and OAuth 2.1 or bearer-token protection for HTTP transport.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@plex-mcp-serversearch my Plex library for Blade Runner and show its details"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
plex-mcp-server
A Model Context Protocol server for Plex Media Server.
Two layers in one server:
Every documented Plex Media Server API operation as an MCP tool. The server ships an OpenAPI 3.1 document of the Plex API, generates one tool per operation from it, and re-generates the document from Plex's published documentation on demand. Nothing is hand-waved: if Plex documents it, there is a tool for it.
Curated tools that do what a caller would otherwise have to reconstruct — resolve a title to a rating key, read Plex's filter vocabulary, compute per-user statistics, recommend something to watch, control a client, write a spoiler-free recap of a film in progress.
plex_library_list plex_sessions_list plex_media_search
plex_media_edit plex_playlist_create plex_collection_create
plex_analytics_overview plex_recommendations plex_clients_control
plex_subtitles_dialogue plex_watchlist_add plex_stream_url
plex_api_request plex_endpoint_search plex_library_section_get_all
…and one tool per documented operationWhy this exists
There are several Plex MCP servers (see Credits). Each one is good at something different, and each one stops short of the full API. This project merges the useful parts, adds complete endpoint coverage generated from Plex's own OpenAPI document, and ships the specification so other tools can consume it.
Related MCP server: Plex Assistant MCP
Quick start
You need a Plex server address and a token.
git clone https://github.com/aminamos/plex-mcp-server.git
cd plex-mcp-server
npm install
npm run buildGet a Plex token
Sign in to Plex in a browser.
Open any library item, then Get Info → View XML.
Copy the
X-Plex-Tokenquery parameter from the URL that opens.
Or, if you only have an account token, leave PLEX_URL unset: the server discovers your owned servers through plex.tv/api/v2/resources and picks the best connection.
Wire it into an MCP client
{
"mcpServers": {
"plex": {
"command": "node",
"args": ["/absolute/path/to/plex-mcp-server/dist/index.js"],
"env": {
"PLEX_URL": "http://192.168.1.10:32400",
"PLEX_TOKEN": "your-token"
}
}
}
}A .env file in the working directory (or ~/.config/plex-mcp-server/.env) is also read, so you can keep credentials out of client configs:
PLEX_URL=http://192.168.1.10:32400
PLEX_TOKEN=xxxxxxxxxxxxHTTP transport
node dist/index.js --transport http --host 127.0.0.1 --port 3000 --path /mcpStreamable HTTP, with optional access control:
Mode | Variables |
None (default, and the default bind is | — |
Static bearer token |
|
OAuth 2.1 with an external authorization server (RS256, verified against the issuer's JWKS) |
|
With OAuth configured, the server publishes /.well-known/oauth-protected-resource and proxied /.well-known/oauth-authorization-server metadata, and answers unauthenticated requests with a WWW-Authenticate challenge — the flow remote MCP clients expect.
Configuration
Flags override environment variables, which override .env.
Flag | Environment | Default | Meaning |
|
| discovered from plex.tv | Plex Media Server base URL |
|
| — |
|
|
| falls back to | plex.tv account token (account, watchlist, Discover) |
|
| generated once, then cached | Stable |
|
|
|
|
|
|
| HTTP bind |
|
|
|
|
|
| — | Restrict tools to these OpenAPI tags, e.g. |
|
| — | Filter tools by name substring |
|
| off | Do not register or allow anything that is not |
|
|
|
|
— |
|
| Cap on items returned from one list endpoint |
— |
|
| Cap on generated tool descriptions |
— |
|
| HTTP timeout |
— |
|
| In-memory GET cache; |
— |
| — | Enables the subtitle tools |
— |
|
|
|
— |
| — | Extra servers for cross-server search |
A note on tool count
Full coverage means a lot of tools: --tools all advertises one tool per documented operation, and a tools/list response of that size costs real context (order of tens of thousands of tokens, depending on the document version). Options:
--tools curated— a few dozen hand-written tools, smallest footprint.--tags Library,Status— keep the generated coverage but only for the areas you care about.Keep
alland let the client search: every generated tool is named after its operation, andplex_endpoint_searchfinds operations by keyword without loading the whole list.
--read-only is enforced at registration and again at call time: mutating tools — generated and curated — are not registered at all, and the escape hatch (plex_api_request) refuses non-GET methods. A read-only server therefore never advertises a tool that cannot run.
What is in the box
Generated tools. One per operation of the bundled OpenAPI document, named plex_ + the snake_cased operationId, e.g. GET /library/sections/{sectionId}/all → plex_library_section_get_all. Parameters (path and query — Plex documents nearly everything as query parameters) become the tool's JSON schema, and the tool performs exactly that request. See docs/ENDPOINTS.md for the full list.
Where a curated tool and a generated tool would share a name, the curated one wins and the generated one is not registered — that is deliberate for the three cases where the curated version does strictly more work (resolving a title to a Discover GUID for the watchlist, cross-checking Discover results against the local library). Use plex_api_request to reach the raw endpoint form of those operations.
Curated tools. See docs/TOOLS.md for the generated catalogue. The areas they cover:
Area | Examples |
Library | list sections, per-section statistics, recently added, scan / refresh / analyze / empty trash, filter and sort vocabulary |
Media | cross-library search, full detail, children (seasons, episodes), metadata edit with lock semantics, artwork, watch state, ratings |
Playlists & collections | create from rating keys, add/remove items, edit, copy to a user |
Sessions | live streams, watch history, terminate a stream, transcodes |
Server | info, bandwidth, host and process resources, Butler tasks, preferences, clean bundles, database optimisation |
Clients | inventory and timelines, playback control (play / pause / stop / seek / step / skip), stream selection |
Users | shared and home users, per-user on-deck, watch history, activity statistics |
Analytics | play/user/popular/library reporting over any window, computed in-process |
Recommendations | scored suggestions from a user's actual watch history, with reasons |
Watchlist & Discover | the account watchlist, and Discover search with "already in my library" cross-checks |
Subtitles | find subtitles, and extract dialogue up to a playback position |
Streaming | direct-play URLs, transcode decisions, subtitle streams |
Discovery tools.
plex_endpoint_search— find an operation by keyword; returns the tool name, method, path and required arguments.plex_api_request— arbitrary request to the server, for endpoints, parameters or iterators that are not in the document.plex_api_info— what the bundled document contains and how tools are named.
Resources. plex://openapi/index (the whole endpoint catalogue in one read), plex://openapi/tag/<tag>, plex://openapi/document (the raw OpenAPI document), plex://registry (every tool with tag, access class and schema), and plex://server/info (the live server).
Prompts. library_report, server_health, and what_have_i_missed — the last one reads the active session, pulls the subtitles for what is playing, and asks for a recap that stops at the current playback position, so it cannot spoil the rest of the film.
The OpenAPI document
spec/plex-pms.openapi.json (and .yaml) is generated, not hand-maintained:
npm run spec:build # fetch developer.plex.tv/pms, extract, normalise, merge extensions
npm run spec:validate # structural + policy checksPlex publishes the Plex Media Server API as documentation rendered by ReDoc from an OpenAPI 3.1 document embedded in the page. scripts/build-spec.mjs extracts that document, normalises it (title, summary, server variables, provenance), and merges spec/extensions.yaml.
spec/extensions.yaml is hand-authored and holds endpoints in wide use that Plex's published document omits — /library/sections, /library/recentlyAdded, /library/metadata/{ids}/children, /statistics/bandwidth, /clients, /diagnostics/*, the Plex Cloud account endpoints and the Discover watchlist. Each one is marked x-plex-extension: true, and each carries the MCP-specific annotations this project defines:
Extension | Meaning |
| Explicit MCP tool name for the operation |
|
|
| Override the tag used for |
| Do not generate a tool for this operation |
| Extra guidance appended to the generated tool description |
Provenance — source URL, extraction timestamp, upstream version, operation counts — is recorded in spec/plex-pms.openapi.json under x-plex-provenance.
Licensing of the document
The upstream document is published by Plex under Apache 2.0; that licence and attribution are preserved in info.license and x-plex-provenance. spec/extensions.yaml and everything under src/ are this project's own work, under MIT.
Development
npm run build # tsc → dist/
npm test # vitest
npm run smoke # end-to-end: real server process, mock Plex, real MCP round trip
npm run spec:build # regenerate the OpenAPI document
npm run docs # regenerate docs/TOOLS.md and docs/ENDPOINTS.md from the running server
npm run check # build + validate the spec + testsThe smoke test is the honest one: it boots dist/index.js as a subprocess, points it at a mock Plex server, and drives initialize / tools/list / tools/call / resources/read / prompts/get over stdio, asserting both the MCP surface and the HTTP requests the server makes.
Limitations
Subtitle tools need an OpenSubtitles API key; without it they fail with a clear message and the rest of the server is unaffected.
plex_clients_*tools talk to the client devices directly, so they need the client's host and port to be reachable from wherever this server runs.Plex's documented response format is XML by default; this server always asks for JSON, and reports the raw body as text when an endpoint answers with something that is not JSON (transcode playlists, image endpoints).
Generated tools return Plex's payloads trimmed to
PLEX_MAX_ITEMSwith an explicit truncation marker. Curated tools return shaped results.The bundled document is a snapshot. Re-run
npm run spec:buildto pick up Plex's changes.
Credits
This server merges the useful parts of four existing projects. No code was copied — the implementations here are new — but the scope, the tool taxonomy and several features come directly from them:
vladimir-tutin/plex-mcp-server — the broad tool taxonomy (library, media, playlist, collection, user, sessions, server, client), the remote-access story with OAuth against an external issuer, and administrative tooling (logs, bandwidth, Butler, empty trash, optimise database, clean bundles).
niavasha/plex-mcp-server — the architecture: one unified binary, tools separated from their schemas and implementation, tool annotations, write-operation gating, a compact/TOON-style tabular encoding that is only used when it is actually shorter, and viewing analytics built from Plex's own endpoints.
eddmann/plex-mcp — the idea worth stealing: ground answers in subtitles up to the current playback position, so a recap of a film in progress cannot spoil it. That is
plex_subtitles_dialogueand thewhat_have_i_missedprompt.BenjaminOddou/alfred-plex — search and filter ergonomics (reading Plex's filter/sort vocabulary and exposing it to a caller), Discover search, server actions (settings, statistics, history), the watchlist toggle, deep links into Plex Web, and streaming URLs handed to a player.
Endpoint coverage comes from Plex's own documentation at https://developer.plex.tv/pms/.
License
MIT — see LICENSE. The generated OpenAPI document retains Plex's Apache 2.0 attribution; the details are in NOTICE and inside the document's info.license and x-plex-provenance fields.
This server cannot be deployed
Maintenance
Related MCP Connectors
The media memory layer for AI agents and their humans. Your AI client gets 29 tools to search your collection, add items, update ratings, preview music, and find patterns across everything you've read, watched, and listened to.
Discover, inspect and run 63,000+ agent tools from one balance. Pay per call, no subscriptions.
YouTube transcripts, search, channels, playlists and bulk transcript jobs for AI agents. 14 tools.
Control Android TV from any AI. 38 MCP tools: playback, recap, recommend, smart-home, schedules.
Related MCP Servers
- AlicenseBqualityCmaintenanceEnables search, browsing, and management of Plex media libraries including movies, TV shows, and music, with support for playlists, watch history, natural language music discovery, and detailed media information retrieval.2223 npm5ISC
- 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 gradedqualityBmaintenanceLets AI assistants browse your libraries, search media, get viewing recommendations, check what's on deck, and more — all read-only against your local Plex instance.110 npm1MIT
- FlicenseNot gradedqualityDmaintenanceEnables full management of a Plex Media Server via Claude, including browsing libraries, fixing metadata, managing collections, and more.-