A media management and AI-assisted remediation server for Radarr, Sonarr, Chaptarr, and Lidarr instances with MCP tool support for quality profile management, issue remediation, and media search/import operations.
Cantinarr defines 6 tools with complete input schemas and descriptions. Naming is clear and verb-driven (post_, conclude_, propose_, ask_, preview_, apply_). Descriptions are detailed and context-aware, explaining state transitions and admin workflows. However, output schemas are not documented in the visible code, only input schemas are shown. Error handling guidance is minimal; tools lack recovery hints for common failure modes. The propose_action tool accepts a generic 'params' object (type: object) with no schema constraints, forcing LLMs to guess the structure of action-specific parameters. Tool composition is sound: each tool has one responsibility, and the workflow (investigate → propose → admin approval → verify) is well-structured.
Apply one same-turn previewed quality-profile update after an explicit admin request. Reauthorizes, refuses stale settings, verifies the complete result, and records a durable before/after history entry for safe review and revert. In-app chat only, admin only
Ask the issue's reporter a clarifying question (intent/preference only). The agent asks the issue's reporter a clarifying question and the run parks as awaiting_user until they reply.
Finish the investigation. The server accepts 'resolved' only for an auto-detected issue when a fresh, exact queue read proves its original target is gone; subjective user reports and 'wont_fix' judgments are escalated for an administrator. Proposing or dispatching a fix is not verification. Include a short plain-language explanation and call this exactly once after posting your diagnosis.
Post a plain-language message to the issue thread the reporter and admins can read. Use this to report what you found and your diagnosis in clear, non-technical language. You have NO mutation tools: you can only investigate and report.
Prepare and show a narrow full-object quality-profile update for one Radarr/Sonarr/Chaptarr/Lidarr instance; it never writes. In Cantinarr's in-app chat it returns a one-use reference apply_profile_change may consume in this same authenticated turn, after an explicit admin request. From an external MCP client it instead parks the change for admin approval in the Cantinarr app and notifies the admins; the write happens only if an admin approves it there. Admin only
propose_action 'params' field lacks schema constraints. It is declared as type:object with no additionalProperties, minProperties, or per-kind schema definitions. LLMs cannot infer the structure of grab_release vs remediate_queue vs manual_import params, forcing guesswork.
Output schemas are not documented in the visible code. Tools return results but LLMs have no formal specification of response fields, types, or structure. This violates the pattern:tool requirement and forces LLMs to infer output shape.
Error handling lacks recovery guidance. Tools do not document what errors are retryable, user-fixable, or fatal. No error responses shown that guide the LLM on next steps (e.g., 'Try ask_reporter() if you need clarification').
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 67 | 2026-07-28+ | v2 |
Propose a fix for an admin to approve. This is the ONLY way you can change anything: you record a proposal and an admin must approve it before the server carries it out. You never perform the change yourself. After you propose, the investigation pauses until the admin decides, then resumes so you can verify the result (on approval) or try another approach (on denial). Choose a 'kind' and supply its 'params': grab_release (download a specific release), remediate_queue (act on a stuck queue item), manual_import (import a download's files), trigger_search (start an automatic search), delete_media_files (delete files the service already imported), rescan (rescan the media on disk and run the import pass). Always include a clear 'rationale' explaining why this fix is correct (the admin reads it).
apply_profile_change requires a 'change_reference' string (86-86 chars) with no explanation of how to obtain it or what it contains. The description mentions 'one same-turn previewed' but does not explain the reference format or lifecycle.
preview_profile_change and apply_profile_change are context-dependent (in-app chat vs external MCP client behavior differs). The descriptions mention this but do not formally document the branching logic or how an external client knows which path applies.