arr-metadata-server
A self-hosted metadata server for your media stack. It speaks the protocols Sonarr, Radarr and TMDB clients already use, keeps its own canonical copy of everything it serves, and lets you correct or invent entries by hand — with manual edits permanently protected from automatic refreshes.
Documentation: https://dim145.github.io/arr-metadata-server/, built from
docs/ and this README.
What it serves
Section titled “What it serves”| Who asks | What it is served | Where |
|---|---|---|
| Sonarr v4 and v5 | Skyhook, in skyhook.sonarr.tv’s place, and Sonarr’s alternate titles, in services.sonarr.tv’s |
the clients’ door |
| Radarr | its metadata API, in api.radarr.video’s place |
the clients’ door |
| Jellyseerr, Overseerr and other TMDB clients | the TMDB API, relayed from api.themoviedb.org with the corrections made here written in |
the clients’ door |
| Yamtrack, Jellyfin’s TheTVDB plugin, Kodi’s scraper, the anime trackers | TheTVDB’s and AniList’s APIs, relayed the same way | the clients’ door |
| Plex Media Server 1.43 or later | a custom metadata provider, /plex |
the interface’s door |
| Kometa, Kodi, Jellyfin, calendar apps, feed readers | Kometa’s metadata file, lists, iCalendar and Atom feeds; .nfo documents with their artwork, written to a directory |
the interface’s door |
| You | the catalogue to browse, its administration, and the API behind both (/api/v1) |
the interface’s door |
The interface’s door is AMS_BIND_ADDRESS (0.0.0.0:8080). The clients’ door,
AMS_CLIENTS_BIND, answers on 443 in TLS under the names the clients have compiled in, with a
certificate from an authority the server makes; resolving those names to the server is what
points a client at it. Behind both is one catalogue, filled from TMDB, TheTVDB, Sonarr’s and
Radarr’s own services and Fanart.tv, and — when switched on — TVmaze, AniList, MyAnimeList,
IMDb and Fankai.
Quick start
Section titled “Quick start”From a checkout of this repository, with Docker Compose:
cp .env.example .env# set AMS_TMDB_API_KEY, and AMS_ADMIN_USERNAME / AMS_ADMIN_PASSWORD (twelve characters at least)docker compose up -dThe interface is then on http://localhost:8080; sign in with the administrator the
environment names. The image is ghcr.io/dim145/arr-metadata-server, for amd64 and arm64.
PostgreSQL instead of SQLite, building from source and checking the image are in
Installing and running.
Pointing Sonarr, Radarr and Plex at it
Section titled “Pointing Sonarr, Radarr and Plex at it”Sonarr and Radarr cannot be given another metadata address: it is compiled in. So the names they call are made to lead here, as Pointing your stack at this server walks through in full:
- Open the clients’ door:
AMS_CLIENTS_BIND=0.0.0.0:443, with the server at a fixed address on the stack’s network. - Resolve
skyhook.sonarr.tv(andservices.sonarr.tv, for the alternate titles) in Sonarr, andapi.radarr.videoin Radarr, to that address —extra_hostsin Compose, or your resolver. - Make them trust the server’s authority:
/ca.crt, anddocker/trust-ca.shfor a linuxserver.io container. - Allow their addresses on Keys & network in the administration; they send no key.
- For Plex Media Server, add a metadata provider at
http://<this server>:8080/plexunder Settings › Metadata Agents, and allow Plex’s address: see Plex.
From then on a correction made here reaches them at their next refresh, or at once with Telling them of a change on.
Documentation
Section titled “Documentation”On the site, or in docs/:
- What it does — everything it serves and keeps, in one list.
- Installing and running — Compose, PostgreSQL, from source, verifying the image, moving between databases, development.
- Configuration — what is a setting and what is an environment variable, and every variable with its default.
- Pointing your stack at this server — Sonarr, Radarr and the TMDB, TheTVDB and AniList clients: the clients’ door, trusting its authority, allowing the clients through.
- Sonarr and Radarr — what Sonarr v4, Sonarr v5 and Radarr are given, and connecting your own Sonarr and Radarr: telling them of a change, filling the catalogue from their libraries.
- Plex — Plex Media Server taking its metadata from this server, as a custom metadata provider.
- The relays — the TMDB, TheTVDB and AniList relays: whose key TMDB and TheTVDB are asked with, what is written into the answers and what is taken out of them.
- Where the data comes from — the sources, how they are merged, whose episode numbering wins, and the further sources.
- Languages — what each client is answered in.
- Notifications — telling what happens to Standard Webhooks receivers, Discord, Slack, ntfy, Gotify and Apprise: tries, log and replay.
- Exports — Kometa’s metadata file, selections as text files, lists and
feeds, calendars, and
.nfodocuments with their artwork. - Editing the catalogue — locks per language, hiding what the sources gave, the catalogue’s register and its actions on many works, the order of the sources, and the dashboard’s list of what there is to do.
- Data — release dates and ratings by country, the schedule, and what a work carries besides: tagline, writers, Wikidata, AniList’s format.
- The site and the administration — the bar along the foot of a phone, the catalogue as a list, the Settings page and the Jobs page.
- Keeping the media — pictures and themes fetched once and kept, on disk or in a bucket.
- Accounts and access — what each surface asks for, browsing without an account, sign-ups, the identity provider, adult titles, the list of allowed addresses.
- What is closed, and how — what to know before the server is reachable from anywhere, and the audit trail.
- Behind a reverse proxy — nginx, Traefik and Caddy in front of the
interface,
AMS_PUBLIC_URLandAMS_TRUSTED_PROXIES, and what to keep off the internet. - Caching, and a cache server and Several instances — Valkey or Redis behind the memory, and several instances run as one.
- The API — where it is documented, and how a key is presented.
- Settings reference — every setting, what it holds and what it starts as, written from the code.
Verifying the image
Section titled “Verifying the image”An image published from a tag is signed, carries its build provenance and an SBOM, and lists the crates inside its binary. The commands that check each are in Installing and running.
Development
Section titled “Development”cargo test # the repository tests use an in-memory SQLitecargo clippy --all-targetscargo fmt --check
cd frontend && npm ci && npm run dev # UI on :5173, proxying to :8080scripts/smoke.sh starts the server against a database URL and walks the paths
that matter, then stops it:
cargo build./scripts/smoke.sh 'sqlite://data/smoke.db?mode=rwc'./scripts/smoke.sh 'postgres://ams:ams@127.0.0.1:5432/ams'CONTRIBUTING.md says the rest.
Licence and credits
Section titled “Licence and credits”MIT — see LICENSE.
It grew out of two earlier, private tools — a TMDB relay and a stand-in for Sonarr’s metadata service — and does what both did, from one catalogue.
The metadata comes from TMDB, TheTVDB, Sonarr’s and Radarr’s own metadata services, Fanart.tv, and, when they are switched on, TVmaze, AniList, MyAnimeList through its API, Jikan or Tenrai, IMDb’s datasets, Fankai and its community’s wiki; the Fribb anime-lists map anime between them. Each provider’s terms apply to what is fetched and kept, and every public page credits the sources that are on. This product uses the TMDB API but is not endorsed or certified by TMDB.