npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

plex-media-server-mcp

v1.0.2

Published

Safe stdio MCP tools for Plex libraries and playlists

Downloads

475

Readme

Plex Media Server MCP

plex-media-server-mcp is a local, stdio-only Model Context Protocol server for safe Plex library and playlist administration. It exposes 21 curated tools by default and one restricted raw-request tool only when explicitly enabled.

The security boundary is one configured Plex origin. The Plex token is accepted through the environment only: tools cannot supply or override the server URL, token, or authentication headers. stdout is reserved for MCP protocol messages; startup errors and diagnostics use stderr and redact the token.

Requirements

  • Node.js 18.18 or newer
  • A reachable Plex Media Server HTTP(S) origin, commonly http://127.0.0.1:32400
  • A Plex authentication token with only the access needed for the intended operations
  • An MCP host with stdio server support

Install and run

Install the executable globally:

npm install -g plex-media-server-mcp
plex-media-server-mcp

Or run it without a global install:

npx plex-media-server-mcp

The process expects configuration from its environment and communicates over stdin/stdout, so it is normally started by an MCP host rather than an interactive shell.

MCP host configuration

Use this shape for Claude Desktop, Codex, or another JSON-configured stdio MCP host. Replace the placeholder values in the host configuration; never commit a real token.

{
  "mcpServers": {
    "plex": {
      "command": "npx",
      "args": ["-y", "plex-media-server-mcp"],
      "env": {
        "PLEX_URL": "http://127.0.0.1:32400",
        "PLEX_TOKEN": "YOUR_PLEX_TOKEN",
        "PLEX_CLIENT_IDENTIFIER": "plex-media-server-mcp",
        "PLEX_REQUEST_TIMEOUT_MS": "30000",
        "PLEX_ENABLE_RAW_REQUEST": "false"
      }
    }
  }
}

Environment variables

| Variable | Required | Default | Meaning | | --- | --- | --- | --- | | PLEX_URL | Yes | None | Absolute http or https origin for one Plex server. Paths, credentials, query strings, and fragments are rejected. | | PLEX_TOKEN | Yes | None | Plex token sent only as the X-Plex-Token request header. | | PLEX_CLIENT_IDENTIFIER | No | plex-media-server-mcp | Stable identifier sent to Plex for this MCP client. | | PLEX_REQUEST_TIMEOUT_MS | No | 30000 | Positive integer request timeout in milliseconds. | | PLEX_ENABLE_RAW_REQUEST | No | false | Set exactly to true to register plex_raw_request. |

Tool reference

Parameters marked with ? are optional. Object fields accept string, finite number, boolean, or arrays of those scalar values unless stated otherwise.

Status

  • plex_server_status() — verify connectivity and return the Plex root identity response.

Libraries

  • library_list_sections() — list configured library sections.
  • library_get_section(sectionId, includeDetails?) — get one section.
  • library_create_section(name, type, agent, language, scanner?, locations?, preferences?) — create a section.
  • library_update_section(sectionId, name?, agent, language?, scanner?, locations?, preferences?) — update a section; agent is required by the Plex contract.
  • library_delete_section(sectionId, asynchronous?, confirm) — permanently delete a section.
  • library_list_items(sectionId, type?, filters?, sort?, offset?, limit?, includeFields?) — browse section items; offset and limit map to Plex pagination headers.
  • library_get_metadata(ids) — get one or more metadata records; ids is a non-empty string array.
  • library_update_metadata(ids, fields) — update metadata using a non-empty query-field object.
  • library_delete_metadata(ids, proxy?, confirm) — permanently delete metadata records.
  • library_refresh(sectionId?, force?, path?) — refresh all sections or one section; path requires sectionId.
  • library_empty_trash(sectionId, confirm) — permanently empty a section's trash.

Playlists

  • playlist_list(playlistType?, smart?) — list playlists; playlistType is audio, video, or photo.
  • playlist_get(playlistId) — get one playlist by non-negative numeric ID.
  • playlist_create(uri?, playQueueId?, fields?) — create a playlist from a URI, play queue, or query metadata.
  • playlist_update(playlistId, fields) — update a playlist using a non-empty query-field object.
  • playlist_delete(playlistId, confirm) — permanently delete a playlist.
  • playlist_list_items(playlistId, types?, offset?, limit?) — list playlist items with optional media types and pagination.
  • playlist_add_items(playlistId, uri?, playQueueId?) — add items; either uri or playQueueId is required.
  • playlist_clear_items(playlistId, confirm) — permanently clear all playlist items.
  • playlist_move_item(playlistId, playlistItemId, after?) — move an item to the beginning or after another item.

Playlist fields are intentionally open query metadata because the Plex OpenAPI contract omits editable playlist fields. Reserved authentication and curated parameter names are still rejected.

Tool result compatibility

Successful tools return the same complete Plex data in two forms: structuredContent for hosts that support structured MCP results, and one text block containing the summary followed by a newline and compact JSON for hosts that read text content only. Large listings therefore appear in both channels; use pagination to control result size.

Restricted raw request

When PLEX_ENABLE_RAW_REQUEST=true, the server additionally registers:

  • plex_raw_request(method, path, query?, body?, confirm?) — send GET, POST, PUT, PATCH, or DELETE to a validated root-relative path.

Raw requests always stay on the configured PLEX_URL origin and always use the configured authentication headers. Schemes, hosts, credentials, protocol-relative paths, backslashes, and unsafe dot segments are rejected. A supplied body is sent as JSON.

query accepts either an object of scalar/repeated scalar values or an application/x-www-form-urlencoded string, with or without one leading ?. Form-string values remain strings, duplicate keys are preserved as repeated parameters, + decodes as a space, and percent escapes are decoded then canonically re-encoded. Reserved Plex authentication and prototype-related keys are rejected in either form.

The form string and query object below produce the same repeated type parameters:

{ "method": "GET", "path": "/library/sections/7/collections", "query": "?type=1&type=4&title=Road+Trip" }
{ "method": "GET", "path": "/library/sections/7/collections", "query": { "type": [1, 4], "title": "Road Trip" } }

Confirmation behavior

Every destructive curated tool requires the literal boolean confirm: true before it sends a request. This applies to section deletion, metadata deletion, emptying trash, playlist deletion, and clearing playlist items. DELETE through plex_raw_request also requires confirm: true. Missing or false confirmation returns an MCP tool error without contacting Plex.

Troubleshooting

  • PLEX_URL is required or PLEX_TOKEN is required: add the missing value to the MCP host's env object, then restart the server.
  • PLEX_URL must be an absolute HTTP(S) origin: use only the origin, such as http://127.0.0.1:32400, without a trailing API path or embedded credentials.
  • Timeout errors: confirm Plex is reachable from the MCP host and, if needed, increase PLEX_REQUEST_TIMEOUT_MS.
  • Authentication or permission errors: create or retrieve a valid Plex token and verify the token can perform the requested operation directly against that server.
  • plex_raw_request is not listed: set PLEX_ENABLE_RAW_REQUEST exactly to true and restart the MCP server.
  • Protocol/JSON errors from the host: ensure wrappers and launch scripts do not write banners or logs to stdout.

Security

  • Treat PLEX_TOKEN as a secret. Keep tokens environment-only; do not place them in tool arguments, source files, logs, issue reports, or committed configuration.
  • Prefer loopback or a trusted private network, HTTPS where appropriate, and a least-privilege Plex token.
  • Review every destructive call before setting confirm: true.
  • Leave raw access disabled unless a curated tool cannot perform the operation, and validate the requested path and effect before use.
  • Tool errors and startup errors are sanitized, but host environment storage and operating-system process access remain part of your local trust boundary.

Development and release verification

npm ci
npm run lint
npm run typecheck
npm test
npm run build
npm run test:stdio
npm run test:package
npm pack --dry-run
npm audit --omit=dev

prepack builds fresh compiled output. The package allowlist is limited to dist/, this README, the MIT license, and npm's package metadata. Publishing is a separate, explicitly authorized release step; none of the commands above publishes a package.

License

MIT © 2026 Plex Media Server MCP contributors. See LICENSE.