Install
$ agentstack add mcp-ondrejmirtes-mcparr ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
MCPArr
An MCP server for Sonarr (TV shows) and Radarr (movies). Manage your media library in natural language from Claude Code or any MCP client.
[](https://github.com/ondrejmirtes/mcparr/actions/workflows/ci.yml) [](https://github.com/ondrejmirtes/mcparr/pkgs/container/mcparr) [](LICENSE)
> Ask things like "are we already tracking Severance?", "add Dune", "a new episode of > The Bear should be out — poke it and grab the best torrent", or "what's airing this week?" — > and MCPArr turns them into the right Sonarr/Radarr API calls.
What is MCPArr?
MCPArr is a small, self-hostable Model Context Protocol server written in TypeScript. It wraps the Sonarr and Radarr v3 REST APIs as a focused set of MCP tools, and ships skills — bundled best-practice guides that the model auto-discovers and follows so it performs the right sequence of actions (e.g. always check the library before adding, never grab a rejected release, confirm before deleting files).
It is heavily inspired by homeassistant-ai/ha-mcp and reuses its skill-delivery pattern (MCP resources + a discovery tool whose description carries each skill's trigger conditions).
Goals
- Answer "do we have this?" — search the library by title.
- Add shows & movies — look up by title/TMDB/TVDB id and add with the right profile & folder.
- Poke late downloads — when an episode/movie that should be out wasn't grabbed, run an
interactive indexer search, sort releases by seeders descending, and grab the right one.
- Calendar — what's airing/releasing over a time window.
- Queue & health — inspect downloads, fix stuck items, diagnose "why isn't anything downloading".
- Quality & cleanup — upgrades (cutoff-unmet), monitoring, and removing items / reclaiming disk.
Features
Sonarr tools (TV)
| Tool | What it does | |---|---| | sonarr_search_library | Is a show already tracked? | | sonarr_lookup_series | Find a show to add (by name / tvdb:/imdb: id) | | sonarr_list_profiles_and_folders | Quality profiles & root folders | | sonarr_add_series | Add a show (mutating) | | sonarr_list_episodes | Episodes of a tracked show (to get an episodeId) | | sonarr_calendar | Upcoming episodes | | sonarr_missing_episodes | Aired-but-missing episodes | | sonarr_cutoff_unmet | Episodes below quality cutoff (upgrade candidates) | | sonarr_search_releases | Interactive release search, sorted by seeders desc | | sonarr_grab_release | Download a chosen release (mutating) | | sonarr_queue | Download queue | | sonarr_remove_queue_item | Remove / blocklist a queue item (mutating) | | sonarr_health | System status, disk, indexers, download clients | | sonarr_set_monitoring | Monitor/unmonitor series or seasons (mutating) | | sonarr_delete_series | Remove a show (optionally delete files) (mutating) |
Radarr tools (movies)
radarr_search_library, radarr_lookup_movie, radarr_list_profiles_and_folders, radarr_add_movie (mutating), radarr_calendar, radarr_missing_movies, radarr_cutoff_unmet, radarr_search_releases (seeders desc), radarr_grab_release (mutating), radarr_queue, radarr_remove_queue_item (mutating), radarr_health, radarr_set_monitoring (mutating), radarr_delete_movie (mutating).
Skills (bundled, auto-discovered)
mcparr_get_skill exposes 8 guides; the model loads the relevant one before acting: media-library-management, late-episode-troubleshooter, interactive-release-search, upcoming-calendar, queue-management, library-health-and-diagnostics, quality-and-upgrades, monitoring-and-cleanup. See [Skills](#skills).
Quick start
MCPArr speaks the Streamable HTTP MCP transport and runs as a long-lived container. Point it at your existing Sonarr/Radarr with environment variables, then connect Claude Code to it.
> Find each API key in the app under Settings → General → Security → API Key.
Docker (CLI)
docker run -d --name mcparr \
-p 3000:3000 \
-e SONARR_URL=http://192.168.1.10:8989 \
-e SONARR_API_KEY=your-sonarr-key \
-e RADARR_URL=http://192.168.1.10:7878 \
-e RADARR_API_KEY=your-radarr-key \
ghcr.io/ondrejmirtes/mcparr:latest
Check it's up:
curl http://localhost:3000/health # -> {"status":"ok",...}
docker-compose
services:
mcparr:
image: ghcr.io/ondrejmirtes/mcparr:latest
container_name: mcparr
environment:
SONARR_URL: http://sonarr:8989
SONARR_API_KEY: ${SONARR_API_KEY}
RADARR_URL: http://radarr:7878
RADARR_API_KEY: ${RADARR_API_KEY}
# MCPARR_AUTH_TOKEN: ${MCPARR_AUTH_TOKEN} # recommended if reachable beyond localhost
# MCPARR_READ_ONLY: "true" # disable all mutating tools
TZ: Europe/Prague
ports:
- "3000:3000"
restart: unless-stopped
docker compose up -d
If Sonarr/Radarr run in the same compose project, put them on the same network and reference them by service name (http://sonarr:8989). Otherwise use their real address.
Image tags: :latest (stable releases), :nightly (nightly build), :edge (latest main), and :X.Y.Z semver tags. Images are multi-arch (amd64 + arm64).
Configuration
| Env var | Default | Purpose | |---|---|---| | SONARR_URL | – | Sonarr base URL, e.g. http://sonarr:8989 | | SONARR_API_KEY | – | Sonarr API key (required if SONARR_URL is set) | | RADARR_URL | – | Radarr base URL, e.g. http://radarr:7878 | | RADARR_API_KEY | – | Radarr API key (required if RADARR_URL is set) | | MCPARR_HOST | 0.0.0.0 | Bind address | | MCPARR_PORT | 3000 | HTTP port | | MCPARR_PATH | /mcp | MCP endpoint path | | MCPARR_AUTH_TOKEN | – | If set, clients must send Authorization: Bearer | | MCPARR_READ_ONLY | false | When true, all mutating tools are disabled | | LOG_LEVEL | info | debug \| info \| warn \| error | | TZ | UTC | Timezone (affects calendar formatting in logs) |
At least one service (Sonarr or Radarr) must be configured. Tools for an unconfigured service are not registered.
Connect to Claude Code
With the container running and reachable at http://localhost:3000/mcp:
claude mcp add --transport http mcparr http://localhost:3000/mcp
If you set MCPARR_AUTH_TOKEN, include the header:
claude mcp add --transport http mcparr http://localhost:3000/mcp \
--header "Authorization: Bearer your-token"
Or add it to your project's .mcp.json:
{
"mcpServers": {
"mcparr": {
"type": "http",
"url": "http://localhost:3000/mcp"
}
}
}
Verify with /mcp inside Claude Code — you should see the MCPArr tools and the skill://… resources.
Skills
Skills are markdown workflow guides that make the model do the right thing without you spelling out every step. They are delivered two ways, so they auto-discover the moment you add the server:
- MCP resources — every skill file is exposed at
skill:///. Resource-capable
clients (Claude Code) list them automatically; no install step.
- The
mcparr_get_skilltool — its description embeds each skill's *"TRIGGER THIS SKILL
WHEN…"* conditions, so the model fetches the relevant guide on demand (e.g. it loads late-episode-troubleshooter as soon as you say "this episode didn't download"). This is the reliable path, since clients list resources but don't auto-inject their content.
Optional: install as native Claude Code skills. For always-on triggering without a tool call, copy the bundled skills into your skills directory:
git clone https://github.com/ondrejmirtes/mcparr
cp -r mcparr/skills/* ~/.claude/skills/ # or /.claude/skills/
Example prompts
- "Are we already tracking Severance?"
- "Add the movie Dune: Part Two in 1080p."
- "Add The Bear and start searching for episodes."
- "A new episode of Slow Horses should be out by now — find it, grab the release with the most
seeders that isn't rejected, and confirm it's downloading."
- "What episodes are airing in the next 7 days?"
- "What movies I'm tracking release this month?"
- "Why isn't anything downloading?"
- "Show me the download queue and clear out anything that's stalled."
- "Stop monitoring season 1 of The Office."
Security
- MCPArr holds your Sonarr/Radarr API keys and can add/delete library items. **Do not expose its
port to the public internet.** Keep it on your LAN / behind a reverse proxy / VPN.
- Set
MCPARR_AUTH_TOKENto require a bearer token on the MCP endpoint. - Set
MCPARR_READ_ONLY=trueto expose only read tools (no add/grab/remove/delete). - The server runs as a non-root user inside the container.
Development & testing
npm install
npm run dev # run from source (tsx watch)
npm run lint # biome
npm run type-check # tsc --noEmit
npm test # unit tests (mocked HTTP)
npm run build # bundle to dist/ with tsup
End-to-end tests
The E2E suite spins up real Sonarr + Radarr containers (with pre-seeded API keys) plus a mock Torznab indexer, drives them through the MCPArr clients, and verifies via the actual API that each action took effect:
npm run e2e:up # start test/docker/docker-compose.test.yml
npm run test:e2e # add a show/movie & confirm it's tracked; calendar; queue;
# interactive search returns mock releases sorted by seeders desc
npm run e2e:down # tear down (-v)
tests/unit mocks the *arr HTTP layer (undici MockAgent); tests/e2e runs against the live containers. CI (GitHub Actions) runs lint + type-check + unit + a Docker image smoke test on every PR, and the full E2E stack on pushes to main.
How MCPArr is verified
Every release is exercised end-to-end before the image ships:
- Unit tests assert request shapes (add bodies, grab
guid+indexerId, queue params) and the
seeders-descending sort.
- E2E tests add a known show/movie to a fresh Sonarr/Radarr and read it back through the API,
query the calendar and queue, and run an interactive search against the mock indexer asserting the releases come back ranked by peers.
- The Docker image is built, booted, and health-checked.
License
MIT — see [LICENSE](LICENSE).
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: ondrejmirtes
- Source: ondrejmirtes/mcparr
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.