Read-only diagnostic MCP server for a self-hosted arr stack (Sonarr, Radarr, Prowlarr & more).
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Ask your media stack what's going on, in plain language.
A locally-run, read-only MCP server that lets an LLM client (Claude Code, Claude Desktop) diagnose a self-hosted *arr media stack.
Oraclarr gives a language model one place to answer the operational "why" questions that normally mean tabbing through six web UIs. It aggregates across your services and returns a single, structured answer without changing anything (it is strictly read-only in this phase).
Covered now: Sonarr, Radarr, Prowlarr, qBittorrent, Tdarr, and Profilarr β including multiple instances of the same type (e.g. a separate anime or 4K Sonarr/Radarr). Every tool fans out across all the instances you define and reports each one separately.
Once registered, you just ask your MCP client. Oraclarr picks the right tool and answers:
| You askβ¦ | Oraclarr runs | β¦and tells you |
|---|---|---|
| "Is anything in my stack down?" | stack_health | which services are unreachable, unhealthy, or low on disk |
| "Why hasn't the new episode of X downloaded yet?" | diagnose | where X is in the wanted β grab β download β import pipeline |
| "Why did a sub-only release get grabbed when I only allow English dubs?" | explain_decision | the release that was grabbed, its custom-format score, and the language formats that matched |
| "Why does Profilarr keep upgrading stuff that already looks fine?" | explain_decision + get_quality_config | the profile cutoff/upgrade thresholds vs. the current file's score |
| "What's stuck downloading right now?" | get_queues | unified queue with progress, ETA, and stall flags |
All read-only and outcome-oriented (not one-per-endpoint, which keeps the model accurate):
| Tool | Answers |
|---|---|
stack_health | Is anything down / unhealthy / low on disk? |
get_queues | Unified active downloads (arr queue β qBittorrent), stalls |
diagnose | Where is X in the pipeline / why isn't it here yet? |
explain_decision | Why was X grabbed or being upgraded? (profile, custom formats, grab history) |
get_quality_config | Quality profiles, custom formats, release profiles, Profilarr sync state |
get_history | Recent grabs / imports / failures |
get_wanted | What's missing / cutoff-unmet? |
search_media | Do I have X, what's its status? |
get_indexers | Which indexers are failing? |
get_transcodes | What's transcoding / stuck? |
There are two ways to run Oraclarr β pick one, you don't need both:
Both options need the same two files. Make them from the templates in this repo β
config.example.yaml (your service URLs) and
.env.example (your API keys / passwords):
cp config.example.yaml config.yaml and
cp .env.example .env, then edit them.config.yaml and a .env in your stack folder, and
fill in your details.See Configuration below for exactly what goes in config.yaml.
Your config.yaml and .env are never committed β your URLs and secrets stay on
your machine. Now follow one of the two options below.
Oraclarr runs as a long-running container that serves MCP over HTTP at
http://<host>:7979/mcp. You need three things in one folder: your config.yaml,
your .env, and a docker-compose.yml.
Using a stack manager (Dockge, Portainer, etc.): create a new stack, paste the
compose below into the editor, and put your config.yaml and .env in the same
stack folder. Hit deploy.
Create
config.yamlas a real file before you deploy. The compose mounts./config.yamlinto the container. If that file doesn't exist yet, Docker silently creates an empty directory at the mount point and the container exits withIsADirectoryError: Is a directory: '/config/config.yaml'. If you hit that: stop the stack, delete theconfig.yamldirectory in the stack folder, createconfig.yamlas a file, and redeploy.
Using the command line:
Either way, this is the compose file β copy/paste it as-is:
The keys on the right (${SONARR_KEY} β¦) are read from your .env file. Then
connect Claude Desktop.
Run Oraclarr directly, no Docker. Requires Python 3.12+ and
uv.
From PyPI (no clone needed): the package is published as
oraclarr-mcp. Point ORACLARR_CONFIG
at your config.yaml and run it with uvx:
From a clone (for development):
This speaks MCP over stdio β the client launches the process for you, so you register it in your client's config rather than connecting to a URL:
(From a clone instead of PyPI, use "command": "uv", "args": ["run", "python", "-m", "oraclarr_mcp"], and add "cwd" pointing at the repo.)
(For Option A / Docker. Option B registers itself with the JSON snippet above.)
Use the mcp-remote bridge in claude_desktop_config.json. It runs locally as
a Claude Desktop "local MCP server", so it can reach the container on your LAN
(requires Node.js / npx):
Replace <host> with the IP or hostname of the machine running the container.
Why
--allow-http? Recent versions ofmcp-remotereject plainhttp://URLs unless the host islocalhost. Without this flag the bridge exits immediately and Claude Desktop shows the server as "disconnected" β even though the server itself is reachable. The flag is safe here: the traffic stays on your trusted LAN.
Why not the native "Add custom connector"? Custom connectors connect to your server from Anthropic's cloud, not from your machine β so the URL must be a publicly reachable HTTPS endpoint (a
http://LAN/localhost URL is rejected). Pointing it at a homelab box means exposing this unauthenticated read-only service to the internet, which we don't recommend until authentication lands (a later phase). If you want it anyway, put a reverse proxy (Caddy/nginx) or tunnel (Cloudflare Tunnel, Tailscale Funnel) with TLS in front and add your own auth.
Security: the service is unauthenticated read-only MCP. Deploy on a trusted LAN only and do not expose port 7979 to the internet. Authentication is a later phase.
These apply to the Docker container only. The image already sets sensible defaults, so you normally don't touch them β the table is here for reference. The Python path (Option B) always uses stdio and ignores these entirely.
| Variable | Default | What it does |
|---|---|---|
ORACLARR_TRANSPORT | http | How clients reach the server. http = long-running service (Docker). stdio = the client launches the process (the Python path). You don't normally set this by hand β your install method picks it. |
ORACLARR_HTTP_HOST | 0.0.0.0 | Which network interface to listen on. 0.0.0.0 means "reachable on your LAN" β leave as-is for Docker. |
ORACLARR_HTTP_PORT | 7979 | Port inside the container. To change the port you reach it on, edit the ports: line in the compose instead. |
ORACLARR_CONFIG | /config/config.yaml | Where the container reads config.yaml. Leave as-is. |
Instances are named in config.yaml; type selects the client, so any number of instances of any type (e.g. two Sonarrs) just work. Secrets are referenced as ${ENV_VAR} and pulled from .env:
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/oraclarr)<a href="https://allmcps.com/mcp/oraclarr"><img src="https://allmcps.com/api/badge/oraclarr?style=directory" alt="Oraclarr on AllMCPs" /></a>