plex-director-mcp
Plex Director is a self-hosted MCP server (with a web dashboard) that lets Claude query and manage a Plex + Servarr media stack, inspect downloads/indexers, run batch upgrade jobs, and monitor hosts.
Search your library: search Plex movies and shows by genre, actor, title, year, library (e.g. 4K), network/studio, rating, watch state, or recency with paging and sorting (
search_plex_library).Find episodes and what to watch next: search individual episodes by title, plot (with a show), air date, or premiere/finale (
search_episodes), and get Plex On Deck / Continue Watching (get_on_deck).Compare owned vs. missing: pull an actor's TMDb filmography and mark which titles are in Plex (
resolve_actor_filmography).Check TV completeness in Sonarr: per-show downloaded vs. missing aired episodes (
check_series_completeness), which shows have gaps (find_series_gaps), show status/quality/next airing (check_series_status), why episodes are missing (diagnose_missing_episodes), upcoming episodes (get_upcoming_episodes), and shows by downloaded quality (find_series_by_quality).Check and diagnose movies in Radarr: whether a movie exists and is monitored (
check_movie_status) and why it is missing via metadata, history, and queues (diagnose_missing_media).Add movies: search TMDb and show a choice grid (
search_and_select_movies), then add chosen titles to Radarr with a download search (confirm_selected_choices).Manage downloads and indexers: audit or purge stalled/slow qBittorrent torrents by hash (
manage_stalled_downloads) and check Prowlarr indexer health and warnings (check_indexer_health).Run batch jobs: plan a movie upgrade batch (
plan_media_upgrade), list jobs (get_background_jobs), pause/resume/cancel (update_job_status), and step a job manually (execute_next_job_step), with a rate-limited automatic runner.Monitor infrastructure: CPU, RAM, disk, uptime, and Docker health over SSH (
get_cluster_infrastructure_health,get_cluster_hardware_analytics), plus trusting a rebuilt host's new SSH key (trust_new_host_key) and triggering Radarr/Sonarr/Prowlarr backups (run_cluster_backup).View Plex/Tautulli analytics: live streams and transcoding load (
get_plex_activity) and watch statistics, top users, platforms, and libraries (get_library_analytics).
Note: several tools change state (adding movies, purging torrents, running backups, starting searches), so they should be confirmed with the user first.
Sends optional status notifications for completed batch jobs via a Discord webhook.
Monitors Docker health on remote hosts as part of cluster infrastructure checks.
Provides tools for checking active Plex streams, recent library usage, and diagnosing missing media in a Plex library.
Provides tools for managing stalled or low-speed downloads in qBittorrent.
Enables checking movie status in Radarr and diagnosing why a movie is missing from the library.
Enables managing TV show media availability and diagnosing missing content through Sonarr.
Monitors remote Ubuntu hosts over SSH for CPU, memory, and Docker health.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@plex-director-mcpWhy is the latest episode of Severance missing from Plex?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
plex-director-mcp
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.
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
Quick start, installing, upgrading and backups and verifying releases.
The user guide: the dashboard pages, the Query chat and the MCP tools. The documentation index lists everything.
Architecture: the components, who uses them, and how a question flows through them.
Security requirements: what Plex Director does and doesn't protect against, and the assurance case behind it.
Roadmap: where the project is going, and what it won't do.
Accessibility: what the dashboard does today and the known gaps.
External interfaces (the dashboard's HTTP API is described in docs/api/openapi.json) and dependencies and vulnerability management.
Support: which versions get fixes, and for how long. Changelog.
Contributing, Code of Conduct, Governance and reporting a vulnerability.
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-stoppeddocker compose up -dThen 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 |
|
GitHub Container Registry |
|
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 ( | ✅ |
arm64 ( | ✅ |
Image tags
Tag | Description |
| The most recent build of the |
| A specific release. Pin one of these if you want to choose when to upgrade. |
| The newest patch release of a minor version. |
| The build of one specific commit, for pinning or bisecting. |
Release notes for the numbered versions are on the Releases page.
Application setup
Start the container with one of the usage examples and open the web UI at
http://<host>:3000.Set a password. Add
WEB_PASSWORDto 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.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.
Give the chat box a brain. The Query page uses Claude to answer questions, so it needs
ANTHROPIC_API_KEYin 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.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 |
Plex | The server URL (e.g. |
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,
localhostis the container itself, not your server. Use the LAN address of each service (for examplehttp://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.
Docker Compose (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-stoppedThe 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.envThen start it:
docker compose up -dDocker 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:latestAdd 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-fileis not the same as a.envfile 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 keybecomes the valueabc # 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:
-iis required, since MCP talks over stdin/stdout. Don't add-t.No
-pis 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 |
| The web dashboard. Change the left number to use a different port on your host. |
| Password for the web dashboard. Strongly recommended. |
| Enables the Query chat. |
| Service connection details; see the reference. Optional, since they can be entered on the Settings page. |
| The SQLite database: your saved settings, job history and login-session secret. Mount a volume here. |
| Optional. A private SSH key for host monitoring (with |
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. Used for movie status, diagnosis, adding movies, and batch jobs. |
| 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. Optional; used for TV episode completeness and backups. |
| Prowlarr, for indexer health and backups. |
| SABnzbd, for the queue and for diagnosing missing media. |
| qBittorrent Web UI. |
| Tautulli, for streams and watch statistics. |
| Plex, for searching what you own. |
| Optional. Comma-separated Plex library names to leave out of searches (whole names, any case), e.g. |
| TMDb API Read Access Token, for actor filmographies and the movie-choice grid. |
| Comma-separated hosts to monitor over SSH, e.g. |
| 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 |
| (none) | Requires a login for the dashboard. Changing it signs everyone out. |
| (none) | Only matters without |
| (none) | The reverse proxy in front of the dashboard: its address or subnet, comma-separated (e.g. |
| (none) | Encrypts the service credentials saved in the database (AES-256-GCM). 32 random bytes, base64 or hex: make one with |
|
| The port the dashboard listens on inside the container. |
| (none) | Anthropic API key for the Query chat. |
| (none) | Path (inside the container) to the private key for host monitoring. It must be readable by the container's user. |
| (none) | The passphrase, if that private key is passphrase-protected. |
| (none) | Discord webhook for job-completed and job-paused notifications. |
|
| How often the job runner advances a started job by one movie (minimum |
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:3000Or 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 pruneDocker 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 pruneVerify 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:latestBuilding 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-passwordSee 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 # notemakes 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 |
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 |
★ | Searches the movies and TV shows in your Plex library by genre, actor, title, year and/or library (e.g. |
★ | 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. |
★ | "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 |
★ | 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. |
★ | "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. |
★ | 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. |
★ | 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 |
★ | 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. |
★ | 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. |
★ | 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. |
★ | Whether a movie is in Radarr, and its monitoring status, with artwork. |
★ | Traces a movie through Radarr metadata, history and the download queues to find why it is missing. |
| Searches TMDb and shows a numbered grid of matches. |
| 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 |
|
|
| Reports failing, backing-off and disabled Prowlarr indexers, and Prowlarr's own warnings. |
Background jobs
Tool | What it does |
| 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). |
| Lists jobs and their progress. |
|
|
| 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 |
| CPU, memory and Docker container health for each SSH host. |
| CPU and memory per host as a table. |
| 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 |
| 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. |
| Live playback streams and transcoding load, via Tautulli. |
| 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 usetrust_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 withssh-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_choicesadds movies and starts downloads,manage_stalled_downloadswithPURGE_STALLEDdeletes the torrents you agreed to after anAUDIT, 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 testsThe 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 youTests 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/datain 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 againstmain: the TypeScript typecheck, the test suite,npm audit --audit-level=high, and the same typecheck and audit for the dashboard inweb/.Build, smoke test, and publish (
publish) runs on every push tomain, everyv*.*.*tag push and every pull request, oncecheckpasses. Every run builds the image and boots it with dummy configuration to confirm it starts. Pushes then publish to both registries (branch pushes taglatestand the commit SHA; tag pushes also get the version, e.g.1.2.3and1.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 onv*.*.*tag pushes, afterpublishsucceeds, 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
Available Tools
26 toolscheck_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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | The exact title of the movie to search for. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| year | No | First air year, only needed to tell same-named shows apart. | |
| title | Yes | The show's title, e.g. 'Breaking Bad'. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| year | No | First air year, only needed to tell same-named shows apart. | |
| title | Yes | The show's title, e.g. 'Severance'. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| rootFolder | No | Radarr root folder path to add to instead of the first one (e.g. '/media/movieskids'). | |
| chosenIndexes | Yes | An array of chosen numbers selected by the user (e.g., [1, 3]). | |
| qualityProfile | No | Radarr quality profile name to use instead of the default. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| year | No | First air year, only needed to tell same-named shows apart. | |
| title | Yes | The show's title, e.g. 'Bluey'. | |
| season | No | Only this season. | |
| episode | No | Only this episode number (needs season). |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | The title of the media to diagnose. |
TDQS
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.
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.
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.
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.
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.
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.)
| Name | Required | Description | Default |
|---|---|---|---|
| jobId | Yes | The unique tracking ID of the active job array to step execute. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many shows to list (default 15, max 200). | |
| folder | No | Only shows in a Sonarr folder whose path contains this text, e.g. 'kids', 'anime', 'sports'. | |
| mixedOnly | No | Only shows whose files are not all the same resolution. | |
| monitored | No | Only shows Sonarr monitors, only ones it does not, or both (default any). | |
| bestAtMost | No | Only shows whose best quality is at most this many lines, e.g. 720. | |
| bestAtLeast | No | Only shows whose best quality is at least this many lines, e.g. 1080 or 2160. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many shows to list (default 15, max 200). | |
| hideEmpty | No | Skip shows with no episodes downloaded at all. | |
| monitored | No | Only shows Sonarr is monitoring, only ones it is not, only ones it is actively searching missing episodes for ('searching'), or all (default any). | |
| maxMissing | No | Only shows missing at most this many episodes, e.g. 5 for nearly complete shows. | |
| minMissing | No | Only shows missing at least this many episodes. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many to list (default 10, max 50). | |
| title | No | Only a movie or show whose title contains this text, e.g. 'Dark Matter'. | |
| library | No | Only Plex libraries whose name contains this text, e.g. 'kids', '4k'. | |
| mediaType | No | Only movies, only shows' next episodes, or both (default any). |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | How many days ahead to list when no title is given (default 7, max 60). | |
| year | No | First air year, only needed to tell same-named shows apart. | |
| title | No | A show to ask about instead, e.g. 'Severance': its next episodes or that none is scheduled. | |
| monitored | No | Only shows Sonarr monitors (default), only ones it does not monitor, or all. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | AUDIT lists stalled downloads with their hashes and changes nothing; PURGE_STALLED deletes the torrents named in hashes, with their files. | |
| hashes | No | PURGE_STALLED only: the hashes, from AUDIT, of the torrents the user agreed to delete. Required for PURGE_STALLED. | |
| minSpeedKbps | No | A download slower than this (KB/s) counts as stalled, as does one qBittorrent reports as stalled. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| mediaType | Yes | The structural classification targeting upgrades. | |
| maxBatchSize | No | Limits the maximum number of edits in a single batch (1 to 100). | |
| targetResolution | Yes | The target processing quality resolution threshold. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| show | No | Only titles the user has in Plex ('owned'), only those they don't ('missing'), or both (default). | |
| limit | No | How many titles to list, newest first (default 15). | |
| yearTo | No | Only titles released in or before this year. | |
| library | No | 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. | |
| yearFrom | No | Only titles released in or after this year. | |
| actorName | Yes | The exact name of the actor (e.g., 'Harrison Ford'). | |
| mediaType | No | Only movies, only TV shows, or both (default any). |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | The film name or fuzzy query text to search for (e.g. 'Heat'). |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| show | No | A show to search inside, e.g. 'Entourage'. Required to search plots. | |
| text | No | Words that must all appear in the episode title (and, with a show, its plot). | |
| limit | No | How many to list (default 15, max 100). | |
| season | No | Only this season. | |
| airedTo | No | Aired on or before this date, YYYY-MM-DD. | |
| episode | No | Only this episode number (needs season). | |
| library | No | Without a show: only show libraries whose name contains this text, e.g. 'kids'. | |
| airedFrom | No | Aired on or after this date, YYYY-MM-DD. | |
| episodeType | No | Only season premieres, or season finales (needs a show). |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Order the results (default title). | |
| year | No | Release year (a show's first air year). | |
| actor | No | Full actor name, e.g. 'Harrison Ford'. | |
| genre | No | Genre name, e.g. 'Horror' or 'Science Fiction'. | |
| limit | No | Maximum results to return (default 25, max 500). | |
| title | No | Part of the movie or show title. | |
| offset | No | Matches to skip, to fetch the next page of a long result. | |
| yearTo | No | Released in or before this year. | |
| library | No | Only search Plex libraries whose name contains this text, e.g. '4k' for the 4K libraries, 'kids', 'anime', 'sports'. | |
| network | No | TV network (shows) or studio (movies), e.g. 'HBO', 'Netflix'. | |
| watched | No | Only titles never played, started but not finished, or finished. | |
| yearFrom | No | Released in or after this year (a decade: 1990 to 1999). | |
| mediaType | No | Search only movies, only TV shows, or both (default any). | |
| minRating | No | Audience rating of at least this (0-10). | |
| contentRating | No | Content rating, e.g. 'TV-MA', 'PG-13', 'R'. | |
| addedWithinDays | No | Added to Plex within this many days. | |
| notWatchedInYears | No | Only titles not watched for this many years (a never-watched title counts from when it was added). |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| host | Yes | The host exactly as configured in UBUNTU_HOSTS, e.g. 192.168.1.10 or host:2222. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| jobId | Yes | The unique ID of the target job | |
| action | Yes | The action to execute on the queue runtime. |
TDQS
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.
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.
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.
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.
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.
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.
3 tool updates
v1.4.0- Changed
manage_stalled_downloads4 fields changed- changed
Input schema / properties / action / descriptionPrevious 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." - added
Input schema / properties / hashesAdded 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" +} - changed
Input schema / properties / minSpeedKbps / descriptionPrevious 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." - added
Input schema / properties / minSpeedKbps / minimumAdded value: +0
- Changed
plan_media_upgrade4 fields changed- changed
Input schema / properties / maxBatchSize / descriptionPrevious 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)." - added
Input schema / properties / maxBatchSize / maximumAdded value: +100 - added
Input schema / properties / maxBatchSize / minimumAdded value: +1 - changed
Input schema / properties / maxBatchSize / typePrevious value: -"number"New value: +"integer"
- Added
trust_new_host_key
10 tool updates
v1.2.0- Added
check_series_completeness - Added
check_series_status - Added
diagnose_missing_episodes - Added
find_series_by_quality - Added
find_series_gaps - Added
get_on_deck - Added
get_upcoming_episodes - Changed
resolve_actor_filmography1 field changed- added
Input schema / properties / mediaTypeAdded value: +{ + "description": "Only movies, only TV shows, or both (default any).", + "enum": [ + "movie", + "show", + "any" + ], + "type": "string" +}
- Added
search_episodes - Changed
search_plex_library13 fields changed- added
Input schema / properties / addedWithinDaysAdded value: +{ + "description": "Added to Plex within this many days.", + "exclusiveMinimum": 0, + "type": "number" +} - added
Input schema / properties / contentRatingAdded value: +{ + "description": "Content rating, e.g. 'TV-MA', 'PG-13', 'R'.", + "type": "string" +} - changed
Input schema / properties / library / descriptionPrevious 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'." - added
Input schema / properties / mediaTypeAdded value: +{ + "description": "Search only movies, only TV shows, or both (default any).", + "enum": [ + "movie", + "show", + "any" + ], + "type": "string" +} - added
Input schema / properties / minRatingAdded value: +{ + "description": "Audience rating of at least this (0-10).", + "maximum": 10, + "minimum": 0, + "type": "number" +} - added
Input schema / properties / networkAdded value: +{ + "description": "TV network (shows) or studio (movies), e.g. 'HBO', 'Netflix'.", + "type": "string" +} - added
Input schema / properties / notWatchedInYearsAdded value: +{ + "description": "Only titles not watched for this many years (a never-watched title counts from when it was added).", + "exclusiveMinimum": 0, + "type": "number" +} - added
Input schema / properties / sortAdded value: +{ + "description": "Order the results (default title).", + "enum": [ + "title", + "recentlyAdded", + "lastWatched", + "leastRecentlyWatched" + ], + "type": "string" +} - changed
Input schema / properties / title / descriptionPrevious value: -"Part of the movie title."New value: +"Part of the movie or show title." - added
Input schema / properties / watchedAdded value: +{ + "description": "Only titles never played, started but not finished, or finished.", + "enum": [ + "unwatched", + "inProgress", + "watched" + ], + "type": "string" +} - changed
Input schema / properties / year / descriptionPrevious value: -"Release year."New value: +"Release year (a show's first air year)." - added
Input schema / properties / yearFromAdded value: +{ + "description": "Released in or after this year (a decade: 1990 to 1999).", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Input schema / properties / yearToAdded value: +{ + "description": "Released in or before this year.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +}
3 tool updates
v1.1.0- Changed
confirm_selected_choices2 fields changed- added
Input schema / properties / qualityProfileAdded value: +{ + "description": "Radarr quality profile name to use instead of the default.", + "type": "string" +} - added
Input schema / properties / rootFolderAdded value: +{ + "description": "Radarr root folder path to add to instead of the first one (e.g. '/media/movieskids').", + "type": "string" +}
- Changed
resolve_actor_filmography5 fields changed- added
Input schema / properties / libraryAdded 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" +} - added
Input schema / properties / limitAdded value: +{ + "description": "How many titles to list, newest first (default 15).", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / showAdded 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" +} - added
Input schema / properties / yearFromAdded value: +{ + "description": "Only titles released in or after this year.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Input schema / properties / yearToAdded value: +{ + "description": "Only titles released in or before this year.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +}
- Added
search_plex_library
16 tool updates
v1.0.0- First observed
check_indexer_health - First observed
check_movie_status - First observed
confirm_selected_choices - First observed
diagnose_missing_media - First observed
execute_next_job_step - First observed
get_background_jobs - First observed
get_cluster_hardware_analytics - First observed
get_cluster_infrastructure_health - First observed
get_library_analytics - First observed
get_plex_activity - First observed
manage_stalled_downloads - First observed
plan_media_upgrade - First observed
resolve_actor_filmography - First observed
run_cluster_backup - First observed
search_and_select_movies - First observed
update_job_status
TDQS
Scored across 26 tools
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.
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.
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.
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
Related MCP Connectors
Work on your own computers from Claude or ChatGPT: run commands, edit and search files.
- sentinelOAuthio.rootstuff
Uptime, SSL, DNS and domain monitoring you can talk to from Claude or any MCP client.
The media memory layer for AI agents and their humans. Your AI client can search your collection, add and log what you've finished, update ratings and lists, and find patterns across everything you've read, watched, played, and listened to.
Live SEO workflow tools for Claude Code, Codex, and AI agents.
Related MCP Servers
- AlicenseBqualityBmaintenanceEnables unified control of \*arr media management applications (Sonarr, Radarr, Lidarr, Readarr, Prowlarr) through natural language queries. Manage TV shows, movies, music, books, search for content, monitor downloads, and check upcoming releases across all services.66743 npm234MIT
- FlicenseNot gradedqualityDmaintenanceEnables full management of a Plex Media Server via Claude, including browsing libraries, fixing metadata, managing collections, and more.-
- FlicenseAqualityDmaintenanceExposes homelab and IT-ops tools to Claude, including system health monitoring, Grafana alert states, Docker container status, Loki logs, SMART disk health, and more.81-
- AlicenseNot gradedqualityBmaintenanceEnables 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.1MIT