An MCP server that lets an agent (Hermes, Claude Code) drive your *arr media stack conversationally: search → request → track progress → refresh Jellyfin.
| Tool | Type | What it does |
|---|---|---|
search_tmdb(query) |
read | Find MOVIES on TMDB, return candidates + tmdb_id |
find_movie(term) |
read | Movie lookup via Radarr (also flags already-added) |
find_show(term) |
read | Show lookup via Sonarr, returns tvdb_id |
request_movie(tmdb_id) |
write | Add to Radarr + trigger search |
request_show(tvdb_id, monitor=) |
write | Add to Sonarr + trigger search |
download_status() |
read | Merged progress: Radarr+Sonarr queue ⋈ qBittorrent + SABnzbd |
refresh_jellyfin() |
read* | Trigger Jellyfin library scan |
ID-first design: request_* take stable IDs, never fuzzy titles. Always
search_*/find_* first, confirm the right title, then request_* with the
confirmed ID. This is the two-step pattern that keeps acquisition unambiguous.
Run on an LXC on VLAN 20 so it has native local access to Radarr/Sonarr/
qBittorrent/SABnzbd. Only ONE port (8770) is exposed to Hermes on VLAN 10 —
the *arr APIs themselves stay unexposed.
# On the VLAN 20 LXC, as root:
adduser --system --group --home /opt/media-mcp media
mkdir -p /opt/media-mcp && cd /opt/media-mcp
# copy media_mcp.py, requirements.txt, .env.example here, then:
python3 -m venv venv
./venv/bin/pip install -r requirements.txt
cp .env.example .env
chmod 600 .env
nano .env # fill in all six services' URLs + keys/creds
chown -R media:media /opt/media-mcp
# install the service
cp media-mcp.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now media-mcp
systemctl status media-mcp # confirm it's listening
# verify it's up (MCP streamable-http health):
curl -s http://127.0.0.1:8770/ # server responds (405/406 on bare GET is fine)- Hermes (VLAN 10) → media-mcp (VLAN 20): allow only
10.10.0.120→10.10.20.<mcp>:8770. This is the single hole; the *arr APIs are not exposed. - media-mcp → Jellyfin (RTX 5070 box): allow the MCP LXC to reach Jellyfin's IP:8096 (cross-boundary, since Jellyfin isn't on VLAN 20).
- Everything else (Radarr/Sonarr/qBit/SAB) is same-VLAN local — no rules needed.
Dashboard → MCP → Add server:
- Type: HTTP / SSE (URL)
- URL:
http://10.10.20.<mcp>:8770/mcp(streamable-http endpoint) - Test — should list the 7 tools.
- Enable.
Then in a Hermes session:
Find the movie Dune Part Two and show me the options.
Hermes calls search_tmdb, you confirm, it calls request_movie(tmdb_id),
and download_status() reports progress. Gate request_* for approval;
auto-approve the read tools.