Skip to main content
Glama

plex-director-mcp

CI/CD CodeQL OpenSSF Scorecard OpenSSF Best Practices OpenSSF Baseline Docker Pulls Docker Version Image Size Node License

Plex Director is a self-hosted assistant for a Plex + Servarr media stack. It connects to Plex, Radarr, Sonarr, Prowlarr, SABnzbd, qBittorrent, Tautulli and TMDb (and, optionally, your Linux hosts over SSH), and gives you two ways to work with them:

  • An MCP server for Claude Desktop — ask Claude to find what you own, work out why a movie is missing, add movies, check your indexers and download queues, or run batch jobs.

  • A web dashboard — a browser UI with a chat box ("Which of Harrison Ford's movies do I have in 4K?"), server status, host utilization, download queues, indexer health, and background jobs.

It is built for a home-run setup: run it on your LAN, next to the apps it talks to.

WARNING

Plex Director holds the API keys for every service you connect and can change them, not just read them: it adds movies to Radarr and starts download searches, removes stalled torrents from qBittorrent, runs batch upgrade jobs, and triggers Servarr backups. Adding movies goes through a pick-then-confirm step and batch jobs are planned before they run, but purging stalled torrents and starting backups happen as soon as they are asked for, and the chat and Claude Desktop act with your keys. SetWEB_PASSWORD, keep the dashboard off the public internet, and see Security requirements.

Documentation

Related MCP server: Plex-MCP

Contents

What it can do

  • Find what you own. Search your Plex library, movies and TV shows, by genre, actor, title, year and library (for example just the 4K libraries) across every library at once. A title held in both HD and 4K is one result with both libraries shown, and shows come with their season and episode counts and how much you have watched. You can leave a library such as Sports out of searches unless you name it.

  • Do I have every episode? Ask about a show and Sonarr's episode list says how many aired episodes are downloaded and exactly which are missing, or ask which of your shows have gaps, ranked, including near-complete ones. Unaired episodes and specials are never counted as missing. For a missing episode it can also say why, from Sonarr's history and download queue.

  • What's on, and when does it return? See which episodes air in the next few days, with premieres and finales flagged, or ask when a particular show comes back (or that no date has been announced yet).

  • What should I watch next? Ask for what is on deck: the next episode of each show you are following and the movies you did not finish, with how far through each one is.

  • What have I watched, and what have I let go stale? Ask for unwatched shows, ones you started but never finished, movies you have not watched in years, or the newest additions, alone or combined with genre, library and the rest. Titles Plex says were watched but holds no date for are set aside and counted, not guessed at.

  • Owned versus missing. Look up an actor's TMDb filmography, movies and TV shows, and see which of those titles are in Plex and which are not, optionally narrowed to movies or shows, by year range, or by "in 4K". Talk-show and "Self" appearances are left out, and a title appears once even when the actor played several roles in it.

  • Diagnose and add movies. Trace a movie through Radarr metadata, history and the download queues to see why it is missing, or search TMDb, pick from a grid, and add the choices to Radarr with a download search.

  • Watch your downloads and indexers. See SABnzbd and qBittorrent queues, clean up stalled torrents, and check every Prowlarr indexer's health (including ones that are backing off).

  • Run batch jobs safely. Plan a movie-upgrade batch and let a rate-limited runner search one movie a minute, with pause, resume, cancel, and automatic pausing if Radarr stops responding.

  • Keep an eye on your hosts. CPU, memory, disk, uptime and Docker container health for your Linux hosts over SSH, plus Radarr, Sonarr and Prowlarr built-in backups on demand. Each host's SSH key is remembered the first time it connects, and a changed key is refused until you approve it.

  • Understand usage. Live Plex streams and watch statistics through Tautulli.

  • Stay informed. Optional Discord notifications when a batch job finishes or is paused.

Quick start

From v1.2.0, Plex Director is listed in the official MCP registry as io.github.HoneyBearTech/plex-director-mcp, so MCP clients that browse the registry can install it directly (server.json lists its settings). Otherwise, the fastest way to try it is Docker Compose:

---
services:
  plex-director:
    image: honeybeartech/plex-director-mcp:latest
    container_name: plex-director
    environment:
      - WEB_PASSWORD=choose-a-password
    volumes:
      - ./data:/app/data
    ports:
      - 3000:3000
    restart: unless-stopped
docker compose up -d

Then open http://localhost:3000, sign in, and fill in your services on the Settings page (Radarr, Sonarr, Prowlarr, SABnzbd, qBittorrent, Tautulli, Plex, TMDb). The full guide, with every option, is in Docker below. To use it from Claude Desktop instead, see Claude Desktop via Docker.

Docker

Images are published to both registries, and both are signed (see CI/CD):

Registry

Image

Docker Hub

honeybeartech/plex-director-mcp

GitHub Container Registry

ghcr.io/honeybeartech/plex-director-mcp

Everything below works with either; the examples use Docker Hub.

Supported architectures

Multi-arch manifests are published, so pulling the image gets the right one for your machine automatically.

Architecture

Available

x86-64 (linux/amd64)

✅

arm64 (linux/arm64)

✅

Image tags

Tag

Description

latest

The most recent build of the main branch. Includes changes that have not been given a version number yet.

1.4.0

A specific release. Pin one of these if you want to choose when to upgrade.

1.1

The newest patch release of a minor version.

sha-<commit>

The build of one specific commit, for pinning or bisecting.

Release notes for the numbered versions are on the Releases page.

Application setup

  1. Start the container with one of the usage examples and open the web UI at http://<host>:3000.

  2. Set a password. Add WEB_PASSWORD to the container's environment. Without it, the dashboard is open to anyone who can reach the port, including the Settings page, and shows a warning banner. See Security.

  3. Add your services. Open Settings and fill in each tab. Every field can also be given as an environment variable (see the reference), which is handy for automated setups. You only need the services you actually use.

  4. Give the chat box a brain. The Query page uses Claude to answer questions, so it needs ANTHROPIC_API_KEY in the container's environment. This is a pay-per-use Anthropic API key, separate from a Claude subscription. The rest of the dashboard works without it.

  5. Keep the data volume. Your settings, job history and the secret that keeps you signed in live in a SQLite database at /app/data. Mount a volume there or you will lose them each time the container is recreated.

Where to find each credential:

Service

What to enter

Radarr, Sonarr, Prowlarr

The URL, and the API key from Settings → General.

SABnzbd

The URL, and the API key from Config → General.

qBittorrent

The Web UI URL, username and password.

Tautulli

The URL (without /api/v2) and the API key from Settings → Web Interface.

Plex

The server URL (e.g. http://192.168.1.10:32400) and an X-Plex-Token: open any movie in Plex Web, choose ⋯ → Get Info → View XML, and copy the X-Plex-Token= value from the address bar. Treat it like a password.

TMDb

Your API Read Access Token (the long one, from your TMDb account's API settings), not the short v3 API key.

Networking: inside the container, localhost is the container itself, not your server. Use the LAN address of each service (for example http://192.168.1.10:7878), or, if the other apps are in the same Compose project or Docker network, their service names (http://radarr:7878).

Usage

Here are some example snippets to help you get started creating a container. Docker Compose is recommended.

---
services:
  plex-director:
    image: honeybeartech/plex-director-mcp:latest
    container_name: plex-director
    environment:
      - WEB_PASSWORD=choose-a-password
      - ANTHROPIC_API_KEY=sk-ant-your-key #optional, needed for the Query chat
      - RADARR_URL=http://192.168.1.10:7878 #optional, or set on the Settings page
      - RADARR_API_KEY=your_radarr_api_key #optional
      - PLEX_URL=http://192.168.1.10:32400 #optional
      - PLEX_TOKEN=your_plex_token #optional
      - TMDB_API_KEY=your_tmdb_read_access_token #optional
      - DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/... #optional
    volumes:
      - /path/to/plex-director/data:/app/data
      - /path/to/ssh/id_ed25519:/ssh/id_ed25519:ro #optional, for host monitoring over SSH
    ports:
      - 3000:3000
    restart: unless-stopped

The image has a built-in health check (docker ps shows healthy once it is up), so you don't need to add one.

To keep your credentials out of the compose file, put them in a .env-style file next to it and reference it instead of listing them:

    env_file:
      - plex-director.env

Then start it:

docker compose up -d

Docker CLI

docker run -d \
  --name=plex-director \
  -e WEB_PASSWORD=choose-a-password \
  -e ANTHROPIC_API_KEY=sk-ant-your-key \
  -p 3000:3000 \
  -v /path/to/plex-director/data:/app/data \
  --restart unless-stopped \
  honeybeartech/plex-director-mcp:latest

Add any other variables from the reference with more -e flags, or put them in a file and pass --env-file plex-director.env. For SSH host monitoring, also add -v /path/to/ssh/id_ed25519:/ssh/id_ed25519:ro.

--env-file is not the same as a .env file for Node. Docker reads values literally: don't put quotes around values, and don't put a comment after a value on the same line (KEY=abc # my key becomes the value abc # my key). Put comments on their own line.

Claude Desktop via Docker

The same image is also the MCP server, which speaks over stdio. Tell Claude Desktop to run it with docker run -i in its config (Settings → Developer → Edit Config, claude_desktop_config.json):

{
  "mcpServers": {
    "plex-director": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "--env-file", "/absolute/path/to/plex-director.env",
        "-v", "plex-director-data:/app/data",
        "honeybeartech/plex-director-mcp:latest"
      ]
    }
  }
}

Restart Claude Desktop and the plex-director server appears as a tool provider (26 tools, listed below). Notes:

  • -i is required, since MCP talks over stdin/stdout. Don't add -t.

  • No -p is needed. The web dashboard also starts inside this container, but you only need to publish its port if you want to open it from this container instead of from the Compose one.

  • If you also run the long-lived container above, give both the same data volume (or bind mount) so they share settings and job history.

  • The container keeps running if Claude closes its stdin; quitting Claude Desktop stops it, or use docker stop.

Parameters

Container images are configured using parameters passed at runtime. These parameters are separated by a colon and indicate <external>:<internal> respectively. For example, -p 8080:3000 would expose port 3000 from inside the container to be accessible from the host's IP on port 8080 outside the container.

Parameter

Function

-p 3000:3000

The web dashboard. Change the left number to use a different port on your host.

-e WEB_PASSWORD=

Password for the web dashboard. Strongly recommended.

-e ANTHROPIC_API_KEY=

Enables the Query chat.

-e RADARR_URL= etc.

Service connection details; see the reference. Optional, since they can be entered on the Settings page.

-v /app/data

The SQLite database: your saved settings, job history and login-session secret. Mount a volume here.

-v /ssh/id_ed25519:ro

Optional. A private SSH key for host monitoring (with -e SSH_KEY_PATH=/ssh/id_ed25519).

Environment variable reference

Nothing is required to start the container: it boots with no configuration and lets you fill things in on the Settings page.

Service connections. On first start these are copied into the database, and from then on the value saved in the database wins (that is what the Settings page edits). If you change one of these variables later and nothing happens, that is why; change it on the Settings page, or delete the database.

Variable

Description

RADARR_URL, RADARR_API_KEY

Radarr. Used for movie status, diagnosis, adding movies, and batch jobs.

RADARR_DEFAULT_QUALITY_PROFILE

Optional. The name of the quality profile new movies get when you add them. Leave it blank to use Radarr's first profile. Also on the Radarr tab of the Settings page.

SONARR_URL, SONARR_API_KEY

Sonarr. Optional; used for TV episode completeness and backups.

PROWLARR_URL, PROWLARR_API_KEY

Prowlarr, for indexer health and backups.

SABNZBD_URL, SABNZBD_API_KEY

SABnzbd, for the queue and for diagnosing missing media.

QBITTORRENT_URL, QBITTORRENT_USER, QBITTORRENT_PASS

qBittorrent Web UI.

TAUTULLI_URL, TAUTULLI_API_KEY

Tautulli, for streams and watch statistics.

PLEX_URL, PLEX_TOKEN

Plex, for searching what you own.

PLEX_SKIP_LIBRARIES

Optional. Comma-separated Plex library names to leave out of searches (whole names, any case), e.g. Sports. A library you name in a question, such as "in Sports", is still searched. Blank searches every library. Also on the Plex tab of the Settings page.

TMDB_API_KEY

TMDb API Read Access Token, for actor filmographies and the movie-choice grid.

UBUNTU_HOSTS

Comma-separated hosts to monitor over SSH, e.g. 192.168.1.10,192.168.1.11. Add :port for a non-standard SSH port (192.168.1.10:2222).

SSH_USER

The SSH user for those hosts.

Container settings. These are read from the environment every time and are never stored in the database or shown on the Settings page.

Variable

Default

Description

WEB_PASSWORD

(none)

Requires a login for the dashboard. Changing it signs everyone out.

WEB_ALLOWED_HOSTS

(none)

Only matters without WEB_PASSWORD: extra host names the dashboard answers to, comma-separated (e.g. plex.example.com behind a reverse proxy). IP addresses, localhost, single-word names and .local / .lan / .home.arpa / .internal names always work; any other name gets a 403, which blocks DNS-rebinding attacks. * turns the check off.

WEB_TRUST_PROXY

(none)

The reverse proxy in front of the dashboard: its address or subnet, comma-separated (e.g. 192.168.40.10 or 192.168.40.0/24), or loopback. Only requests from there may set X-Forwarded-For and X-Forwarded-Proto, so the login limit applies per real client and the session cookie is Secure over HTTPS. Unset, both headers are ignored. true and hop counts are refused.

SETTINGS_ENCRYPTION_KEY

(none)

Encrypts the service credentials saved in the database (AES-256-GCM). 32 random bytes, base64 or hex: make one with openssl rand -base64 32. Credentials already saved are encrypted at the next start. Every container sharing the database needs the same key, and the database is useless without it, so keep a copy somewhere other than your backups. Recommended.

WEB_PORT

3000

The port the dashboard listens on inside the container.

ANTHROPIC_API_KEY

(none)

Anthropic API key for the Query chat.

SSH_KEY_PATH

(none)

Path (inside the container) to the private key for host monitoring. It must be readable by the container's user.

SSH_KEY_PASSPHRASE

(none)

The passphrase, if that private key is passphrase-protected.

DISCORD_WEBHOOK_URL

(none)

Discord webhook for job-completed and job-paused notifications.

JOB_RUNNER_INTERVAL_SECONDS

60

How often the job runner advances a started job by one movie (minimum 10; 0 turns the runner off).

Read-only and non-root operation

The container runs as a non-root user, UID and GID 65532 (distroless's nonroot), from 1.3.0 on; earlier versions ran as root. The image has no shell or package manager, and the data directory is the only place it writes, so it also runs with a read-only filesystem and no capabilities:

services:
  plex-director:
    image: honeybeartech/plex-director-mcp:latest
    read_only: true
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    volumes:
      - /path/to/plex-director/data:/app/data
    ports:
      - 3000:3000

Or with the CLI: --read-only --cap-drop ALL --security-opt no-new-privileges:true.

A named volume works as it is: Docker gives a new volume the image's ownership of /app/data. A host folder must belong to UID 65532 first: sudo chown -R 65532:65532 /path/to/plex-director/data. To run as another user instead, for example one that already owns the folder, add user: "1000:1000" (or --user 1000:1000). If the data directory isn't writable, the container stops at startup and prints the chown to run. Upgrading from 1.2.x or earlier, whose data belongs to root: see upgrading. If you use SSH host monitoring, the mounted key must also be readable by the container's user.

Updating

Your settings and job history live in the data volume, so updating just replaces the container.

Docker Compose

docker compose pull plex-director
docker compose up -d
docker image prune

Docker CLI

docker pull honeybeartech/plex-director-mcp:latest
docker stop plex-director
docker rm plex-director
# ...then run the same `docker run` command as before
docker image prune

Verify a download. Every published image is signed with cosign using GitHub's OIDC identity (no keys to manage):

cosign verify \
  --certificate-identity-regexp "https://github.com/HoneyBearTech/plex-director-mcp/.*" \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  honeybeartech/plex-director-mcp:latest

Building locally

git clone https://github.com/HoneyBearTech/plex-director-mcp.git
cd plex-director-mcp
docker build -t plex-director-mcp .

.dockerignore keeps .env, the local database and other secrets out of the build context. Never bake secrets into an image; pass them at run time.

Run without Docker (Claude Desktop)

Requires Node.js 24.

git clone https://github.com/HoneyBearTech/plex-director-mcp.git
cd plex-director-mcp
npm install
# Build the dashboard; without this the web UI has nothing to serve.
cd web && npm install && npm run build && cd ..

Create a .env file in the repo root with the services you use (all optional; you can also enter service details later on the Settings page):

RADARR_URL=http://radarr:7878
RADARR_API_KEY=your_radarr_api_key
RADARR_DEFAULT_QUALITY_PROFILE=Your Profile Name
SONARR_URL=http://sonarr:8989
SONARR_API_KEY=your_sonarr_api_key
PROWLARR_URL=http://prowlarr:9696
PROWLARR_API_KEY=your_prowlarr_api_key
SABNZBD_URL=http://sabnzbd:8080
SABNZBD_API_KEY=your_sabnzbd_api_key
QBITTORRENT_URL=http://qbittorrent:8080
QBITTORRENT_USER=your_qbittorrent_user
QBITTORRENT_PASS=your_qbittorrent_password
TAUTULLI_URL=http://tautulli:8181
TAUTULLI_API_KEY=your_tautulli_api_key
PLEX_URL=http://plex:32400
PLEX_TOKEN=your_plex_token
TMDB_API_KEY=your_tmdb_read_access_token
ANTHROPIC_API_KEY=your_anthropic_api_key
UBUNTU_HOSTS=192.168.1.10,192.168.1.11
SSH_USER=your_ssh_username
SSH_KEY_PATH=/path/to/id_ed25519
SSH_KEY_PASSPHRASE=only_if_the_key_has_one
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
WEB_PORT=3000
WEB_PASSWORD=choose-a-password

See the reference for what each one does. Two things that commonly go wrong:

  • Comments go on their own line, never after a value (KEY=abc # note makes the note part of the value in some tools).

  • A path with a space needs quotes around the whole value: SSH_KEY_PATH="/Users/me/.ssh/my key", not /Users/me/.ssh/'my key'.

Add the server to Claude Desktop (Settings → Developer → Edit Config):

{
  "mcpServers": {
    "plex-director": {
      "command": "npx",
      "args": ["-y", "tsx", "/absolute/path/to/plex-director-mcp/src/index.ts"],
      "env": { "NODE_ENV": "production" }
    }
  }
}

Replace the path with the real one and restart Claude Desktop. The server starts the web dashboard on WEB_PORT in the same process.

Web dashboard

The dashboard runs on WEB_PORT (default 3000) in the same process as the MCP server.

Page

What it shows

Query

A chat box that answers questions about your library using Claude and your services. Search results appear as a table with posters (shows add seasons, episodes and watch progress), showing the first 50 with a button to expand. Follow-up questions keep the context; New chat starts over. Needs ANTHROPIC_API_KEY.

Server Status

Live Plex streams and watch statistics (from Tautulli).

Node Utilization

CPU, memory, disk, uptime and container health for each SSH host. A host that is unreachable shows why; a host whose SSH key changed is flagged with a Trust new key button (see Security).

Queues

The SABnzbd and qBittorrent download queues.

Indexers

Every Prowlarr indexer with its status (healthy, recent failures, backing off, disabled) and Prowlarr's own health warnings.

Jobs

Batch jobs and their progress. Read-only: start, pause and cancel jobs from Claude.

Settings

Connection details for every service. Secrets are never sent back to the browser, only whether they are set.

Set WEB_PASSWORD to require a login: a sign-in page, then a signed 7-day session cookie (marked Secure automatically when served over HTTPS). Failed logins are rate-limited. Logging out only clears your browser's copy, so to revoke every session, change the password.

The health check is GET /healthz, which returns {"ok":true} and needs no login. The Docker image runs it for you every 30 seconds using Node itself (the image has no curl), on whatever WEB_PORT is set to.

MCP tools

Twenty-six tools are available to Claude Desktop. The twelve marked ★ are also what the dashboard's Query chat uses.

The server also sends MCP clients short usage instructions: which tool answers which kind of question, and to confirm before anything that changes your services. The same guidance is in an Agent Skill for agents that load skills (such as Claude Code), and in the Query chat's prompt. It is written once in src/guidance.ts.

Your library

Tool

What it does

★ search_plex_library

Searches the movies and TV shows in your Plex library by genre, actor, title, year and/or library (e.g. 4k), across all libraries, or only movies or only shows. Shows report seasons, episodes and watch progress. Filter by watch state (unwatched, in progress, watched) or "not watched in N years" (a never-watched title counts from when it was added), and sort by recently added or last watched. Narrow by network or studio, content rating (TV-MA, R…), audience rating, release years (a decade) or "added in the last N days". Watch state is for the Plex account the app is connected with. Paged for large results.

★ search_episodes

Finds individual TV episodes: "the episode of Entourage where…", an episode by title, episodes that aired in a date range, a show's season premieres or finales. With a show named it searches the episode titles and plots; without one only titles and air dates, because Plex cannot search plots across the whole library. Shows the season and episode numbers, air date and watch state.

★ get_on_deck

"What should I watch next?" from Plex's On Deck (Continue Watching): the movies you have partly played and, for each show you are following, the episode to watch next (or the one you are part way through), most recently active first, with how far through each is. A movie held in HD and 4K is one entry. Can be limited to movies or shows, or to a library such as kids. Plex reports at most 50 items; the watch state is for the Plex account the app is connected with.

★ resolve_actor_filmography

An actor's TMDb filmography, movies and TV shows (or only one), with each title marked as in Plex or not, filterable by year range, owned/missing, and library. Shows are matched to Plex by TMDb id, so a Plex show with no TMDb match is not recognised as owned.

★ check_series_completeness

"Do I have every episode of this show?" From Sonarr's episode list: how many aired episodes are downloaded, which seasons and episodes are missing, what has not aired yet, and whether Sonarr is monitoring the show (so will fetch the rest). Counts the episodes themselves rather than Sonarr's statistics, which treat a partly downloaded, unmonitored show as complete. It does not check what Plex has scanned.

★ find_series_gaps

Which TV shows are missing aired episodes, most missing first, with how many are downloaded and whether Sonarr is looking for the rest. Filter by monitored, not monitored or actively being searched for, by how many are missing (for "nearly complete" shows) and hide shows with nothing downloaded.

★ find_series_by_quality

Finds TV shows by the video quality Sonarr downloaded: "which shows do I only have in 720p?", "which have 1080p or better?", "which mix qualities?" (upgrade candidates). Shows the lowest best quality first with how many files are at each resolution. It sees only what Sonarr downloaded, so a 4K copy in a separate Plex 4K library is not counted (use the Plex search with the 4k library). Read-only.

★ check_series_status

What Sonarr knows about one show: monitored or not, its quality profile and location, when the next episode airs, when something was last downloaded, what is in the download queue, and how many aired episodes are downloaded.

★ diagnose_missing_episodes

Why aired episodes of a show have no file, from Sonarr's history and download queue: never grabbed, grabbed but never imported, a download that failed (with Sonarr's reason), a file that was removed, stuck in the queue, or simply not monitored so Sonarr never looks for it. Can be limited to a season or one episode. Read-only.

★ get_upcoming_episodes

What TV is coming, from Sonarr's calendar. With no title: "what's on this week?", every episode airing in the next few days (7 by default, up to 60) from the shows Sonarr monitors, by day, with season premieres and finales flagged and episodes already downloaded marked. With a title: "when does this show come back?", its next episodes, or that none is scheduled yet, or that it has ended. Shows Sonarr does not monitor are left out unless asked for, and their number is reported.

★ check_movie_status

Whether a movie is in Radarr, and its monitoring status, with artwork.

★ diagnose_missing_media

Traces a movie through Radarr metadata, history and the download queues to find why it is missing.

search_and_select_movies

Searches TMDb and shows a numbered grid of matches.

confirm_selected_choices

Adds the chosen numbers from that grid to Radarr as monitored movies and starts a download search. Already-present movies are reported, not added twice. Uses the quality profile you name, otherwise the default set on the Radarr tab of the Settings page, otherwise Radarr's first profile; and Radarr's first root folder unless you name another.

Downloads and indexers

Tool

What it does

manage_stalled_downloads

AUDIT lists stalled or slow qBittorrent downloads with their hashes; PURGE_STALLED deletes the ones you name by hash, with their files, and nothing else.

check_indexer_health

Reports failing, backing-off and disabled Prowlarr indexers, and Prowlarr's own warnings.

Background jobs

Tool

What it does

plan_media_upgrade

Finds movies without a file or below 1080p and schedules them as a batch job (movies only, up to 25 at a time by default).

get_background_jobs

Lists jobs and their progress.

update_job_status

PAUSE, RESUME or CANCEL a job. Resuming a job is what starts it.

execute_next_job_step

Searches the next movie in a job by hand. Started jobs are also advanced automatically, one movie a minute, by the job runner.

Infrastructure and analytics

Tool

What it does

get_cluster_infrastructure_health

CPU, memory and Docker container health for each SSH host.

get_cluster_hardware_analytics

CPU and memory per host as a table.

trust_new_host_key

Forgets a monitored host's remembered SSH key after you rebuilt it, so the next check trusts the key it presents now. The dashboard's Trust new key button does the same, but only when WEB_PASSWORD is set.

run_cluster_backup

Asks Radarr, Sonarr and Prowlarr (whichever are configured) to run their built-in database backups, waits for each (up to about a minute; a slower one is reported as still running), and confirms a new backup file appeared, with its name, size and time. The backups stay in each app's own backup folder; nothing is copied.

get_plex_activity

Live playback streams and transcoding load, via Tautulli.

get_library_analytics

Most-watched titles, top users, platforms and libraries, via Tautulli.

How batch jobs work. plan_media_upgrade creates a job in the PENDING state; nothing runs until you RESUME it. A started job is then advanced by the job runner, one Radarr search per interval (default 60 seconds), so a large batch cannot flood your indexers. A paused, cancelled or pending job is never touched, and a job that fails three times in a row (for example because Radarr is down) is paused and reported to Discord.

Security

  • Run it on a trusted network. It is designed for a home LAN and is not designed or tested to be exposed to the public internet. If you do reach it from outside, put it behind HTTPS and a reverse proxy you trust. See SECURITY.md to report a vulnerability.

  • Set WEB_PASSWORD. Without it, anyone who can reach the port can use the dashboard and change its settings.

  • Secrets stay on the server. The Settings page never returns a saved key or token, and Plex artwork is fetched through a server-side proxy so the Plex token never reaches your browser.

  • SSH host monitoring uses key authentication, and remembers each host's key on first use. The first time a host connects, its key fingerprint is saved; from then on a different key is refused before any command is sent, and the Node Utilization page shows the host as offline with a Trust new key button for when you have legitimately rebuilt it (that button needs WEB_PASSWORD; without one, ask Claude Desktop to use trust_new_host_key). Without a password anyone on your network could use that button to trust an impostor, so it is only offered with one. That protects against a host being swapped for an impostor after first contact, so if you want certainty about the first connection, compare the fingerprint with ssh-keyscan -t ed25519 <host> | ssh-keygen -lf -. Use a dedicated, unprivileged user, and keep it on a network you trust.

  • Some tools change things. confirm_selected_choices adds movies and starts downloads, manage_stalled_downloads with PURGE_STALLED deletes the torrents you agreed to after an AUDIT, with their files, and the job runner triggers searches. Claude Desktop asks for your permission before it uses a tool, so review what it proposes.

  • The image runs as a non-root user (UID 65532); see read-only and non-root operation to lock it down further.

Development

npm install
npm start           # MCP server (stdio) + dashboard on WEB_PORT
npm test            # the test suite
npx tsc --noEmit    # typecheck the backend and the tests

The dashboard is a separate npm project in web/ (React, Vite and TypeScript, with its own package.json):

cd web
npm install
npm run dev         # dev server on :5173, proxies /api to the backend on :3000
npx tsc --noEmit
npm run build       # static assets the backend serves; the Dockerfile does this for you

Tests use Node's built-in test runner, so there is nothing extra to install. They run against a throwaway database, never read your real .env, have your service credentials removed from the environment, and fail every HTTP request unless a test installs a fake, so running them can't touch your real services. test/isolation.test.ts fails the run if any of that ever breaks.

Runtime notes

  • State (settings, job history, the login secret) is a SQLite database at data/plex_director.db, or /app/data in the container.

  • Uses the official MCP SDK.

  • The Query chat calls the Anthropic API with the tools above; nothing else leaves your network except calls to TMDb and, if you set it, Discord.

CI/CD

.github/workflows/ci.yml has three jobs:

  • Typecheck & audit (check) runs on every push and pull request against main: the TypeScript typecheck, the test suite, npm audit --audit-level=high, and the same typecheck and audit for the dashboard in web/.

  • Build, smoke test, and publish (publish) runs on every push to main, every v*.*.* tag push and every pull request, once check passes. Every run builds the image and boots it with dummy configuration to confirm it starts. Pushes then publish to both registries (branch pushes tag latest and the commit SHA; tag pushes also get the version, e.g. 1.2.3 and 1.2), run a Docker Scout vulnerability scan (reported in the job summary, non-blocking for now), and sign both images with cosign.

  • Create GitHub Release (release) runs only on v*.*.* tag pushes, after publish succeeds, and creates a release with generated notes.

Alongside it: CodeQL analyses the TypeScript on every push and pull request and weekly, OpenSSF Scorecard scores the repo's supply-chain practices weekly (see the badge above), and Dependabot opens weekly PRs for npm, Docker base image and GitHub Actions updates, which auto-merge once CI passes unless they are a major version bump.

License

MIT

Available Tools

26 tools
check_indexer_healthA

Audits all Usenet indexers and torrent trackers configured in Prowlarr to flag connection failures or bans, and reports Prowlarr's own system health warnings.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral disclosure burden. It transparently states the actions: audits, flags failures/bans, and reports system health warnings. This conveys a read-only monitoring operation and makes side effects (or lack thereof) reasonably clear. No contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, well-structured sentence that leads with the action verb 'Audits' and packs all relevant details without redundancy. Every word earns its place; there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-parameter tool with no output schema, the description fully covers what the tool does and what it reports. An agent has everything needed to invoke and interpret the result. No gaps that would hinder correct usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and the schema is empty (100% coverage). The description adds meaning by explaining the tool's purpose, but since there are no parameters to document, the baseline of 4 applies. Nothing more is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Audits'), a specific resource ('Usenet indexers and torrent trackers configured in Prowlarr'), and a precise outcome (flag connection failures/bans, report health warnings). This clearly distinguishes it from siblings like get_cluster_infrastructure_health, which targets a broader infrastructure scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: this tool is for auditing indexer/tracker connectivity in Prowlarr. It does not explicitly name alternatives or when-not conditions, but the context is specific enough that an agent can infer when to use it. Lacks the explicit routing that a 5 would require.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_movie_statusA

Checks if a specific movie exists in the Radarr library on the Ubuntu cluster and returns its monitoring status with artwork.

NameRequiredDescriptionDefault
titleYesThe exact title of the movie to search for.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description must carry the behavioral burden. It conveys a read-only check and names the output (monitoring status and artwork), but it does not describe behavior when the movie is absent, error conditions, or explicitly confirm no side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that states the action, resource, and output with no filler or redundancy. Every phrase earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema and no annotations, the description should clarify the return contract more fully. It says monitoring status and artwork are returned, but not what the output looks like when the movie is not found or how 'monitoring status' is represented. This is adequate but has clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the parameter is already documented as 'The exact title of the movie to search for.' The description adds context about the Radarr library but does not meaningfully enrich the title parameter beyond the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action ('Checks if a specific movie exists'), a concrete resource ('Radarr library on the Ubuntu cluster'), and a distinct outcome ('returns its monitoring status with artwork'). This clearly differentiates it from siblings like search_and_select_movies or diagnose_missing_media.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The intended use is implied: call it when you need to verify a movie's presence and monitoring status. However, the description never explicitly says when to prefer this tool over siblings, nor does it mention alternatives or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_series_completenessA

Answers 'do I have every episode of ?' from Sonarr's episode list: how many aired episodes are downloaded, which seasons and episodes are missing, what has not aired yet, and whether Sonarr is monitoring the show (so will fetch the rest). Use this for one specific TV show; use find_series_gaps to see which shows have gaps. It does not check what Plex has scanned.

NameRequiredDescriptionDefault
yearNoFirst air year, only needed to tell same-named shows apart.
titleYesThe show's title, e.g. 'Breaking Bad'.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the data source (Sonarr), the return contents (downloaded aired count, missing seasons/episodes, unaired episodes, monitoring status), and a key limitation (doesn't reflect Plex scanning). It stops short of stating read-only nature or any rate/auth behavior, but the query semantics are otherwise clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the question it answers, then the returned contents, then the sibling alternative and the boundary. Dense but every clause earns its place with zero filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-param query tool with no output schema and no annotations, the description enumerates what the result includes and clarifies the data source and its Plex blind spot. It does not describe the exact response shape, but the content coverage is sufficient for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (title, year) are already documented in the schema, including the year's disambiguation role. The description adds no syntax or format detail beyond what the schema provides, which is the baseline 3 case.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

It states a specific verb+resource framed as a question it answers ('do I have every episode of <show>?') and names the exact data source (Sonarr's episode list) and returned contents. It explicitly distinguishes itself from the sibling find_series_gaps. An agent can select it correctly without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit when-to-use ('for one specific TV show'), names the alternative for the opposite case ('use find_series_gaps to see which shows have gaps'), and adds a boundary exclusion ('does not check what Plex has scanned'). Both the routing rule and the negative scope are stated, not implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_series_statusA

The TV counterpart of check_movie_status: what Sonarr knows about one show - whether it is monitored, its quality profile and location, when the next episode airs, when something was last downloaded, what is in the download queue, and how many aired episodes are downloaded. Use it for 'is monitored?', 'what quality is ?', 'when does come back?'. For which episodes are missing use check_series_completeness; for why one is missing use diagnose_missing_episodes.

NameRequiredDescriptionDefault
yearNoFirst air year, only needed to tell same-named shows apart.
titleYesThe show's title, e.g. 'Severance'.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It richly describes the informational scope of the response (monitoring, quality, queue, download counts), which signals a read-only status lookup, but it never explicitly states read-only/safe behavior or any auth or rate-limit constraints. Strong on what it reports, thinner on safety profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core identity ('TV counterpart of check_movie_status') before the attribute list, then usage examples, then alternatives. The attribute enumeration is somewhat dense, but each element is informative and no sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no annotations, the description does the heavy lifting by enumerating exactly what the tool returns, so an agent knows what to expect. It does not cover error behavior or output format, leaving minor gaps for a status-query tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with title and year both documented in the schema (including the same-named-show disambiguation rationale). The description adds no syntax or format detail beyond the schema, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (what Sonarr knows about one show) and enumerates the exact data points returned: monitored state, quality profile, location, next episode air date, last download, queue contents, and downloaded count. It positions itself explicitly as the TV counterpart of check_movie_status, making it easy to tell apart from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete trigger phrases ('is <show> monitored?', 'what quality is <show>?', 'when does <show> come back?') and routes two adjacent questions to explicit alternatives: check_series_completeness for which episodes are missing and diagnose_missing_episodes for why. When-to-use and when-not-to-use are both covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

confirm_selected_choicesA

Adds the user's numbered choices from the last search_and_select_movies grid to Radarr as monitored movies and starts a download search for each. Movies already in Radarr are reported, not added twice. Uses the quality profile you name, otherwise the default set on the Settings page, otherwise Radarr's first quality profile; and Radarr's first root folder unless told otherwise.

NameRequiredDescriptionDefault
rootFolderNoRadarr root folder path to add to instead of the first one (e.g. '/media/movieskids').
chosenIndexesYesAn array of chosen numbers selected by the user (e.g., [1, 3]).
qualityProfileNoRadarr quality profile name to use instead of the default.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it discloses key behaviors: adding monitored movies, starting download searches, avoiding duplicate additions, and default quality profile/root folder fallbacks. It could go further by describing result reporting format, but the core side effects are transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences cover the main action, duplicate handling, and defaulting logic without waste. The most important purpose is front-loaded, and each sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is largely complete for a mutating workflow tool: it explains what happens, the dependency on a prior search grid, and fallback defaults. It does not describe the output/report format, and with no output schema this is a minor gap, but the essential invocation context is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds meaning beyond the schema by explaining the fallback order for qualityProfile and the default rootFolder behavior. It also ties chosenIndexes to the user's numbered selections from the search grid.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Adds the user's numbered choices... to Radarr as monitored movies and starts a download search for each.' This clearly distinguishes it from siblings like search_and_select_movies and check_movie_status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Establishes clear context by referencing 'the last search_and_select_movies grid,' indicating this is a follow-up to that specific sibling tool. It does not explicitly state exclusions or alternatives, but the workflow context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

diagnose_missing_episodesA

Explains WHY aired episodes of a show have no file, the TV counterpart of diagnose_missing_media: from Sonarr's history and download queue it says, per group of episodes, whether they were never grabbed, were grabbed but never imported, had a download fail (and why), had their file removed, are stuck in the queue, or are simply not monitored so Sonarr never looks for them. Read-only: it changes nothing. Give season (and episode) to look at just those; without them it groups every missing episode of the show. Use check_series_completeness first to see which episodes are missing.

NameRequiredDescriptionDefault
yearNoFirst air year, only needed to tell same-named shows apart.
titleYesThe show's title, e.g. 'Bluey'.
seasonNoOnly this season.
episodeNoOnly this episode number (needs season).

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and does well: it declares 'Read-only: it changes nothing,' names its data sources (Sonarr's history and download queue), and enumerates the diagnostic categories returned. It stops short of mentioning error behavior or lookup ambiguity handling, but the safety profile and result shape are covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense paragraph that is front-loaded with purpose before moving to behavior, safety, scoping, and finally the prerequisite. Every clause contributes, though the diagnostic-cause enumeration makes it longer than strictly needed for selection.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema and no annotations, so the description must supply the return semantics and safety profile itself, and it does: it lists the diagnostic verdicts an agent will receive and confirms the call is side-effect free. An agent has everything needed to call it and interpret results correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline would be 3, but the description adds parameter-dependent behavior the schema does not: season/episode act as optional narrowing filters, and omitting them changes the result to a whole-show grouping. The year parameter's disambiguation role is already in the schema, so no extra credit there.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (explains why aired episodes have no file) and immediately scopes it as the TV counterpart of diagnose_missing_media, which disambiguates it from that sibling. The enumerated causes it reports (never grabbed, grabbed but not imported, failed download, file removed, stuck in queue, unmonitored) make the tool's output unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit routing: 'Use check_series_completeness first to see which episodes are missing,' plus the invocation choices ('Give season (and episode) to look at just those; without them it groups every missing episode of the show'). The alternative and prerequisite are both named, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

diagnose_missing_mediaA

Traces a movie through Radarr metadata, history, and active download client queues to pinpoint why it is missing.

NameRequiredDescriptionDefault
titleYesThe title of the media to diagnose.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It discloses that the tool reads multiple sources (metadata, history, download client queues) and produces a diagnosis, which is useful. However, it doesn't disclose whether the tool performs any mutations (e.g., triggering searches, changing statuses), what the output format is, or whether it can take actions beyond diagnosis. The word 'Traces' suggests read-only, but that is not explicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the action and resources, no filler. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter diagnostic tool, the description is mostly complete. However, with no annotations and no output schema, an agent doesn't know whether the tool is read-only or may trigger actions, nor what the diagnosis result looks like. Given the tool's complexity (tracing through multiple systems), a bit more context about side effects or output would make it fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the only parameter 'title' is described as 'The title of the media to diagnose.' The description adds the context that the title refers to a movie, which is slightly more specific than the schema's 'media.' This is a minor addition; the schema already carries the meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Traces') and names the exact resources it inspects (Radarr metadata, history, active download client queues) and the goal (pinpoint why a movie is missing). This clearly distinguishes it from siblings like check_movie_status or manage_stalled_downloads.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies a diagnostic use case: when a movie is missing and the cause is unknown. It doesn't explicitly name alternatives or when-not-to-use, but the context of tracing through multiple sources makes the intended scenario clear. A small gap is not stating when to prefer check_movie_status or manage_stalled_downloads instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

execute_next_job_stepA

Processes a single sequential block item from an active background batch queue entry to prevent API flooding. (Jobs that have been started are also advanced automatically, one item per minute, by the job runner.)

NameRequiredDescriptionDefault
jobIdYesThe unique tracking ID of the active job array to step execute.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the disclosure burden. It usefully discloses that exactly one sequential block item is processed, that the job must be active, and that auto-advance already occurs. But it does not mention side effects on job state, error conditions, reversibility, or what happens when no steps remain.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The first sentence front-loads the action and purpose; the second adds relevant automatic-advancement context. Appropriately sized for a single-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple one-parameter tool, but with no annotations and no output schema, the description must do more. It explains what and why, but omits return/outcome details and side-effect behavior, leaving the agent with only partial context for a mutating action.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already fully describes jobId as the unique tracking ID of the active job array, so the baseline is 3. The description adds some contextual language around 'active' and 'block item' but does not materially extend the parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States precise behavior: processes a single sequential block item from an active background batch queue entry, with a clear rationale (prevent API flooding). This is specific enough to distinguish it from sibling read/manage tools like get_background_jobs and update_job_status, even without naming them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than explicit: the description suggests manual stepping exists to prevent API flooding, and notes that started jobs also auto-advance one item per minute. However, it does not state when not to use this tool or name an alternative explicitly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_series_by_qualityA

Finds TV shows by the video quality Sonarr downloaded: 'which shows do I only have in 720p?' (bestAtMost 720), 'which shows have 1080p or better?' (bestAtLeast 1080), 'which shows mix qualities?' (mixedOnly, useful as upgrade candidates). Lists the shows with the lowest best quality first, each with how many files are at each resolution, and opens with how many shows are at each level. It only sees what Sonarr downloaded, so a 4K copy in a separate Plex 4K library that Sonarr does not manage is not counted: for 4K use search_plex_library with library '4k'. Use folder to narrow to a kind of show by its Sonarr folder ('kids', 'anime', 'sports'). The first call reads every show's files (about 15 seconds) and is then cached for 5 minutes. Read-only.

NameRequiredDescriptionDefault
limitNoHow many shows to list (default 15, max 200).
folderNoOnly shows in a Sonarr folder whose path contains this text, e.g. 'kids', 'anime', 'sports'.
mixedOnlyNoOnly shows whose files are not all the same resolution.
monitoredNoOnly shows Sonarr monitors, only ones it does not, or both (default any).
bestAtMostNoOnly shows whose best quality is at most this many lines, e.g. 720.
bestAtLeastNoOnly shows whose best quality is at least this many lines, e.g. 1080 or 2160.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It discloses performance ('first call reads every show's files about 15 seconds'), caching ('cached for 5 minutes'), scope limitations (only Sonarr-downloaded content), and read-only nature. It does not specify permission requirements or pagination/return format details, but covers most behavioral traits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded: it begins with the core purpose and examples, then explains scope, output summary, performance, and read-only status in a logical flow. Every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given six optional parameters, no output schema, and no annotations, the description is quite complete: it covers purpose, usage, performance, caching, scope limits, and output summary. It could mention permission requirements or exact return format, but the key context for correct invocation is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds usage examples for parameters (bestAtMost 720, bestAtLeast 1080, mixedOnly as upgrade candidates) and folder narrowing ('kids', 'anime', 'sports'), which reinforce but do not significantly exceed the schema documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Finds TV shows by the video quality Sonarr downloaded') and immediately contextualizes with example questions. It distinguishes itself from siblings like search_plex_library by explicitly noting it only sees Sonarr-downloaded content and routing 4K searches elsewhere.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use examples ('which shows do I only have in 720p?'), explains parameter conditions (bestAtMost 720, bestAtLeast 1080, mixedOnly for upgrade candidates), and names a boundary with search_plex_library for 4K. Alternative and exclusion conditions are clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_series_gapsA

Lists the TV shows in Sonarr that are missing aired episodes, most missing first, with how many are downloaded, whether Sonarr is monitoring each show, and whether it is actively looking for the rest. Use it for 'which of my shows have gaps?', 'what am I missing?' or 'which shows are only missing a few episodes?'. Use monitored 'searching' for 'what is Sonarr still looking for?'. Express any narrowing as a filter (monitored, minMissing, maxMissing, hideEmpty) rather than filtering the result yourself, because the table shown to the user is exactly the rows returned. Most gaps are in shows that are deliberately not monitored or only partly kept; 'hideEmpty' drops shows with nothing downloaded and 'maxMissing' finds near-complete ones. For one show use check_series_completeness.

NameRequiredDescriptionDefault
limitNoHow many shows to list (default 15, max 200).
hideEmptyNoSkip shows with no episodes downloaded at all.
monitoredNoOnly shows Sonarr is monitoring, only ones it is not, only ones it is actively searching missing episodes for ('searching'), or all (default any).
maxMissingNoOnly shows missing at most this many episodes, e.g. 5 for nearly complete shows.
minMissingNoOnly shows missing at least this many episodes.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses sort order, which per-show fields come back, and the important operational constraint that the returned rows are exactly what the user sees, so narrowing must happen server-side via filters. It omits any statement about permissions or read-only nature, but the read semantics are unambiguous from the wording.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose and output shape before the query examples and filter rationale. Dense and mostly waste-free, though the interpretation guidance ('Most gaps are in shows that are deliberately not monitored...') is slightly more editorial than needed for tool selection.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates by enumerating the columns returned and the ordering. Combined with the filter-selection guidance and the sibling handoff, an agent has enough to invoke and interpret this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is already 100%, so the baseline is 3, but the description adds genuine intent beyond the schema: 'hideEmpty' is framed as dropping shows with nothing downloaded and 'maxMissing' as finding near-complete shows, and it explains why filtering should be done here rather than on the result set. That is meaning the schema alone does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Lists the TV shows in Sonarr that are missing aired episodes') plus ordering ('most missing first') and the per-row payload (downloaded count, monitoring state, searching state). It names the sibling check_series_completeness for the single-show case, so an agent can separate it from adjacent tools without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete user-intent triggers ('which of my shows have gaps?', 'which shows are only missing a few episodes?') and explicitly routes the 'what is Sonarr still looking for?' case to the monitored='searching' variant, plus points to check_series_completeness for one show. When-to-use and the alternative path are both spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_background_jobsA

Retrieves active, pending, or completed persistent media processing jobs running on the server cluster.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden, but it does not disclose behaviors like whether this is read-only (it implies retrieval, so likely safe), how results are ordered, or if there are any side effects. The description is clear about the action (retrieves) but lacks depth on return format or filtering, though the tool has no parameters.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that front-loads the verb and resource, with no wasted words. It is appropriately sized for a simple tool with no parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no parameters and no output schema, the description is nearly complete. It specifies what it retrieves (jobs) and their states, but could mention whether it returns a list or counts, though without an output schema, the description does enough to guide basic usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, and the description covers the full schema (100% coverage with no properties). The description clarifies the scope (server cluster) and job states, adding meaning beyond the empty schema, which justifies a score above the baseline for no params.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves media processing jobs, specifying the job states (active, pending, completed) and the resource (persistent media processing jobs on the server cluster). It distinguishes from siblings like get_plex_activity or get_library_analytics, though it does not explicitly name them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool—when you need to check on media processing jobs—but does not explicitly contrast with siblings like update_job_status or execute_next_job_step. No exclusions or alternative conditions are stated, but the context is clear enough for most agents.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_cluster_hardware_analyticsA

Fetches real-time CPU load and memory allocation for every configured cluster host over SSH, as a Markdown table.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It does disclose that the tool connects over SSH and returns a Markdown table, which is useful. However, it does not mention potential side effects, authentication requirements, latency implications, or what happens if SSH fails. The description is honest but incomplete on behavioral traits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that front-loads the core purpose (real-time CPU load and memory allocation), specifies the scope (every configured cluster host), the method (over SSH), and the output format (Markdown table). Every element earns its place with zero waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with no output schema, the description covers the main purpose and output format. However, it lacks context about failure modes, authentication prerequisites, or how this relates to sibling tools like get_cluster_infrastructure_health. An agent might not know when to prefer this over the infrastructure health tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema provides no parameter semantics to cover. The description compensates by explaining what data is fetched and how it is presented. With no parameters, the baseline is 4, and the description adds meaningful context about the tool's behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool fetches real-time CPU load and memory allocation for every configured cluster host over SSH, and specifies the output format as a Markdown table. This is a specific verb+resource combination that distinguishes it from siblings like get_cluster_infrastructure_health, which likely covers broader health metrics.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context (real-time hardware monitoring for cluster hosts) but does not explicitly state when to use this tool versus alternatives like get_cluster_infrastructure_health. There is no mention of when not to use it or what conditions would make a sibling tool more appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_cluster_infrastructure_healthA

Collects real-time CPU utilization, RAM usage, and active Docker container counts across all configured Ubuntu hosts.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral disclosure burden. It does disclose that data is real-time, scoped to all configured Ubuntu hosts, and limited to CPU, RAM, and Docker container counts. It does not explicitly state whether the operation is read-only, describe potential side effects, error conditions, or output shape, so some behavioral detail is still missing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single well-structured sentence conveys the action, the data collected, and the scope. Every word contributes meaning, and the most important information is front-loaded. No filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-style monitoring tool, the description is largely complete: it names the exact metrics and host scope. The main gap is the lack of explicit return-format or usage-context details, but the low complexity of this tool means an agent can reasonably infer how to invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so per the rubric the baseline is 4. The description appropriately focuses on what data is collected rather than parameter details, since there is no input schema to clarify.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Collects') and a specific resource ('cluster infrastructure health') with concrete metrics: CPU utilization, RAM usage, and active Docker container counts. It is clear and likely distinguishable from get_cluster_hardware_analytics, though it does not explicitly name the sibling or draw the contrast.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage: call this when you need real-time resource metrics across the Ubuntu hosts. However, it provides no explicit guidance about when to prefer this tool over related siblings like get_cluster_hardware_analytics or check_indexer_health, and no exclusions or alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_library_analyticsA

Queries historical statistics regarding most watched movies, total user count, and overall watch metrics.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries the full burden. It indicates a read-only operation via 'Queries' and clarifies the data is historical aggregate statistics, but it does not disclose output structure, pagination, or authorization requirements. It is adequate for a simple query tool but leaves behavioral details unspecified.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler. Every clause contributes specific metrics or scope, making it efficient and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter analytics query with no output schema, the description gives the main return categories and scope, which is reasonably complete. It could specify the time window or output format, but the low complexity makes the current description sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters and 100% description coverage, and the tool takes no arguments. Per the 0-parameter baseline, this is a 4; there is no parameter semantics for the description to add.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Queries') and names the resource ('historical statistics') with concrete content examples: most watched movies, total user count, and overall watch metrics. It is clear and distinguishes itself from siblings like get_cluster_hardware_analytics by subject matter, though it does not explicitly contrast with any sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when historical library analytics are needed, but it provides no explicit when-to-use or when-not-to-use guidance and does not mention alternatives such as get_plex_activity or get_cluster_hardware_analytics. The context is understandable, but the guidance is indirect.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_on_deckA

Answers 'what should I watch next?' from Plex's On Deck ('Continue Watching'): the movies the user has partly played and, for each show they are following, the episode to watch next (or the one they are part way through), most recently active first, with how far through each one is. A movie held in HD and 4K is one entry. Use title for 'which episode is next for ?' and mediaType 'show' for 'which episode is next in each show?'. IMPORTANT: On Deck is only Plex's short recent list (at most 50 items across everything), not every unfinished title, so for 'which movies did I start but not finish?', 'what haven't I finished?' or any complete list use search_plex_library with watched 'inProgress' instead. The watch state is for the Plex account the app is connected with.

NameRequiredDescriptionDefault
limitNoHow many to list (default 10, max 50).
titleNoOnly a movie or show whose title contains this text, e.g. 'Dark Matter'.
libraryNoOnly Plex libraries whose name contains this text, e.g. 'kids', '4k'.
mediaTypeNoOnly movies, only shows' next episodes, or both (default any).

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses ordering (most recently active first), a hard cap (at most 50 items across everything), deduplication (movie in HD and 4K is one entry), and the auth/scope of watch state (the connected Plex account). It stops short of stating the read-only nature or error behavior, which is a minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose and the routing constraint are front-loaded and information-dense, with no filler. It is somewhat long, and the three quoted user-phrasings ('what haven't I finished?', etc.) restate the same routing point, which is mild redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter, no-output-schema query tool this is complete: the description tells the agent what is returned (how far through each entry), how results are ordered, how they are capped, and when to route elsewhere, so nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3; the description adds value by mapping filters to user intents ('Use title for which episode is next for <show>?') and clarifying what mediaType 'show' returns, beyond the schema's terse enum text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('answers what should I watch next from Plex's On Deck') and precisely defines the resource — partly played movies plus next/partial episode per followed show. It is clearly distinguishable from search_plex_library and other siblings by naming the alternative explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use mappings ('Use title for which episode is next for <show>?', mediaType 'show' for next episode in each show) and an explicit when-NOT-to-use with the named alternative (search_plex_library with watched 'inProgress') for complete unfinished lists. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_plex_activityA

Fetches real-time playback streaming analytics from Plex via Tautulli to monitor user context and transcoding strain.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must disclose behavioral traits. It states the tool 'fetches' data, implying a read operation, but does not explicitly say it is read-only, mention any side effects, rate limits, authentication requirements, or what happens if Tautulli is unavailable. It also doesn't clarify the output structure or that it returns current sessions only. This leaves significant gaps for an agent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that front-loads the primary action and purpose without any redundant filler. Every phrase adds value, and it is appropriately concise for a simple parameterless tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no parameters and no output schema, the description is the sole source of context about the return value and limitations. It says it fetches 'analytics' but does not describe the shape of the response (e.g., list of active sessions, per-user details). For an agent to know what to do with the result, more detail on the return would be helpful. Still, the tool is simple enough that the current description is minimally viable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has 0 parameters, and the schema is empty. Per the rubric, 0 parameters sets a baseline of 4. The description adds no parameter information (since there are none), and no compensation is needed because the schema already fully covers the parameter surface.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Fetches'), names a clear resource ('real-time playback streaming analytics from Plex via Tautulli'), and states the purpose ('to monitor user context and transcoding strain'). This distinguishes it from siblings like get_library_analytics, which focus on broader analytics, and check_movie_status, which checks individual titles.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by mentioning the monitoring purpose, but it does not explicitly state when to use this tool over alternatives or provide exclusions. No mention of siblings or conditions like 'use this for live streams, use get_library_analytics for historical data'. The purpose gives some context but falls short of clear guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_upcoming_episodesA

What TV episodes are coming, from Sonarr's calendar. With no title it answers 'what's on this week?': every episode airing in the next few days (default 7, up to 60) from the shows Sonarr monitors, by day, with season premieres and finales flagged and episodes already downloaded marked. With a title it answers 'when does come back?': that show's next episodes, or that none is scheduled yet (or that it has ended). Only shows Sonarr monitors are listed by default and the number left out is reported; use monitored 'unmonitored' when the user asks about shows they do not monitor, or 'any' for everything (express that as the filter, because the table shown to the user is exactly the rows returned). Dates are the network's own air dates.

NameRequiredDescriptionDefault
daysNoHow many days ahead to list when no title is given (default 7, max 60).
yearNoFirst air year, only needed to tell same-named shows apart.
titleNoA show to ask about instead, e.g. 'Severance': its next episodes or that none is scheduled.
monitoredNoOnly shows Sonarr monitors (default), only ones it does not monitor, or all.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does substantial work: default 7-day window capped at 60, only monitored shows returned by default with the excluded count reported, seasons premieres/finales/ downloaded state flagged, and the warning that the returned rows are exactly what the user sees. It omits explicit read-only confirmation, pagination behavior, and auth needs, but adds real context beyond any structured field.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose and the default-mode answer are front-loaded, and each sentence carries operational content rather than filler. It is dense and somewhat long, but nothing reads as redundant padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, yet the description explains the return shape (grouped by day, premieres/finales flagged, already-downloaded marked) and the default filter semantics. An agent has enough to answer correctly without probing further.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaning: how 'days' interacts with the no-title mode, what 'title' returns when nothing is scheduled, why 'year' disambiguates same-named shows, and the operational reason the monitored filter must reflect the exact filter used. That is genuine value beyond the schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('What TV episodes are coming, from Sonarr's calendar') and cleanly separates two modes: a calendar view by default and a per-show lookup when a title is given. It does not name or contrast with any sibling such as get_on_deck, search_episodes, or check_series_status, so it falls short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit use conditions for both modes ('what's on this week?' without a title; 'when does <show> come back?' with one) and prescribes exactly when to use each monitored filter value. It stops short of pointing to alternative tools for adjacent questions, so context is clear but alternatives are unnamed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

manage_stalled_downloadsA

Lists qBittorrent downloads that are stalled or slower than a threshold (AUDIT), and deletes chosen ones with their downloaded files (PURGE_STALLED). PURGE_STALLED only deletes the torrents whose hashes you pass, taken from an AUDIT the user has seen and agreed to; it never deletes anything else, and Radarr and Sonarr are not told.

NameRequiredDescriptionDefault
actionYesAUDIT lists stalled downloads with their hashes and changes nothing; PURGE_STALLED deletes the torrents named in hashes, with their files.
hashesNoPURGE_STALLED only: the hashes, from AUDIT, of the torrents the user agreed to delete. Required for PURGE_STALLED.
minSpeedKbpsNoA download slower than this (KB/s) counts as stalled, as does one qBittorrent reports as stalled.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: it discloses that AUDIT changes nothing, that PURGE_STALLED deletes only the passed hashes and never anything else, deletes downloaded files too, and explicitly notes Radarr/Sonarr are not notified. This is the key behavioral context an agent needs before a destructive operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences front-load the read/write split and the safety constraint; only a minor amount of repetition between the action enum description and the top-level description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations and no output schema, the description supplies exactly the missing behavioral and safety context: read-vs-write modes, deletion scope, file removal, and absence of *arr notifications. Nothing essential for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents action, hashes, and minSpeedKbps in detail. The description reinforces that hashes come from AUDIT and are required for PURGE_STALLED, but adds little beyond the schema on the threshold semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States precise verbs and resources for both modes: lists stalled/slow downloads (AUDIT) and deletes chosen ones with files (PURGE_STALLED). The dual-mode action is made explicit, and the description distinguishes itself from the many sibling tools focused on media status, search, and infrastructure.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly directs that PURGE_STALLED should only be used with hashes from a user-agreed AUDIT, giving a strong precondition. It does not name alternatives or state when not to use the tool, but the audit-then-purge workflow is well spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

plan_media_upgradeC

Evaluates and safely schedules a controlled batch upgrade for specified media classes while enforcing storage policies.

NameRequiredDescriptionDefault
mediaTypeYesThe structural classification targeting upgrades.
maxBatchSizeNoLimits the maximum number of edits in a single batch (1 to 100).
targetResolutionYesThe target processing quality resolution threshold.

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It gestures at safety ('safely', 'controlled batch', 'enforcing storage policies') but never clarifies whether the tool mutates state or only produces a plan, what happens on execution, or what constraints (permissions, reversibility) apply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single, front-loaded sentence with the verb leading and no filler. It is efficient, though the terseness contributes to the gaps in the other dimensions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no annotations and no output schema, the description must explain what the tool returns and how a 'plan' relates to execution, and it does not. The core ambiguity of whether this only evaluates/schedules or actually performs the upgrade is left unresolved for a tool whose name centers on planning.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters (mediaType, maxBatchSize, targetResolution) are already documented with enums and bounds in the schema. The description adds only the vague phrase 'specified media classes', providing no syntax or format detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource ('schedules a controlled batch upgrade for specified media classes'), which is clearer than a bare name restatement. However it does not distinguish the tool from related siblings like find_series_by_quality or diagnose_missing_media, leaving the agent to infer the planning/evaluation angle.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no mention of prerequisites, and no routing to or away from any sibling tool. The phrase 'for specified media classes' implies scope but gives the agent no condition under which this tool should be chosen over others.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolve_actor_filmographyA

Resolves an actor's name to their official TMDb filmography (movies and TV shows), filtering out talk shows, news, self-appearances, and uncredited roles. When Plex is configured, marks which of those titles the user already has in their Plex library and which they don't. Use this to answer which of an actor's movies or shows the user is missing. Pass mediaType 'movie' when the user asks about movies/films, 'show' for TV/series, and leave it out (any) when the question is about the actor's work in general; keep the same mediaType on follow-ups.

NameRequiredDescriptionDefault
showNoOnly titles the user has in Plex ('owned'), only those they don't ('missing'), or both (default).
limitNoHow many titles to list, newest first (default 15).
yearToNoOnly titles released in or before this year.
libraryNoJudge ownership only against Plex libraries whose name contains this text, e.g. '4k': 'owned' then means held in a 4K library and 'missing' means not held in any.
yearFromNoOnly titles released in or after this year.
actorNameYesThe exact name of the actor (e.g., 'Harrison Ford').
mediaTypeNoOnly movies, only TV shows, or both (default any).

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the exclusions (talk shows, news, self-appearances, uncredited roles) and that Plex ownership marking is conditional on Plex being configured. It omits failure modes, rate limits, and permissions, which keeps it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then filtering, then Plex behavior, then usage guidance. Dense but every sentence is load-bearing; only the mediaType sentence runs slightly long.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter tool with no annotations and no output schema, the description covers intent, filtering, ownership semantics, and the key enum choice. Remaining parameter detail (yearFrom, limit, library, show) is handled by the complete schema, so nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description adds genuine meaning by prescribing mediaType values per question phrasing ('movie' for films, 'show' for series, omit for general work) and reinforcing consistency on follow-ups.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Resolves an actor's name to their official TMDb filmography') plus the scope (movies and TV shows) and filtering behavior. No sibling tool covers actor filmography, so the agent can place it precisely.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit use case ('answer which of an actor's movies or shows the user is missing') and detailed mediaType selection guidance including follow-up behavior. It does not name a when-not condition or a competing alternative, but its function is fairly unique among siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_cluster_backupA

Asks each configured Servarr app (Radarr, Sonarr, Prowlarr) to create its built-in database backup, waits for each to finish, and confirms a new backup file appeared, reporting the file's name, size and time. The backups stay in each app's own backup folder; nothing is copied.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations are absent, so the description carries the whole burden. It discloses that it waits for completion, verifies a new backup file, reports file metadata, leaves backups inside app folders, and copies nothing. It does not mention failure modes or authorization requirements, but the core behavior is transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The action is front-loaded, the waiting behavior is clarified, and the non-copying boundary is stated at the end. Every sentence contributes useful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-input, no-output-schema tool, this description is complete: it states target apps, action, synchonization behavior, verification step, return details, and side-effect boundary. No important invocation information appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema already covers everything. The description adds useful context by defining the scope ('each configured Servarr app'), and no parameter clarification is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('asks... to create'), the resource ('built-in database backup' for each Servarr app), and the observable outcome (waiting, confirming, reporting file name/size/time). This clearly distinguishes it from siblings like manage_stalled_downloads or get_plex_activity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit alternative or 'use instead' guidance, but the context is unmistakable: use when you need each configured Servarr app to create a database backup and verify it. No sibling tool appears to compete for the same operation, so missing exclusions is a minor gap, not a critical one.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_and_select_moviesA

Searches TMDb for matching movies and renders a structured Markdown multi-choice grid interface for confirmation.

NameRequiredDescriptionDefault
queryYesThe film name or fuzzy query text to search for (e.g. 'Heat').

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries the full burden. It discloses a key behavior: rendering a Markdown multi-choice grid for confirmation, which goes beyond a simple search. However, it does not mention potential side effects, user interaction flow, or whether it blocks pending confirmation. This is adequate but not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, efficient sentence that front-loads the primary action ('Searches TMDb') and follows with the output behavior. No wasted words; every phrase contributes meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one parameter and no output schema, the description is complete enough to understand its purpose and behavior. It explains the search and the confirmation grid. It does not detail what happens after confirmation, but this is a minor gap given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides 100% coverage for the only parameter (query), including a description and example. The tool description adds no further semantics about the parameter beyond restating the search action, so it meets the baseline without extra value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action: searching TMDb for movies, and the specific output: a Markdown multi-choice grid for confirmation. It distinguishes this tool from siblings like check_movie_status or get_plex_activity by its search-and-select nature.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is used when you need to search for a movie and let the user confirm a selection, but it does not explicitly contrast it with alternatives or state when not to use it. No explicit exclusions or comparisons are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_episodesA

Finds individual TV episodes in the user's Plex library: 'the episode of where ...', 'which episode is called ...', episodes that aired in a date range, a show's season premieres or finales. IMPORTANT: Plex cannot search episode plots across the whole library. To search PLOTS (summaries) you must name the show (the show argument); the words then match the episode title and its plot. Without a show, only episode TITLES (and air dates) can be searched. When the user describes an episode by its plot and no show is known, ask which show or say only titles can be searched. Use season and episode for a specific one, airedFrom/airedTo (YYYY-MM-DD) for 'aired in March 2026', and episodeType 'premiere' or (with a show) 'finale'. Each result shows the show, season and episode numbers, air date and watch state.

NameRequiredDescriptionDefault
showNoA show to search inside, e.g. 'Entourage'. Required to search plots.
textNoWords that must all appear in the episode title (and, with a show, its plot).
limitNoHow many to list (default 15, max 100).
seasonNoOnly this season.
airedToNoAired on or before this date, YYYY-MM-DD.
episodeNoOnly this episode number (needs season).
libraryNoWithout a show: only show libraries whose name contains this text, e.g. 'kids'.
airedFromNoAired on or after this date, YYYY-MM-DD.
episodeTypeNoOnly season premieres, or season finales (needs a show).

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden, and it does so well by disclosing the non-obvious constraint that Plex cannot search episode plots library-wide and that plot search requires naming the show. It also states what each result contains (show, season/episode numbers, air date, watch state). It omits any pagination/truncation guidance beyond limit, keeping it out of the top tier.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and its flagship example queries are front-loaded, and the critical plot-search limitation is flagged with 'IMPORTANT' before param guidance. It is dense and slightly long, but nearly every sentence carries actionable content; no major redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter, zero-required tool with no output schema and no annotations, the description covers the essential gaps: the plot-vs-title search constraint, per-parameter usage, the fallback behavior, and the result shape. It is complete enough to invoke correctly, with only minor gaps around result volume/pagination handling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning: it maps airedFrom/airedTo to natural queries ('aired in March 2026'), explains episodeType 'premiere'/'finale' semantics including the show dependency for 'finale', and clarifies season+episode pairing for a specific episode. This is more than the schema restates.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('finds') and resource ('individual TV episodes in the user's Plex library') and immediately disambiguates scope with several example natural-language queries. An agent can distinguish this from siblings like search_plex_library, search_and_select_movies, and get_upcoming_episodes without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use conditions (plot search, title search, date-range membership, premieres/finales) and a clear when-not fallback: 'When the user describes an episode by its plot and no show is known, ask which show or say only titles can be searched.' It stops short of naming specific alternative sibling tools, so it lacks the explicit routing of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_plex_libraryA

Searches the movies and TV shows actually in the user's Plex library (across all movie and show libraries, including 4K) by genre, actor, title, release year, and/or library. Filters can be combined, e.g. genre 'Horror' with year 1982, or genre 'Horror' with library '4k'. Pass mediaType 'movie' when the user asks about movies/films, 'show' for TV/series/shows, and leave it out (any) when the question is about titles in general, e.g. everything with an actor; a show in several libraries is one result, with its season and episode counts. Some libraries (such as Sports) may be left out unless named in the library filter. Use this to answer what the user owns or can watch; use check_movie_status for Radarr/download status of one specific movie. Watch state: use watched 'unwatched' (never played), 'inProgress' (started but not finished - this is the complete list of unfinished titles, unlike get_on_deck's short recent list) or 'watched' (finished), and notWatchedInYears for 'haven't watched in N years' (a never-watched title counts from when it was added); they are for the Plex account the app is connected with. sort orders by recentlyAdded, lastWatched or leastRecentlyWatched instead of by title. Also filter by network (or movie studio), contentRating (TV-MA, R...), minRating (audience rating 0-10), yearFrom/yearTo (a decade is 1990 to 1999) and addedWithinDays ('what showed up this week?'). Plex does not know whether a show is continuing or ended; use Sonarr tools for that. Always express a narrowing the user asks for (4K, a genre, a year, unwatched...) as a filter here rather than filtering results yourself, because the results table shown to the user contains exactly the rows this returns. The default limit is small: when the user wants everything ('all', 'every', 'list them'), pass limit 500; if the reply says more matches remain, call again with the offset it gives.

NameRequiredDescriptionDefault
sortNoOrder the results (default title).
yearNoRelease year (a show's first air year).
actorNoFull actor name, e.g. 'Harrison Ford'.
genreNoGenre name, e.g. 'Horror' or 'Science Fiction'.
limitNoMaximum results to return (default 25, max 500).
titleNoPart of the movie or show title.
offsetNoMatches to skip, to fetch the next page of a long result.
yearToNoReleased in or before this year.
libraryNoOnly search Plex libraries whose name contains this text, e.g. '4k' for the 4K libraries, 'kids', 'anime', 'sports'.
networkNoTV network (shows) or studio (movies), e.g. 'HBO', 'Netflix'.
watchedNoOnly titles never played, started but not finished, or finished.
yearFromNoReleased in or after this year (a decade: 1990 to 1999).
mediaTypeNoSearch only movies, only TV shows, or both (default any).
minRatingNoAudience rating of at least this (0-10).
contentRatingNoContent rating, e.g. 'TV-MA', 'PG-13', 'R'.
addedWithinDaysNoAdded to Plex within this many days.
notWatchedInYearsNoOnly titles not watched for this many years (a never-watched title counts from when it was added).

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the default small limit, the pagination flow (offset, 'more matches remain'), that a show in multiple libraries is deduplicated into one result, that some libraries are excluded unless named, and that watch state maps to the connected Plex account. It omits auth/permission requirements and error behavior, so it stops short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and routing, then details; every part is dense with usable information. It is a single long block rather than a scannable structure and repeats several things already in the schema (network/contentRating/minRating examples, sort enum values, decade hint), which costs it the top score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 17-parameter tool with no output schema and no annotations, the description is unusually complete: it explains the shape of returned rows (one row per title, season/episode counts), the pagination contract, library inclusion quirks, and how filters combine. Nothing an agent needs to call it correctly appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning beyond the schema: how mediaType should be chosen from user phrasing, the semantic split of watched values, that notWatchedInYears counts never-watched titles from their add date, that a decade is expressed as yearFrom/yearTo, and that limit 500 should be passed for 'all/every' requests.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Searches the movies and TV shows actually in the user's Plex library') and scopes it to owned content. It explicitly distinguishes itself from siblings: check_movie_status for Radarr/download status, Sonarr tools for continuing/ended status, and get_on_deck for recent unfinished items.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Extensive when-to-use routing: mediaType mapping for movie/show/any queries, watched vs inProgress vs watched usage, when to use notWatchedInYears, and a direct instruction to express any narrowing as a filter here rather than post-filtering. It also names alternatives for adjacent queries.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

trust_new_host_keyA

Forgets the remembered SSH key of a monitored host so the next check trusts the key it presents now. Only for a host the user rebuilt or reinstalled: an unexpected key change can mean another machine is impersonating it. Confirm with the user first.

NameRequiredDescriptionDefault
hostYesThe host exactly as configured in UBUNTU_HOSTS, e.g. 192.168.1.10 or host:2222.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it explains the actual mechanism (the old key is forgotten, the next check accepts whatever key is presented) and flags the security risk and the need for user confirmation. It stops short of stating reversibility, required privileges, or any response behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences: purpose first, then the narrow applicability condition, then the safety caution. No redundancy and nothing that fails to earn its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter tool with full schema coverage and no output schema, the description covers purpose, preconditions, and the risk/confirmation requirement. Minor gaps: no statement of what is returned or whether the operation can be undone.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the sole 'host' parameter is documented in-schema with format examples ('192.168.1.10 or host:2222'). The description adds no additional parameter meaning, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb and resource ('Forgets the remembered SSH key') plus the downstream effect ('so the next check trusts the key it presents now'), which resolves the ambiguity in the tool name 'trust_new_host_key'. It does not distinguish itself from siblings, but the sibling list is entirely media/cluster-job tooling, so differentiation is largely moot.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly scopes use to 'a host the user rebuilt or reinstalled' and adds a when-not signal via the impersonation warning ('an unexpected key change can mean another machine is impersonating it'), plus a required workflow step ('Confirm with the user first'). This is textbook usage guidance for an agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_job_statusA

Updates the operational state of an active or pending background batch job.

NameRequiredDescriptionDefault
jobIdYesThe unique ID of the target job
actionYesThe action to execute on the queue runtime.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It indicates the tool mutates job state, but does not disclose potential side effects (e.g., whether CANCEL is irreversibly destructive, or whether PAUSE/RESUME have any queuing effects). It also doesn't mention any permissions or whether actions are reversible. For a mutation tool, this is a moderate gap, but the action enum provides some clarity for the agent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that is front-loaded with the purpose. It avoids fluff and is easy to scan, which is ideal for an agent's prompt context.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 2-parameter tool with a clear schema, the description is mostly sufficient. However, given no annotations and no output schema, it could benefit from stating the expected response (e.g., success/failure indicators) or any constraints (e.g., actions only on active/pending jobs). The description is adequate but leaves some behavioral context unclear.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers 100% of parameters with descriptions for jobId and action, including an enum for action. The description adds minimal extra meaning beyond the schema—it just restates that these actions operate on operational state. Baseline 3 is appropriate as the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Updates the operational state of an active or pending background batch job.' It specifies a verb (updates), a resource (operational state of a job), and the scope (active or pending). It distinguishes from siblings like get_background_jobs (which likely reads) but does not explicitly differentiate from other update tools like execute_next_job_step or manage_stalled_downloads, though the specific action set (PAUSE/RESUME/CANCEL) is implied.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implicitly indicates usage: to change the state of an active or pending job, not for completed jobs. It does not explicitly state when to use this tool versus alternatives like execute_next_job_step (which might advance a job) or manage_stalled_downloads (which might handle stalled jobs). No explicit exclusions or alternative routing is provided, so guidance is adequate but not explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv1.4.0
    • Changedmanage_stalled_downloads4 fields changed
      • changedInput schema / properties / action / description
        Previous value: -"AUDIT returns stalled candidates; PURGE_STALLED wipes them and flags a re-search."New value: +"AUDIT lists stalled downloads with their hashes and changes nothing; PURGE_STALLED deletes the torrents named in hashes, with their files."
      • addedInput schema / properties / hashes
        Added value: +{
        +  "description": "PURGE_STALLED only: the hashes, from AUDIT, of the torrents the user agreed to delete. Required for PURGE_STALLED.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • changedInput schema / properties / minSpeedKbps / description
        Previous value: -"The minimum allowed speed threshold before a torrent is considered stalled."New value: +"A download slower than this (KB/s) counts as stalled, as does one qBittorrent reports as stalled."
      • addedInput schema / properties / minSpeedKbps / minimum
        Added value: +0
    • Changedplan_media_upgrade4 fields changed
      • changedInput schema / properties / maxBatchSize / description
        Previous value: -"Limits the maximum number of edits in a single batch."New value: +"Limits the maximum number of edits in a single batch (1 to 100)."
      • addedInput schema / properties / maxBatchSize / maximum
        Added value: +100
      • addedInput schema / properties / maxBatchSize / minimum
        Added value: +1
      • changedInput schema / properties / maxBatchSize / type
        Previous value: -"number"New value: +"integer"
    • Addedtrust_new_host_key
  2. 10 tool updatesv1.2.0
    • Addedcheck_series_completeness
    • Addedcheck_series_status
    • Addeddiagnose_missing_episodes
    • Addedfind_series_by_quality
    • Addedfind_series_gaps
    • Addedget_on_deck
    • Addedget_upcoming_episodes
    • Changedresolve_actor_filmography1 field changed
      • addedInput schema / properties / mediaType
        Added value: +{
        +  "description": "Only movies, only TV shows, or both (default any).",
        +  "enum": [
        +    "movie",
        +    "show",
        +    "any"
        +  ],
        +  "type": "string"
        +}
    • Addedsearch_episodes
    • Changedsearch_plex_library13 fields changed
      • addedInput schema / properties / addedWithinDays
        Added value: +{
        +  "description": "Added to Plex within this many days.",
        +  "exclusiveMinimum": 0,
        +  "type": "number"
        +}
      • addedInput schema / properties / contentRating
        Added value: +{
        +  "description": "Content rating, e.g. 'TV-MA', 'PG-13', 'R'.",
        +  "type": "string"
        +}
      • changedInput schema / properties / library / description
        Previous value: -"Only search Plex libraries whose name contains this text, e.g. '4k' for the 4K libraries, 'kids', 'documentaries'."New value: +"Only search Plex libraries whose name contains this text, e.g. '4k' for the 4K libraries, 'kids', 'anime', 'sports'."
      • addedInput schema / properties / mediaType
        Added value: +{
        +  "description": "Search only movies, only TV shows, or both (default any).",
        +  "enum": [
        +    "movie",
        +    "show",
        +    "any"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / minRating
        Added value: +{
        +  "description": "Audience rating of at least this (0-10).",
        +  "maximum": 10,
        +  "minimum": 0,
        +  "type": "number"
        +}
      • addedInput schema / properties / network
        Added value: +{
        +  "description": "TV network (shows) or studio (movies), e.g. 'HBO', 'Netflix'.",
        +  "type": "string"
        +}
      • addedInput schema / properties / notWatchedInYears
        Added value: +{
        +  "description": "Only titles not watched for this many years (a never-watched title counts from when it was added).",
        +  "exclusiveMinimum": 0,
        +  "type": "number"
        +}
      • addedInput schema / properties / sort
        Added value: +{
        +  "description": "Order the results (default title).",
        +  "enum": [
        +    "title",
        +    "recentlyAdded",
        +    "lastWatched",
        +    "leastRecentlyWatched"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / title / description
        Previous value: -"Part of the movie title."New value: +"Part of the movie or show title."
      • addedInput schema / properties / watched
        Added value: +{
        +  "description": "Only titles never played, started but not finished, or finished.",
        +  "enum": [
        +    "unwatched",
        +    "inProgress",
        +    "watched"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / year / description
        Previous value: -"Release year."New value: +"Release year (a show's first air year)."
      • addedInput schema / properties / yearFrom
        Added value: +{
        +  "description": "Released in or after this year (a decade: 1990 to 1999).",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedInput schema / properties / yearTo
        Added value: +{
        +  "description": "Released in or before this year.",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
  3. 3 tool updatesv1.1.0
    • Changedconfirm_selected_choices2 fields changed
      • addedInput schema / properties / qualityProfile
        Added value: +{
        +  "description": "Radarr quality profile name to use instead of the default.",
        +  "type": "string"
        +}
      • addedInput schema / properties / rootFolder
        Added value: +{
        +  "description": "Radarr root folder path to add to instead of the first one (e.g. '/media/movieskids').",
        +  "type": "string"
        +}
    • Changedresolve_actor_filmography5 fields changed
      • addedInput schema / properties / library
        Added value: +{
        +  "description": "Judge ownership only against Plex libraries whose name contains this text, e.g. '4k': 'owned' then means held in a 4K library and 'missing' means not held in any.",
        +  "type": "string"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "description": "How many titles to list, newest first (default 15).",
        +  "maximum": 100,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / show
        Added value: +{
        +  "description": "Only titles the user has in Plex ('owned'), only those they don't ('missing'), or both (default).",
        +  "enum": [
        +    "all",
        +    "owned",
        +    "missing"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / yearFrom
        Added value: +{
        +  "description": "Only titles released in or after this year.",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedInput schema / properties / yearTo
        Added value: +{
        +  "description": "Only titles released in or before this year.",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
    • Addedsearch_plex_library
  4. 16 tool updatesv1.0.0
    • First observedcheck_indexer_health
    • First observedcheck_movie_status
    • First observedconfirm_selected_choices
    • First observeddiagnose_missing_media
    • First observedexecute_next_job_step
    • First observedget_background_jobs
    • First observedget_cluster_hardware_analytics
    • First observedget_cluster_infrastructure_health
    • First observedget_library_analytics
    • First observedget_plex_activity
    • First observedmanage_stalled_downloads
    • First observedplan_media_upgrade
    • First observedresolve_actor_filmography
    • First observedrun_cluster_backup
    • First observedsearch_and_select_movies
    • First observedupdate_job_status

TDQS

A3.7/5.0

Scored across 26 tools

Disambiguation4/5

Most tools are clearly separated by their descriptions, especially across Plex discovery, Sonarr episode diagnostics, Radarr movie status, and job control. However, get_cluster_infrastructure_health and get_cluster_hardware_analytics overlap heavily, and the background job tools require careful reading to distinguish retrieval, update, and step execution.

Naming Consistency5/5

All tool names use snake_case and overwhelmingly follow predictable verb_noun or verb_noun_phrase patterns such as check_*, get_*, find_*, diagnose_*, and search_*. Minor outliers like get_on_deck and search_and_select_movies remain readable and do not break the overall convention.

Tool Count3/5

At 26 tools, the surface is heavy and sits just above the rubric's 25+ 'too many' threshold. The broad server scope across Plex, Radarr, Sonarr, Prowlarr, qBittorrent, cluster infrastructure, and background jobs justifies many tools, but some consolidation—especially around cluster metrics and job control—would improve scoping.

Completeness3/5

The server covers diagnostics, status checks, search, backups, and movie-addition workflows well, but there are notable lifecycle gaps. There is no tool to add or monitor TV series, no general update/delete capability for Radarr/Sonarr/Plex items, and no media removal beyond stalled torrents.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables full management of a Plex Media Server via Claude, including browsing libraries, fixing metadata, managing collections, and more.
    -
  • F
    license
    A
    quality
    D
    maintenance
    Exposes homelab and IT-ops tools to Claude, including system health monitoring, Grafana alert states, Docker container status, Loki logs, SMART disk health, and more.
    8
    1
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables control of a home lab through a single MCP server, exposing tools for Home Assistant, Portainer, Sonarr, Radarr, SABnzbd, and Jellyfin so Claude can query states, manage containers and stacks, handle media libraries and download queues, and run automations. Each service is optional and can be configured via environment variables, with a read-only mode and bearer-token-protected HTTP transport for always-on deployments.
    1
    MIT