An MCP server for the *arr media stack.
Let Claude, Cursor, VS Code or any other MCP client run your media server.
Install with your AI · Quickstart · Client setup · Tools · Docs
- Real MCP — JSON-RPC 2.0 over stdio and Streamable HTTP, built on the official Go SDK
- 336 tools — what you would otherwise do by clicking through each web UI
- Multi-instance — run two Sonarrs (4K and 1080p) and address them by name
- Permission controls — read-only, confirm-before-write, or full access
- Single static binary, distroless container, multi-arch image
| Service | Tools | Service | Tools | |
|---|---|---|---|---|
| Sonarr | 77 | Maintainerr | 25 | |
| Radarr | 73 | Seerr | 17 | |
| Bazarr | 33 | Jellyfin | 24 | |
| Prowlarr | 23 | Jellystat | 10 | |
| qBittorrent | 22 | Synology DSM | 14 | |
| NZBGet | 18 |
Expose one service or all of them; anything you don't configure registers no tools. What is planned and what is deliberately left out is in docs/scope.md.
The fastest way in. Paste this into Claude, ChatGPT, Cursor, or whichever assistant you use:
Read https://raw.githubusercontent.com/GauranshMathur/ARR_MCP/main/docs/ai-install-prompt.md
and follow it to set up ARR-MCP for me. It is an instruction document — act on it, don't
summarise it back to me.
That last sentence matters: without it, assistants tend to fetch the page and report on it rather than doing anything.
It works out which MCP client you are using — often the one you are already talking to — then asks only what it needs and either performs the setup itself or gives you exact steps for your operating system, ending with a command to check it worked.
If your assistant can't browse the web, paste the contents of docs/ai-install-prompt.md instead — it is self-contained and needs no network access.
Would rather do it by hand? Carry on below.
The shortest path from nothing to a working server. No config file, no clone — just environment variables and one container.
1. Collect one URL and one API key for each service you want to expose. See Find your API key if you don't know where they live.
2. Write them into a .env file:
cat > .env <<'EOF'
SONARR_URL=http://192.168.10.12:8989
SONARR_API_KEY=your-sonarr-api-key
RADARR_URL=http://192.168.10.14:7878
RADARR_API_KEY=your-radarr-api-key
EOFAny service you leave out is simply not exposed. One service is enough to start.
3. Check that the credentials work before wiring up a client, so a mistake shows up as a clear error rather than as a client that mysteriously has no tools:
docker run --rm --env-file .env ghcr.io/gauranshmathur/arr-mcp --checkOK sonarr/default (http://192.168.10.12:8989)
OK radarr/default (http://192.168.10.14:7878)
4. Add it to your client. For Claude Code:
claude mcp add arr -- docker run -i --rm --env-file /absolute/path/to/.env \
ghcr.io/gauranshmathur/arr-mcp --transport stdioThat is the whole setup. docs/clients.md has copy-pasteable blocks for Claude Desktop, Cursor, VS Code, Windsurf, Zed, Cline, Roo Code, Continue.dev, LibreChat, Goose and anything else that speaks MCP.
Use an absolute path for
--env-file. Your MCP client starts the server from its own working directory, which is rarely the one you were standing in when you created.env.
Run it once over HTTP and point every client at the same endpoint:
docker run -d --name arr-mcp --env-file .env -p 8080:8080 \
ghcr.io/gauranshmathur/arr-mcp
curl -s localhost:8080/health # {"status":"ok"}MCP is served at http://localhost:8080/mcp. The container defaults to
--transport http --addr 0.0.0.0:8080, so no arguments are needed. If you cloned the
repository, docker compose up -d does the same thing.
Every credential you hand ARR-MCP is full access to that application, so mutating tools are
gated by a policy. The default, confirm, asks you before any write or delete; readonly
hides mutating tools from the client entirely; full runs everything immediately. Any
instance can override the global policy. If writes are refused without a prompt, your client
does not support MCP elicitation: see docs/permissions.md for the
fallback and confirmScope settings.
Full copy-pasteable configuration for every client below lives in docs/clients.md. The two forms everything reduces to:
stdio — the client launches the process and talks over stdin/stdout:
docker run -i --rm --env-file /absolute/path/to/.env ghcr.io/gauranshmathur/arr-mcp --transport stdio
The -i is required: without it Docker gives the container no stdin and the JSON-RPC
handshake never completes.
HTTP — the server runs somewhere and the client connects to it:
http://localhost:8080/mcp
/health on the same port answers {"status":"ok"} and is not part of the MCP protocol;
it exists for container and Kubernetes probes.
Manifests for a Deployment, Service, ConfigMap and Secret template are in
deploy/kubernetes/, with a kustomization.yaml so they can be
pointed at directly by Argo CD or kubectl apply -k.
| Client setup | Copy-pasteable config for Claude, Cursor, VS Code, Windsurf, Zed and others |
| Configuration | Finding API keys, environment variables, config.yaml, multiple instances, CLI flags |
| Permissions | Modes, confirmation scope, per-instance overrides |
| Tools | Every tool by service, and what responses contain |
| Troubleshooting | 401, connection refused, missing tools, refused writes |
| Scope | What is covered, what is planned, and what is left out on purpose |
| Development | Building, testing, adding a service, releases |
Issues and pull requests are welcome. Start with docs/development.md; AGENTS.md holds the repository conventions.