Plex MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| PORT | No | HTTP listen port, an integer from 0 to 65535. Default is 8627. | 8627 |
| MCP_HOST | No | HTTP listen address. Defaults to 127.0.0.1 outside the image, or 0.0.0.0 in the Docker image. | 127.0.0.1 |
| PLEX_URL | Yes | The URL of your Plex Media Server, e.g. http://<plex-host>:32400. Must be an http or https URL. | |
| PLEX_TOKEN | Yes | Your Plex owner/admin X-Plex-Token. | |
| TAUTULLI_URL | No | Tautulli URL. Set together with TAUTULLI_API_KEY to register the Tautulli tools. Must be an http or https URL. | |
| MCP_TRANSPORT | No | Transport mode: stdio (default) or http. Any other value is refused at startup. | stdio |
| PLEX_READ_ONLY | No | Set to 1 to register no write or playback tools, regardless of PLEX_ALLOW_PLAYBACK. 0, empty or unset registers them. | |
| MCP_PATH_SECRET | No | Capability-URL secret for HTTP mode. Required when MCP_TRANSPORT=http. Must be at least 16 characters of letters, digits, -, _, . or ~. | |
| TAUTULLI_API_KEY | No | Tautulli API key. Set together with TAUTULLI_URL to register the Tautulli tools. | |
| MCP_ALLOW_NO_AUTH | No | Set to 1 to run HTTP mode without a secret. Intended only for trusted networks. | |
| PLEX_ALLOW_PLAYBACK | No | Set to 1 to register the list_clients and play_item playback tools. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| prompts | {
"listChanged": true
} |
| resources | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_librariesA | List all Plex library sections. libraryType is the type as Plex names it in the UI (Movies, TV Shows, Music, Photos, Other Videos) and is the field to read when deciding how to treat a library. Do NOT infer that from |
| list_mediaA | List items from any library with rich filtering. Returns watched state, view counts and last-viewed on every record. watched defaults to 'all': the full library, seen and unseen. For SHOW libraries: the watched filter means any-episode-played (watched) / has-unplayed-episodes (unwatched), while each record's watched field means fully watched. A partially-watched show matches both filters' opposites. kind defaults to the library's natural top-level type (movie/show/artist). Use episode/track/album/season for deeper types, or collection to list a section's collections. rated filters on the owner's star rating (userRating, 1-10 internal scale). Movie records carry userRating, and sort=userRating asc puts unrated first. Filters combine (AND). Paginate with offset/limit. detail=true caps limit at 25 and adds fields such as directors, actors, collections and summaries. kind=collection lists a section's collections only. Other filters/sort are ignored for collections. |
| library_changesA | What changed in a library since a cutoff: 'added' (new items) and 'updated' (pre-existing items whose metadata changed since then). The buckets never overlap. Caveat: Plex bumps updatedAt during routine background refreshes, so 'updated' can include items with no meaningful change. since accepts ISO date or relative like '-7d'. kind is movie, show, season, episode, artist, album or track, and defaults to the library's own kind. Use episode in a show library to see new episodes. For a library's collections, use list_media with kind 'collection'. limit applies to each bucket. detail=true caps limit at 25 and adds fields such as directors, actors, collections and summaries. |
| searchA | Global search across ALL libraries (movies, shows, episodes, music, people, collections, playlists). Returns hits grouped by type. Use person hits with person_credits. Use item hits with get_item. Pass externalId instead of query to ask whether the library holds a title you have an IMDb, TMDB or TVDB id for ('imdb:tt0113277', 'tmdb:949', 'tvdb:12345'): it matches the ids Plex already holds on every movie and show library and returns the matching movies/shows, usually one item or none. It reads every movie and show library in full, so it takes a second or two on a large server. |
| get_itemA | Full metadata for one item by ratingKey (any kind). Movies include file paths/codec/size. Shows include watch progress (episodes watched / total). |
| get_extrasA | Extras (trailers, featurettes, behind-the-scenes, deleted scenes) for one item by ratingKey. Local extras include file paths. Plex-provided streaming trailers have no local file (paths is empty). |
| get_childrenA | Children of a container: show→seasons, season→episodes, artist→albums, album→tracks, collection→items. Set playlist=true when ratingKey is a playlist. Paginated. detail=true caps limit at 25 and adds fields such as directors, actors, collections and summaries. |
| person_creditsA | Everything by a person (director, actor, writer, or composer) within one library, with optional watched filter. 'Scorsese films I haven't seen' = role:director, watched:'unwatched'. Paginated. detail=true caps limit at 25 and adds fields such as directors, actors, collections and summaries. |
| library_statsA | Aggregate stats for a library: totals, watched AND unwatched counts, genre/decade/contentRating breakdowns. includeUserStats=true adds per-user play counts from watch history (recent 10,000 plays). |
| similar_itemsA | Plex's 'more like this' list for one item (movie, show, album…) by ratingKey, from your own library only. watched filters the results so 'similar but unseen' is one call. |
| random_pickA | N random items matching the same filters as list_media (the 'just pick something' tool). Defaults to 3 picks. Combine watched=unwatched with genre, decade, maxDurationMin etc. user picks as a Plex Home user, so unwatched means unwatched by them. Each pick is the record list_media returns (title, year, watched state, genres, duration and so on). detail=true adds fields such as directors, actors, collections and summaries so you can explain the pick. |
| get_watchlistA | The server owner's plex.tv watchlist, newest first. Each entry says whether the title is in a library here (inLibrary) and gives its ratingKey if so. Titles not in any library have ratingKey null. Paginate with offset/limit. |
| continue_watchingA | What to continue tonight: the next unwatched episode for every show in progress (and partially-watched movies), with how far in you are. Optional library narrows to one section. user shows a Plex Home user's list. detail=true caps limit at 25 and returns full item records (watched, viewCount, actors, collections…) instead of the progress fields. |
| watch_historyA | Watch/listen history across ALL users: who played what, when. Filter by user (name or account id), library, time window (since/until, ISO dates), or a specific item (ratingKey: answers 'has X seen Y?'). Sorted newest first. kind filters the returned page client-side (movie/episode/track). total reflects the unfiltered count. |
| now_playingA | What is playing on the server right now: user, item, player, progress. |
| list_usersA | All Plex accounts on this server with ids. Use names or ids with watch_history's user filter. |
| set_watchedA | Mark specific items watched or unwatched by ratingKey (owner account). Explicit keys only. Marking watched also records a play. If Plex fails partway, the error names the keys already marked. |
| rate_itemB | Set (0-10) or clear (null) the owner's rating on an item. |
| manage_playlistA | Create, extend, prune, or delete a playlist. create: title + ratingKeys (+ mediaType video|audio). add_items/remove_items: playlistId + ratingKeys. delete: playlistId (deletes ONLY the playlist, never media). If Plex fails partway through remove_items, the error names the keys already removed. |
| manage_collectionA | Create, extend, prune, or delete a collection in a library. create: title + library + ratingKeys (+ kind, which defaults to the kind the library holds and must match it). add_items/remove_items: collectionId + ratingKeys. delete: collectionId (removes ONLY the grouping: its items are untouched). If Plex fails partway through remove_items, the error names the keys already removed. |
| manage_watchlistA | Add movies or shows in the library to the server owner's plex.tv watchlist, or remove them, by ratingKey. Every key is checked before anything is sent: one that is not in a library, is not a movie or show, or has no Plex GUID fails the whole call. If plex.tv fails partway, the error names the keys already changed. |
| scan_libraryA | Trigger 'Scan Library Files' for one library so Plex picks up added or removed files on disk. Safe: never modifies media files or metadata edits, and never re-downloads metadata. Optional path limits the scan to one server-side folder (find valid paths via get_item file.paths). Scans run async. Poll list_libraries and watch 'refreshing'. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| movie_night | Pick three things to watch tonight from the library, with reasons. |
| whats_new | Summarize what was added to every library recently. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| libraries | Every library section with its type and key. |
TDQS
Scored across 22 tools
The tools have clearly distinct purposes: read-only listing/search/metadata/stat tools, watch-state mutations, and playlist/collection/watchlist management are separated by resource and action. Overlapping-sounding retrieval tools (list_media, search, random_pick, similar_items, library_changes) are differentiated by scope and filters, and read vs. manage watchlist/playlist/collection pairs are unambiguous.
Almost all names use consistent snake_case and readable Plex terminology, with mutating tools generally following verb_noun patterns like set_watched, rate_item, and manage_playlist. A few query/status tools use noun phrases such as library_stats, watch_history, and now_playing, but this is predictable enough to remain clear.
At 22 tools the surface is on the high side, but the Plex domain is broad and each tool maps to a distinct capability rather than duplicating another. It is slightly over the typical 3-15 range, yet the set is reasonably scoped.
The server covers core Plex workflows well: library/media discovery, metadata, stats, changes, watch history, now playing, watch state, ratings, playlists, collections, watchlist, and library scans. Minor gaps remain around explicit playlist listing, media metadata editing, and server/library administration, but these are not fatal for the apparent scope.