MCP tools
Implementation contracts and behavior for mcp tools.
Every discover tool filters its titles through the caller’s kids-account policy (resolved once per call in ExecuteTool): searches, trending, recommendations, browse (limits pushed upstream too), collections (parts cut, an emptied collection dropped), and display_media drop what the account may not see and tell the model how many titles the limits removed; get_movie_details / get_tv_details answer “That title is not available for this account.” rather than describe it. A policy that cannot be read fails the call. Admins and the server-owned remediation runner are never filtered.
The registry contains 41 in-app AI tools; 40 are also exposed through /mcp. apply_profile_change alone is hidden from external MCP: its one-use handoff depends on authenticated in-app chat-turn provenance, and no external path may complete a profile write itself. preview_profile_change is exposed externally, where it parks an admin-approval proposal instead of arming the same-turn apply (see the profile-change proposals section below). The remediation agent receives a constrained read-only subset plus issue-scoped human gates. Every shared tool can be disabled from Settings > AI Tools. Interactive execution reauthorizes the current device and role immediately before each tool and rechecks the included-AI grant when shared billing is in use. Tools marked admin require the admin role (either flagged directly or gated by a permission the user role doesn’t hold). Every arr-facing tool (get_queue through rescan_media, plus the settings tools) accepts an optional instance_id from list_arr_instances to target any configured library instead of the default; library-read answers name the library they read, an unknown id is refused rather than quietly served by the default, and the remediation runner’s issue scope always overrides the model’s choice:
| Tool | Description |
|---|---|
search_movies |
Search TMDB for movies |
search_movie_collections |
Search TMDB for movie franchises/collections |
search_tv_shows |
Search TMDB for TV shows |
search_books |
Search the authorized Chaptarr instance within ten seconds; return exact foreign_book_id, instance_id and search term |
search_music |
Unified MusicBrainz albums/EPs/singles with exact-ID live library and saved-request enrichment by default; keeps relevance order and matching library-only records, labels failed reads, and carries foreign_album_id, foreign_id, instance_id, and search_term. Explicit public, library, and all retain the legacy catalog modes. Admins can browse before Lidarr setup; requester grants still apply. |
get_trending |
Trending movies/shows by day or week |
browse_titles |
Browse movies or TV by genre, year range, minimum rating and votes, original language, streaming service (per region), keyword, and studio, sorted and paged; plain names are resolved to TMDB ids server-side and any it cannot resolve is reported with the valid options; the admin’s English-only preference applies unless a language is named |
get_movie_details |
Full movie metadata |
get_tv_details |
Full TV show metadata |
get_recommendations |
Similar content suggestions |
check_request_status |
Read live media status by native identity, or immediate saved delivery by request_id; book formats remain separate |
get_request_options |
Show current request choices, libraries, quality profiles, and request_quotas; optional preview accepts a REST selection (with foreign_id for books/music), inheriting the outer media_type and instance_id, and returns cost without reservation |
request_media |
Save requests under the same allowances as REST, with optional instance_id/book_format and TV season_scope or explicit seasons; return structured request_quota_exceeded failures for an affordable retry |
list_my_requests |
User’s request history |
display_media |
Curate the visual results carousel (movies/TV verified via TMDB; books verified against the user’s own lookup by foreign_book_id) |
get_queue |
Combined arr download queue (admin) |
get_calendar |
Upcoming releases (admin) |
get_library |
What’s on the server, filterable, with the answer naming which library it read; for books, drills from the author list into one author’s books (or one exact book) with the book ids the per-book action tools take, and for music from the artist list into one artist’s albums (or one exact album) with their album ids (admin) |
get_history |
Recent grabs/imports/failures; a call scoped to one title reads that title’s own history from the service instead of filtering a page of global events, so an old event is still found (admin) |
trigger_search |
Kick off an automatic download search; a TV season search can be narrowed to aired_only, resolving the aired-and-missing episodes at call time. This narrowing is available to an admin here but deliberately not in the remediation agent’s action vocabulary, where replacing what a bad import destroyed belongs to delete_media_files (admin) |
search_releases |
Exact movie, season, episode, book, or album indexer search; returns one-way release references, never raw GUID capabilities (admin) |
grab_release |
Freshly re-search the supplied exact media scope and download the unique release matching its one-way reference + indexer id, on the same library the search ran against (admin) |
remove_queue_item |
Remove/blocklist a queue item on any of the four arrs (admin) |
get_disk_space |
Disk space for every configured library, labeled per instance; optional instance_id narrows to one (admin) |
get_arr_health |
Arr system health: download client, remote path mapping, indexers, disk, root folders (admin) |
get_episode_timeline |
Lay one TV season out episode by episode: air date, whether it has aired, and the file the library holds for it: and flag files the service imported before that episode aired (admin) |
get_media_file_details |
Inspect the file(s) the library holds for one movie, TV season, or album: resolution, codecs, audio languages, embedded subtitles, runtime, size, and import date: or, per track file, Lidarr’s codec, bit depth, sample rate, channels, and bitrate: the arr’s own analysis of what is on disk; a file the arr has not analyzed says so explicitly (admin) |
get_service_config |
Read-only summary of one settings section on Radarr, Sonarr, Chaptarr, or Lidarr: indexers (min seeders, priority), delay profiles, release profiles, download clients (category), remote path mappings: bounded and secret-free: credentials and URLs never leave the arr client (admin) |
get_book_timeline |
Join what the library holds for one book (files, import dates) to what happened (grab and import history with download identities): the receipts a wrong-book report is judged from (admin) |
get_album_timeline |
One album’s receipts: track files on disk (with import dates) joined to its grab/import history, with one-sided history blindness labelled. admin |
list_arr_instances |
Configured arr instances with the instance IDs the settings tools accept (admin) |
get_quality_profiles |
Quality profile summaries, one profile’s full stored JSON by id, and optionally the live Radarr/Sonarr language catalog with IDs that may vary by service/version (admin) |
get_custom_formats |
Custom format summaries, or one format’s full stored JSON by id (admin) |
upsert_custom_format |
Create/update a native or TRaSH custom format by exact name; creates enter profiles at score 0, updates preserve profile scores without recomputing stored file matches, and every AI/MCP write is recorded as readable, non-restorable history (admin) |
preview_profile_change |
Build a read-only diff for one profile; it never writes. In-app chat: mint a one-use reference valid only in the same authenticated turn after an explicit admin request. External MCP: park the change as a durable proposal, page the admins, and leave the write to an in-app approval (admin) |
apply_profile_change |
Autonomously consume that same-turn reference, refuse detected stale state, verify the complete result, and record durable before/after history (in-app chat only, admin) |
diagnose_queue |
Import Doctor across all four arr queues: explain stuck items + print the exact next call (admin) |
get_manual_import_candidates |
List a stuck download’s files, mappings (for music, which of the artist/album/track ids a file lacks), rejections (admin) |
execute_manual_import |
Force a download’s files into the library (admin) |
remediate_queue_item |
One-click queue fix: remove, blocklist (service decides replacement), blocklist without replacement, change category (admin) |
rescan_media |
Rescan a movie/series/author/artist on disk and run the import pass (admin) |
Custom-format tools probe the configured instance’s live collection endpoint rather than trusting a stored version. Sonarr requires v4 for custom formats; a collection-read 404 is reported as either an older/incompatible build or a stored instance URL missing its service URL base, because those cases are indistinguishable at that API boundary. Write-side 404s stay concrete so a concurrently deleted record is not misdiagnosed as an old service. Every successful AI/MCP custom-format create or update receives a verified readback and durable history entry with live comparison; failed or ambiguous attempts retain outcome-aware history for reconciliation. Custom-format entries cannot be restored.
Quality-profile mutation is intentionally narrow: one existing profile, one full-object PUT, and only upgrade policy, an already-allowed quality/group cutoff, score thresholds, existing custom-format scores, plus Radarr’s profile language. It does not create/delete/rename profiles, toggle or reorder qualities, create custom formats, or batch profiles. An explicit admin request lets the assistant preview and apply within the same authenticated chat turn; the admin never has to copy or type the one-use reference. Preview binds the actor, device, issuing chat turn, exact service instance and current URL/API-key fingerprint, profile, complete custom-format collection, relevant language catalog, and desired full object. The resolved instance remains pinned even if the service default changes. Apply consumes the random reference before remote I/O, reauthorizes, rebuilds from fresh JSON, checks the bound state immediately before writing, verifies the complete stored profile afterward, and records server-held before/applied snapshots. Any detected stale state, expired/superseded/restarted/used reference, or ambiguous write outcome requires a new preview.
The final guards are optimistic, not an atomic compare-and-swap: Cantinarr serializes its own settings writes, but a direct arr UI/API edit; or a local authorization, tool-toggle, URL, or API-key change; can still race the last check and PUT. Settings > Configuration history safely projects the recorded differences and current live comparison. A guarded restore is offered once, only while the live profile, its relevant dependencies, and the instance binding still match the applied update; success creates a linked, non-restorable history entry and permanently consumes that update’s restore action. Direct arr edits or connection changes make restore unavailable rather than overwriting newer work. Typed arr HTTP 400 validation details are projected through a bounded, redacted exception used only for credential-free custom-format/profile endpoints; all other error bodies remain discarded.
Language IDs may vary by service and version, so they are read live from each Radarr/Sonarr instance (get_quality_profiles with include_languages) instead of hardcoded or reused. Sonarr v4 language behavior comes from scoring an existing LanguageSpecification custom format; it has no persistent profile-language write. Radarr’s profile-level language is a hard release filter and must be Any when a language custom format has a nonzero score. Chaptarr supports the scalar/cutoff/custom-format-score profile changes but no release-language specification. These settings influence future release selection for media assigned to the profile: they do not inspect or remux downloaded streams, change file-level default audio/subtitle flags, guarantee playback language, or retroactively replace files.