kroeberd/mediastarr

By kroeberd

Updated 3 days ago

Automated media search for Sonarr & Radarr — multi-instance, Discord, SQLite, DE/EN | mediastarr.d

Image
Networking
Integration & delivery
Monitoring & observability
1

10K+

kroeberd/mediastarr repository overview

Mediastarr Logo

Mediastarr

EN · DE

Website Docker Hub GitHub Release License Discord Live Demo


Automated missing-content and quality-upgrade search for Sonarr & Radarr.
Runs on a configurable schedule, keeps a SQLite history, sends rich Discord embeds, and has a first-run browser wizard. No config file editing required.

Note: Independent project, built from scratch. Not affiliated with Huntarr.


🎮 Live Demo

Try it without installing anything:demo.mediastarr.de

The live demo runs a fully interactive mock of the Mediastarr UI — dashboard, settings, history, Discord preview, and stats. No Sonarr/Radarr connection needed.


✨ Features

FeatureDetails
📺 Multiple Sonarr instancesMissing + Upgrades · Episode / Season / Series mode
🎬 Multiple Radarr instancesMissing + Upgrades
🏷️ Custom namesSonarr 4K, Anime, Radarr HD — each with its own card
🧙 First-run wizardBrowser-based, no config file editing
🗄️ SQLite historyTitle, year, type, result, search count, timestamps
⏳ Cooldown1–365 days, resets automatically
📊 Daily limitMax searches/day (0 = unlimited)
🎲 Random selectionItems picked randomly per cycle for even coverage
⭐ IMDb filterMin. rating — global or per Sonarr/Radarr tab
🎯 Target resolutionOnly upgrade below your quality target
🔢 Upgrade daily limitSeparate limit for upgrades — global, per Sonarr/Radarr type, or per instance
🔒 API key censoringAPI keys are masked in activity log and never returned in API responses
⚡ Stalled download monitorAutomatically detects stuck downloads and triggers a new search (queue API-based)
⏱ JitterRandom ±N sec offset per cycle
🔔 DiscordRich embeds: poster + fanart, IMDb/TVDB/TMDB links, ratings, genres, runtime
📊 Stats reportPeriodic Discord embed with progress bar + per-instance table
🌐 MultilingualGerman & English (UI, logs, Discord messages)
🎨 4 themesDark / Light / OLED / System
🕐 TimezoneIANA timezone picker, respects TZ env var
🔒 SecurityCSRF protection, optional password, brute-force lockout, config.json set 0600
🖥 MSLogBrowser console logger: TRACE/DEBUG/INFO/WARN/ERROR with timestamps
📅 Per-instance daily limitEach instance can have its own search limit per day
💾 Config backupExport / import full config as JSON (incl. API keys)
🔓 Public API mode/api/state optionally accessible without login — for external tools
🏷️ Tag taggingAdd a tag to processed items in Sonarr/Radarr for easy filtering
🔖 Tag-based filteringPer-instance: only search items that carry specific tags (e.g. seasonal collections)
🔔 Separate Discord webhooksDifferent webhook URL for Sonarr vs Radarr notifications
🔗 Webhook triggerPOST /api/webhook/trigger — trigger a cycle from external automation
💾 Config export/importDownload config as JSON backup, restore on fresh instance
🆕 Update notificationsDashboard badge + sidebar indicator + Discord webhook when new version available
🔒 SecurityCodeQL hardened ping endpoints — exception data never exposed in API responses
💬 TooltipsNative browser tooltips on all settings inputs and action buttons
🎵 Lidarr ⚠Lidarr integration (EXPERIMENTAL) — missing album search, upgrade search, deep-link to artist
🔀 SubpathMEDIASTARR_BASE_URL=/mediastarr — run behind a reverse proxy under a URL prefix

🚀 Quick Start

docker run -d \
  --name mediastarr \
  --restart unless-stopped \
  -p 7979:7979 \
  -v /your/appdata/mediastarr:/data \
  -e TZ=Europe/Berlin \
  kroeberd/mediastarr:latest

Open http://your-server:7979 — the setup wizard starts automatically.

🐳 Docker Compose

services:
  mediastarr:
    image: kroeberd/mediastarr:latest
    container_name: mediastarr
    restart: unless-stopped
    ports:
      - "7979:7979"
    volumes:
      - /your/appdata/mediastarr:/data
    environment:
      - TZ=Europe/Berlin
      # - MEDIASTARR_PASSWORD=change-me   # optional

📦 Unraid

Install via Community Apps — search for Mediastarr.
Or use the template: mediastarr.xml

⚙️ Environment Variables

VariableDefaultDescription
TZUTCIANA timezone, e.g. Europe/Berlin
MEDIASTARR_PASSWORD(empty)Dashboard + API password. Leave empty for open access.
SONARR_URL(empty)Pre-fill Sonarr URL (skips wizard for this instance)
SONARR_API_KEY(empty)Pre-fill Sonarr API key (requires SONARR_URL)
RADARR_URL(empty)Pre-fill Radarr URL
RADARR_API_KEY(empty)Pre-fill Radarr API key (requires RADARR_URL)

🔔 Discord Notifications

Settings → Discord tab:

  1. In Discord: Right-click channel → Edit Channel → Integrations → Webhooks → New Webhook
  2. Copy the URL (https://discord.com/api/webhooks/ID/TOKEN)
  3. Paste into Mediastarr → SaveSend test

6 event types — each with a message preview in the UI:

EventEmbedColour
🔍 Missing searchedPoster + fanart, links, rating, genre, runtime, status🟢 Green
⬆️ Upgrade searchedSame as missing + current quality field🟡 Yellow
⏳ Cooldown expiredItem count, next run, cooldown setting🔵 Blue
🚫 Daily limit reachedProgress bar ████████░░, reset time🔴 Red
📡 Instance offlineError message, URL, service type⚫ Grey
📊 Statistics reportProgress bar, KPIs, per-instance table🟠 Orange

🛡️ Security

  • Optional password via MEDIASTARR_PASSWORD env var
  • CSRF token on all state-mutating requests
  • Brute-force protection: 10 failed logins → 5 min IP lockout
  • API keys never returned in /api/state responses
  • SSRF protection on all URL inputs
  • config.json chmod 0600 on every save
  • Security headers: X-Frame-Options, X-Content-Type-Options, Referrer-Policy, CSP

🔌 API Reference

All endpoints require authentication if a password is configured (header X-Api-Key: <your-password> or cookie session). Set public_api_state: true in config to expose /api/state without auth.

MethodEndpointDescription
GET/api/stateFull application state: running status, config, per-instance stats, cycle info
POST/api/controlControl the service — body: {"action":"start"} / {"action":"stop"} / {"action":"run_now"}
POST/api/configSave configuration — full config object in JSON body
GET/api/config/exportDownload current config as JSON
POST/api/config/importImport config from JSON
GET/api/instancesList all configured instances
POST/api/instancesAdd a new instance — body: {"type":"sonarr","name":"…","url":"…","api_key":"…"}
PATCH/api/instances/<id>Update instance fields (name, url, api_key, enabled, daily_limit, upgrade_daily_limit, search_upgrades, tag_enabled, tag_filter_ids, stall_monitor_enabled)
DELETE/api/instances/<id>Remove an instance
GET/api/instances/<id>/pingTest connectivity to a Sonarr/Radarr instance
GET/api/instances/<id>/tagsFetch available tags from the instance (for tag-filter UI)
GET/api/historyPaginated search history (SQLite) — params: ?page=1&per_page=50
GET/api/history/statsAggregate stats: total searches, per-year breakdown, result counts
POST/api/history/clearClear all search history
POST/api/history/clear/<id>Clear history for one instance
POST/api/webhook/triggerTrigger an immediate hunt cycle from external automation (e.g. Sonarr/Radarr webhooks)
POST/api/discord/testSend a Discord test notification
POST/api/discord/statsSend Discord stats report immediately
GET/api/log/statusGet current log file information
POST/api/log/rotateManually trigger log rotation
GET/api/timezonesList available IANA timezones
Webhook trigger example
curl -X POST http://your-server:7979/api/webhook/trigger \
  -H "X-Api-Key: your-password" \
  -H "Content-Type: application/json" \
  -d '{"source":"sonarr"}'

📸 Screenshots

DashboardSettingsDiscordMobile
DashboardSettingsDiscordMobile
DashboardSettingsDiscord
DashboardSettingsDiscord
HistoryDC NotificationsConsole Logger
HistoryNotifyConsole

🗺️ Roadmap / Ideas

  • Per-instance daily limits (v6.4.1)
  • Export/import config (v6.4.1)
  • Read-only API mode (no auth required for /api/state) (v6.4.1)
  • Skip upcoming/unreleased content (v6.4.3)
  • Scheduled maintenance windows (v6.4.4)
  • Per-instance upgrade toggle (v6.4.6)
  • Structured logging (DEBUG/INFO/WARN/ERROR) (v7.0.0)
  • Separate upgrade daily limit (v7.0.6)
  • Tag-based filtering per instance (v7.0.5)
  • Separate Discord webhooks for Sonarr/Radarr (v7.0.5)
  • Webhook trigger endpoint (v7.0.5)
  • Config export/import, update notifications, CodeQL hardening, tooltips (v7.1.2–v7.1.12)
  • Tagging of searched items in Sonarr/Radarr (v7.0.4)
  • API key censoring in logs (v7.1.0)
  • Stalled download monitor (v7.1.0)
  • Push via Gotify / Apprise (alternative to Discord)
  • Per-indexer or per-profile stall settings
  • Import list support

🔒 Why not Huntarr or its forks?

In February 2026, a public security audit of Huntarr v9.4.2 uncovered 21 vulnerabilities — 7 critical, 6 high. The most severe finding: a single unauthenticated HTTP request returned every API key for every connected *arr application in cleartext. No login required. The project's GitHub repository, subreddit and Discord were taken offline shortly after.

# Anyone on your network could run this against a stock Huntarr install:
curl -X POST http://huntarr:9705/api/settings/general \
  -H "Content-Type: application/json" \
  -d '{"proxy_enabled": true}'
# → Full config dump: Sonarr API key, Radarr API key, Prowlarr API key — all in cleartext

Community forks have appeared, but they inherit the same codebase. As the security researcher noted: "Fixing 21 specific findings doesn't fix the process that created them."

Mediastarr was built independently from scratch — with security as a foundation, not an afterthought.

Security findings: github.com/rfsbraz/huntarr-security-review (Feb 2026).



DE · EN


Automatische Suche nach fehlenden Inhalten und Qualitäts-Upgrades für Sonarr & Radarr.
Läuft nach einem konfigurierbaren Zeitplan, führt eine SQLite-Historie, sendet reiche Discord-Embeds und hat einen Browser-Einrichtungsassistenten. Kein Bearbeiten von Config-Dateien erforderlich.

Hinweis: Eigenständiges Projekt, von Grund auf neu entwickelt. Keine Verbindung zu Huntarr.


🎮 Live-Demo

Ohne Installation ausprobieren:demo.mediastarr.de

Die Live-Demo läuft als vollständig interaktive Simulation der Mediastarr-Oberfläche — Dashboard, Einstellungen, History, Discord-Vorschau und Statistiken. Keine Sonarr/Radarr-Verbindung nötig.


✨ Features

FeatureDetails
📺 Mehrere Sonarr-InstanzenFehlend + Upgrades · Modus: Episode / Staffel / Serie
🎬 Mehrere Radarr-InstanzenFehlend + Upgrades
🏷️ Eigene NamenSonarr 4K, Anime, Radarr HD — jede mit eigener Karte
🧙 Erster-Start-AssistentBrowser-basiert, keine Config-Datei nötig
🗄️ SQLite-HistorieTitel, Jahr, Typ, Ergebnis, Suchanzahl, Zeitstempel
⏳ Cooldown1–365 Tage, automatisches Zurücksetzen
📊 TageslimitMax. Suchen/Tag (0 = unbegrenzt)
🎲 Zufällige AuswahlItems zufällig gewählt für gleichmäßige Abdeckung
⭐ IMDb-FilterMindestbewertung — global oder pro Sonarr/Radarr-Tab
🎯 ZielauflösungNur upgraden wenn unter der Zielqualität
⏱ JitterZufälliger ±N-Sek-Offset pro Zyklus
🔔 DiscordReiche Embeds: Poster + Fanart, IMDb/TVDB/TMDB-Links, Bewertungen, Genre, Laufzeit
📊 Statistik-BerichtPeriodisches Discord-Embed mit Fortschrittsbalken + Instanz-Tabelle
🌐 MehrsprachigDeutsch & Englisch (UI, Logs, Discord-Nachrichten)
🎨 4 ThemesDark / Light / OLED / System
🕐 ZeitzoneIANA-Zeitzonenwahl, respektiert TZ-Umgebungsvariable
🔒 SicherheitCSRF-Schutz, optionales Passwort, Brute-Force-Lockout, config.json 0600
🖥 MSLogBrowser-Konsolen-Logger: TRACE/DEBUG/INFO/WARN/ERROR
📅 Pro-Instanz TageslimitJede Instanz kann ihr eigenes Tageslimit haben
💾 Config-BackupExport / Import der gesamten Konfiguration als JSON (inkl. API-Keys)
🔓 Öffentlicher API-Modus/api/state optional ohne Login erreichbar — für externe Tools

🚀 Schnellstart

docker run -d \
  --name mediastarr \
  --restart unless-stopped \
  -p 7979:7979 \
  -v /dein/appdata/mediastarr:/data \
  -e TZ=Europe/Berlin \
  kroeberd/mediastarr:latest

Öffne http://dein-server:7979 — der Setup-Assistent startet automatisch.

🐳 Docker Compose

services:
  mediastarr:
    image: kroeberd/mediastarr:latest
    container_name: mediastarr
    restart: unless-stopped
    ports:
      - "7979:7979"
    volumes:
      - /dein/appdata/mediastarr:/data
    environment:
      - TZ=Europe/Berlin
      # - MEDIASTARR_PASSWORD=change-me   # optional

📦 Unraid

Installation über Community Apps — nach Mediastarr suchen.
Oder Template verwenden: mediastarr.xml

⚙️ Umgebungsvariablen

VariableStandardBeschreibung
TZUTCIANA-Zeitzone, z.B. Europe/Berlin
MEDIASTARR_PASSWORD(leer)Dashboard + API-Passwort. Leer lassen für offenen Zugang.
SONARR_URL(leer)Sonarr-URL vorausfüllen (überspringt Wizard für diese Instanz)
SONARR_API_KEY(leer)Sonarr-API-Key vorausfüllen (benötigt SONARR_URL)
RADARR_URL(leer)Radarr-URL vorausfüllen
RADARR_API_KEY(leer)Radarr-API-Key vorausfüllen (benötigt RADARR_URL)

🛡️ Sicherheit

  • Optionales Passwort über MEDIASTARR_PASSWORD
  • CSRF-Token bei allen zustandsändernden Requests
  • Brute-Force-Schutz: 10 Fehlversuche → 5 Min. IP-Lockout
  • API-Keys nie in /api/state-Antworten enthalten
  • SSRF-Schutz auf allen URL-Eingaben
  • config.json chmod 0600 bei jedem Speichern
  • Sicherheits-Header: X-Frame-Options, X-Content-Type-Options, Referrer-Policy, CSP

🔌 API-Endpunkte

Alle Endpunkte erfordern Authentifizierung wenn ein Passwort konfiguriert ist (Header X-Api-Key: <dein-passwort> oder Session-Cookie). Mit public_api_state: true in der Config ist /api/state ohne Auth zugänglich.

MethodeEndpunktBeschreibung
GET/api/stateVollständiger App-State: Laufstatus, Konfiguration, Instanz-Stats, Zyklus-Info
POST/api/controlSteuerung — Body: {"action":"start"} / {"action":"stop"} / {"action":"run_now"}
POST/api/configKonfiguration speichern — vollständiges Config-Objekt als JSON
GET/api/config/exportAktuelle Konfiguration als JSON herunterladen
POST/api/config/importKonfiguration aus JSON importieren
GET/api/instancesAlle konfigurierten Instanzen auflisten
POST/api/instancesNeue Instanz hinzufügen — Body: {"type":"sonarr","name":"…","url":"…","api_key":"…"}
PATCH/api/instances/<id>Instanzfelder aktualisieren (name, url, api_key, enabled, daily_limit, upgrade_daily_limit, search_upgrades, tag_enabled, tag_filter_ids, stall_monitor_enabled)
DELETE/api/instances/<id>Instanz entfernen
GET/api/instances/<id>/pingVerbindung zu einer Sonarr/Radarr-Instanz testen
GET/api/instances/<id>/tagsVerfügbare Tags der Instanz abrufen (für Tag-Filter)
GET/api/historySuchverlauf (SQLite) — Parameter: ?page=1&per_page=50
GET/api/history/statsStatistiken: Gesamtsuchen, Jahresaufschlüsselung, Ergebnis-Counts
POST/api/history/clearGesamten Suchverlauf löschen
POST/api/history/clear/<id>Verlauf einer Instanz löschen
POST/api/webhook/triggerSofortigen Such-Zyklus auslösen — für externe Automatisierung (z.B. Sonarr/Radarr-Webhooks)
POST/api/discord/testDiscord-Test-Nachricht senden
POST/api/discord/statsDiscord-Statistik-Bericht jetzt senden
GET/api/log/statusAktuelle Log-Datei-Informationen abrufen
POST/api/log/rotateLog-Rotation manuell auslösen
GET/api/timezonesVerfügbare IANA-Zeitzonen auflisten
Webhook-Trigger Beispiel
curl -X POST http://dein-server:7979/api/webhook/trigger \
  -H "X-Api-Key: dein-passwort" \
  -H "Content-Type: application/json" \
  -d '{"source":"sonarr"}'

🗺️ Roadmap / Ideen

  • Pro-Instanz Tageslimits (v6.4.1)
  • Konfiguration exportieren/importieren (v6.4.1)
  • Read-only-API-Modus (kein Auth für /api/state) (v6.4.1)
  • Upcoming/unveröffentlichte Inhalte überspringen (v6.4.3)
  • Wartungsfenster (Pause zu bestimmten Uhrzeiten) (v6.4.4)
  • Pro-Instanz Upgrade-Toggle (v6.4.6)
  • Strukturiertes Logging (DEBUG/INFO/WARN/ERROR) (v7.0.0)
  • Separates Upgrade-Tageslimit (v7.0.6)
  • Tag-basierter Filter pro Instanz (v7.0.5)
  • Separate Discord-Webhooks für Sonarr/Radarr (v7.0.5)
  • Webhook-Trigger-Endpunkt (v7.0.5)
  • Config-Export/Import, Update-Benachrichtigungen, CodeQL-Härtung, Tooltips (v7.1.2–v7.1.12)
  • Tagging von durchsuchten Elementen (v7.0.4)
  • API-Key-Zensierung in Logs (v7.1.0)
  • Stalled-Download-Monitor (v7.1.0)
  • Push via Gotify / Apprise (Alternative zu Discord)
  • Pro-Indexer oder Pro-Profil Stall-Einstellungen
  • Import-Listen-Unterstützung

🔒 Warum nicht Huntarr oder seine Forks?

Im Februar 2026 deckte ein öffentliches Sicherheitsaudit von Huntarr v9.4.2 21 Schwachstellen auf — 7 kritisch, 6 hoch. Die schwerwiegendste: Eine einzelne unauthentifizierte HTTP-Anfrage gab jeden API-Key jeder verbundenen *arr-Anwendung im Klartext zurück — ohne Login. GitHub-Repo, Subreddit und Discord wurden kurz darauf abgeschaltet.

# Jeder im Netzwerk konnte das gegen eine Standard-Huntarr-Installation ausführen:
curl -X POST http://huntarr:9705/api/settings/general \
  -H "Content-Type: application/json" \
  -d '{"proxy_enabled": true}'
# → Vollständiger Config-Dump: Sonarr-API-Key, Radarr-API-Key, Prowlarr-API-Key — alles im Klartext

Community-Forks sind entstanden — sie erben aber dieselbe Codebasis. Wie der Sicherheitsforscher schrieb: „21 Findings zu fixen behebt nicht den Prozess, der sie erzeugt hat."

Mediastarr wurde unabhängig, von Grund auf neu gebaut — mit Sicherheit als Fundament, nicht als Nachgedanke.

Sicherheitsbefunde: github.com/rfsbraz/huntarr-security-review (Feb. 2026).

📸 Screenshots

DashboardEinstellungenDiscord
DashboardEinstellungenDiscord
VerlaufDC BenachrichtigungenConsole Logger
VerlaufBenachrichtigungenConsole

🤝 Contributing & Community

Made with ❤️ · mediastarr.de · Discord · Buy Me a Coffee

Tag summary

Content type

Image

Digest

sha256:449f5e7b4

Size

58.6 MB

Last updated

3 days ago

docker pull kroeberd/mediastarr:sha-3825518