Fills in what other metadata providers leave empty: IMDb and TMDB ratings, the Rotten Tomatoes critic and audience scores, MDBList's own score, the release certification, the Common Sense Media minimum age, and basic facts such as year, release date, runtime, language, genres, and show status.
Silo shows the Rotten Tomatoes scores and the MDBList score only after an administrator turns them on under Settings > Library & Metadata > Ratings.
MDBList also aggregates Metacritic, Letterboxd, Trakt, Roger Ebert and MyAnimeList ratings. The plugin does not pass those on: their owners' terms restrict redistribution, and Trakt has blocked MDBList's API access.
Upgrading from 0.4 or earlier: the plugin stops refreshing those scores but
cannot delete the ones Silo already stored. A Silo server that reads
rating_sources hides them, because this plugin no longer declares them. An
older server keeps showing the last stored scores until they are removed on
the server.
This plugin never identifies an item. It has no search: Search returns zero
results by design, even though MDBList has a /search endpoint. It only looks
up titles that another provider has already matched, using the IMDb or TMDB ID
that provider resolved.
Silo runs a library's metadata providers as a priority-ordered chain and merges the results fill-empty, so the first provider to supply a field keeps it. Put a primary provider — TMDB — above MDBList. The primary resolves identity and fills the bulk of the record; MDBList then adds the ratings columns the primary had nothing for.
Given no IMDb or TMDB ID in the request, the plugin returns an empty result. It does not guess, and it does not fall back to searching.
| MDBList | Silo |
|---|---|
ratings[source=imdb] |
rating_imdb (0-10) |
ratings[source=tmdb] |
rating_tmdb (0-10) |
ratings[source=tomatoes] |
rating_rt_critic (0-100) |
ratings[source=popcorn|tomatoesaudience|audience] |
rating_rt_audience (0-100) |
the four sources above, plus the top-level score |
ratings.sources (0-100 with vote counts; see below) |
certification |
content rating |
age_rating + commonsense |
advisory_age / advisory_source |
year |
year |
released |
release date (movies) or first air date (shows) |
runtime |
runtime (movies only; a show's figure is not per episode) |
language |
original language |
genres |
genres |
status |
show status (shows only; the host normalises the spelling) |
Silo merges a library's providers fill-empty, so every one of these only lands where the primary provider left a blank. Genres go to whichever provider supplies them first.
Keywords and countries are not sent. Silo adds list fields from every provider
together instead of filling a blank, so MDBList's would be added to TMDB's on
every title. Its keywords are slugs (parent-child-relationship next to TMDB's
parent child relationship) mixed with MDBList's own tags such as
has-trailer and 2k-blu-ray: 0.3.0 appended about 24 of them per title.
Nothing else. The plugin maps no titles, overviews, taglines, artwork, trailers
or external IDs. MDBList's text is English only and would override the
library's language wherever the primary provider left a blank. The host keeps
every provider's trailers, so MDBList's would duplicate TMDB's. And an
enrichment-only provider must not hand the host identity it did not verify, so
MDBList's ids object is read only to match batch answers to requests.
MDBList reports each rating twice: value on the source's own scale and
score normalised to 0-100. The scales are not uniform — IMDb's value is out
of 10, TMDB's and Rotten Tomatoes' are out of 100 — so score is the input
wherever it is present, and the per-source conversion is pinned to
provider/testdata/movie_jaws.json.
Alongside the four flat keys, the ratings Struct carries a sources object:
{
"imdb": 8.1, "tmdb": 7.6, "rt_critic": 97,
"sources": {
"imdb": {"score": 81, "votes": 673852},
"tmdb": {"score": 76, "votes": 10114},
"rt_critic": {"score": 97, "votes": 102},
"mdblist": {"score": 86}
}
}Keys are imdb, tmdb, rt_critic, rt_audience, and mdblist. Every
score is 0-100; votes is omitted when MDBList has no count. Silo servers
that predate per-source storage read only number-valued keys and skip
sources, so the plugin sends it to every server version.
Silo names IMDb and TMDB itself. It keeps any other key only if the capability
declares it, so the manifest lists the other three under
capabilities[0].metadata.rating_sources, each with the short name clients
show beside the score (RT, RT Audience, MDBList), a longer label, and its
scale. A server that predates rating_sources ignores the declaration.
The Common Sense age has no typed field in the plugin API, so it rides in the
free-form metadata map under advisory_age and advisory_source, which the
host reads.
Requires a Silo server that reads lookup_provider_ids. Silo used to call
a metadata provider only when the item carried an ID of the provider's own,
which an enrichment-only provider never has. The manifest now declares
capabilities[0].metadata.lookup_provider_ids: ["imdb", "tmdb"], and servers
that understand the key call this plugin whenever the item carries either ID.
An older server ignores the key; the plugin then installs and configures but
contributes nothing.
Reports failures as errors, which older servers log as warnings. The
manifest also declares bulk_lookup_limit: 100, which opts the plugin into
Silo's bulk enrichment pass, and the plugin reports a spent quota, an outage or
a missing key as a gRPC error rather than an empty item (see below). Servers
with the pass log those errors at debug level. An older server logs one warning
per item it looks up while no key is saved, the key is rejected, the quota is
spent, or MDBList is down, and otherwise behaves as before.
A genuine 0% Rotten Tomatoes score is reported as "no score". Zero is the absent sentinel in the host's rating merge and columns, so it cannot currently be told apart from unrated; fixing it needs nullable rating fields host side.
- Create an API key in your MDBList preferences.
- Install the plugin and paste the key into its settings.
- Add MDBList to a library's metadata provider chain at a lower priority than the primary provider.
Without a key the plugin stays idle and contributes nothing.
MDBList meters requests per day: 1000 on the free tier, then 10k, 25k, 100k and 250k by paid tier, resetting at 00:00 UTC. Every tier is also capped at 1000 reads per fixed five-minute window.
- Batching. Silo asks for one item at a time but runs several match workers
at once, and its hourly Bulk Metadata Enrichment task keeps 100 lookups in
flight (the manifest's
bulk_lookup_limit). Lookups for the same route (IMDb or TMDB, movie or show) that arrive within 250 ms of each other go out as one request to MDBList's batch endpoint, up to 100 IDs. A lookup with no partner uses the ordinary single-title request. If MDBList refuses a batch, the plugin retries it in halves; when both halves go through, it remembers the smaller limit for that route. TMDB IDs are preferred over IMDb IDs for lookups because the batch endpoint's schema types IDs as integers. - Quota pause. When MDBList answers 429, the plugin stops sending requests
until
Retry-After(or, for the daily quota, until 00:00 UTC). When a successful answer reportsX-RateLimit-Remaining: 0, it pauses untilX-RateLimit-Resetwithout spending another request. Saving a different API key lifts the pause. - Pacing. A client-side limiter keeps requests at three a second, under the five-minute cap.
A metadata refresh never fails because of MDBList: Silo continues past a provider's error. A title MDBList does not know is an empty answer. Every other failure is a gRPC status, so Silo can tell "nothing to find" from "ask again later" and its bulk pass does not file a paused lookup as a title with no data:
| Failure | Status |
|---|---|
| Quota or burst limit spent, including while paused | RESOURCE_EXHAUSTED |
| No API key configured | FAILED_PRECONDITION |
| Key rejected (HTTP 401 or 403) | UNAUTHENTICATED |
| Outage: unreachable, HTTP 5xx, an error body answering a batch | UNAVAILABLE |
| MDBList refused or garbled one title's answer, including an error body | INTERNAL |
The plugin logs each failed request, and a quota pause once when it begins. It does not log a missing key: it simply stays idle until one is saved.
make build # host platform
make build-all # linux/amd64, linux/arm64, darwin/arm64