Gelato: a Jellyfin plugin that turns AIOStreams addons into library items
Jellyfin Stremio Integration Plugin
At a glance
- What is it?
- Gelato is a Jellyfin plugin that connects a Jellyfin server to an AIOStreams addon so that addon titles appear in Jellyfin search and get imported into libraries on a schedule. It streams on demand through Jellyfin rather than downloading, and it only works with AIOStreams, which is the sharpest limit in the project.
- Who is it for?
- Gelato suits a Jellyfin operator who already runs AIOStreams and wants addon catalogs to behave like ordinary library items, searchable, playable in any Jellyfin client and requestable through Seerr. It does not suit anyone without AIOStreams, since the documentation states support for AIOStreams only, and it does not suit a server you cannot upgrade carefully, because the Jellyfin 10.11 to 12 path loses every Gelato title if the final 10.11 release is not installed first.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Gelato turns addon catalogs into ordinary Jellyfin library items
The problem Gelato addresses is that a Stremio-style addon lives in its own world. Its titles are searchable inside the addon interface, not inside your media server, and they never become items you can browse, resume or watch with progress tracking. Gelato is a Jellyfin plugin that closes that gap.
The mechanism has three parts, and they are worth separating because they fail independently. First, the plugin talks to an AIOStreams instance, which is a Stremio addon configuration service you can host yourself or point at a public instance. Second, the catalogs you select are imported into your Jellyfin library on a schedule, so the titles become regular library items rather than transient search results. Third, when you press play, Gelato asks the addon for streams at that moment, so nothing is downloaded to your server ahead of time.
That last part explains a feature that would otherwise look odd. Streams are proxied through Jellyfin, so a debrid service sees a single IP address rather than each client's. The plugin is not a downloader; it is a live bridge between an addon and a library.
The plugin is written in C#, with a solution and project file, and the source is laid out the way a Jellyfin plugin tends to be: Controllers, Services, Providers, ScheduledTasks, Filters, Decorators, a Frontend directory, and a Config directory. There is also a Makefile that handles the release process, and a build.yaml that carries the version.
The audience is a self-hosted media server operator. This is a plugin for a server you administer, not a consumer product.
Setup runs from AIOStreams configuration to a Jellyfin repository URL
The installation path has four steps, and the order matters because each one depends on the previous.
Step one is AIOStreams. You host it or use a public instance, and you need at least the TMDB addon turned on for search to work, plus one addon that finds streams. A starter configuration is included in the repository as aiostreams-config.json, and debrid providers are enabled under Services in the AIOStreams interface.
Step two is adding the plugin repository to Jellyfin. On Jellyfin 12 you add this URL to your plugin repositories.
https://raw.githubusercontent.com/lostb1t/Gelato/refs/heads/gh-pages/repository.jsonStep three is installing the plugin and running its Setup assistant, which walks through the addon, the libraries and the catalogs. Then the Libraries tab holds the Default movies library and Default series library settings, plus a New library option where Gelato creates the folder and a Copy folder button that gives you the path for Jellyfin's own library dialog.
Step four is the part that is easy to miss. In Jellyfin, for each library, the Gelato entry has to be first under the metadata downloaders and image fetchers. Gelato does not change the settings of a library you already had, so you turn it on yourself for those.
After that you can search for a movie and play it, or run the Import Catalogs scheduled task to fill the library in bulk. The documentation also points to a step-by-step setup guide in the repository discussions.
The plugin supports only AIOStreams, and that is stated twice, once in the setup steps and once in the notes. If your addon setup is not AIOStreams, Gelato is not an option.
The Jellyfin 12 upgrade path is the sharpest operational risk in the project
The documentation devotes more space to upgrading Jellyfin than to most features, and the reason is a data loss scenario.
If you are upgrading from Jellyfin 10.11, the instruction is to first update Gelato to its final 10.11 release and to shut the server down normally at least once before upgrading Jellyfin. That release empties the Gelato folders on shutdown. Without it, the first Jellyfin 12 start deletes every Gelato title.
So the upgrade order is not optional and it is not a matter of taste. Update Gelato first, restart or shut down cleanly once, and only then move Jellyfin forward. The settings page shows whether the server is ready for the upgrade.
If somebody upgraded without doing that, the mitigation is a scheduled task called Repair watch state, which Gelato runs once on the first start and which brings back every title that still has watch state. The same task also runs after every later major Jellyfin upgrade.
That task has a documented downside worth understanding before you reach for it. It has no schedule, because it cannot tell what you deleted on purpose from what you lost by accident, so it runs only when you start it manually. It also brings back titles you deleted yourself. And the documentation warns against running Jellyfin's own User data cleanup task first, since that task deletes the kept watch state.
There is a separate task for a genuine clean slate, called WARNING: purge all gelato items, which removes the watch state along with the titles. The two tasks are opposites: one restores, the other destroys, and confusing them is how a user loses progress.
Catalogs, libraries and how titles are routed
The routing model is more configurable than the setup steps first suggest, and the Catalogs tab is where it lives.
A catalog can import into a library of its own rather than the default one, which is how you keep Anime or Documentaries separate. On the Catalogs tab, the Library column lets you pick a library you already have, in which case Gelato adds a folder of its own to it. Pick New library and Gelato creates the folder, then you add a library with it in Jellyfin, because Jellyfin needs a folder for a new library. At the next import, new titles go there, and the titles that catalog imported before move there with their watch state.
Two behaviours follow from this that are worth knowing. A title listed by two catalogs stays with whichever one imported it first. And the library type filters what arrives: a movies library takes only the catalog's movies, a shows library only its series, and the rest goes to the default library. Setting the catalog back to Default moves its titles back.
Search inside such a dedicated library also asks the addon, and a result you open from that search goes into that library. So the addon is queried at browse time as well as at import time.
For watch state, the rule is that removing a title does not lose its progress. Jellyfin keeps it, and Gelato puts it back when the title returns, so a movie you delete and add again later still has your progress. What can go wrong is a bulk loss of titles, such as the Jellyfin 12 upgrade case, where the watch state goes with them.
There is a Refresh button on the Catalogs tab that makes Gelato read the addon again after you change the AIOStreams config. No restart is needed, and none is needed after changing Gelato's own settings either.
Seerr requests and per-user addons
Gelato accepts approved requests from Seerr, meaning Jellyseerr or Overseerr, and turns them into library items. The settings page on the Libraries tab lists the fields to copy into Seerr, and in Seerr you go to Settings, then Notifications, then Webhook.
The values are these: the Webhook URL is http://<your-jellyfin>:8096/gelato/seerr, the Authorization Header is MediaBrowser Token="<API key>", the JSON Payload stays at the default, and the Notification Types are Request Approved and Request Automatically Approved.
The API key comes from Jellyfin's Dashboard, under API Keys. The authorization header format is worth copying exactly rather than improvising, since the plugin validates it.
When a request is approved, the movie or series is added to your library, and Seerr marks it available at its next Jellyfin scan. A series request adds the whole series, even when the request named only some seasons. If the requester has their own libraries configured on Gelato's Users tab, the title goes to those instead of the shared library.
Per-user settings are the other feature in this area. A user can have their own addon, which is what you want for a kids' account where the content source differs. The Users tab is where those libraries live, and it is the same mechanism that decides where a Seerr-requested title lands.
For stream resolution, the documentation suggests a lower timeout for Stremio addons in AIOStreams, for example 5 seconds, and warns that Debridio TMDB and Debridio TVDB cause problems, suggesting the regular TMDB addon instead.
The repository layout and a release pipeline driven by git-cliff
The C# project sits in a Jellyfin plugin shape, with the entry points named for the roles they play. GelatoManager.cs and GelatoStremioProvider.cs handle the plugin lifecycle and the addon communication, Plugin.cs and ServiceRegistrator.cs do the registration work, and Common.cs holds shared code. The Frontend directory holds the configuration UI, which is what produces the Setup assistant, the Libraries tab, the Catalogs tab and the Users tab you interact with.
The build metadata is in build.yaml, which carries the version, and the project file Gelato.csproj. There is a global.json, so the .NET SDK version is pinned.
The release process is automated through a Makefile, and the two targets are release and test. What the release target does is instructive about how the project ships.
git fetch --tags
$(eval NEW_VERSION := $(shell git cliff --bumped-version))
@git cliff --unreleased --tag $(NEW_VERSION) --strip all > /tmp/release_notes.md
sed -i 's/^version: .*/version: "$(NEW_VERSION:v%=%)"/' build.yaml
sed -i 's#<Version>[^<]*</Version>#<Version>$(NEW_VERSION:v%=%)</Version>#' Gelato.csproj
git commit -m "chore(release): bump version to $(NEW_VERSION)"
git push
gh release create $(NEW_VERSION) --title "$(NEW_VERSION)" --notes-file /tmp/release_notes.mdThe version is derived from git-cliff, which reads the commit history, and the changelog for the release is generated by the same tool from the unreleased commits. The version is then written into both build.yaml and the project file, in a comment noted as keeping local builds in step so a dev build reports the version its plugin folder and meta.json carry. The release itself is created with the GitHub CLI.
The release cadence visible in the tags is fast: v0.26.27.0, v0.26.26.0 and v0.26.25.0 landed on consecutive days around 2026-10-16 to 2026-10-19, and the last push was on 2026-10-20. The project is GPL-3.0 licensed, with the LICENSE file at the root, which is the copyleft licence that suits a plugin whose source you install onto your own server.
Where Gelato is the wrong tool
The first wrong-tool case is a server that does not run AIOStreams. The documentation states support for AIOStreams only, twice, and there is no alternative addon provider in the plugin. If your Stremio setup is a collection of individual addons configured elsewhere, Gelato has nothing to talk to.
The second case is a Jellyfin server you cannot upgrade carefully. The Jellyfin 12 path requires a specific ordered sequence, and getting it wrong deletes every Gelato title. On a managed or locked-down server where you cannot install the final 10.11 release of the plugin and perform a clean shutdown first, that risk is not yours to take. The plugin is also a Jellyfin plugin rather than a standalone service, so it inherits whatever constraints your server imposes on plugin installation and filesystem access.
The third case is a user who wants their own downloads. Gelato streams on demand and nothing is downloaded, and the titles behave as library items but they are not files in your possession. If the goal is an offline library, this plugin is not that.
A further caveat is the plugin's dependence on the upstream addon's uptime and configuration. Catalog imports and stream lookups are requests to an addon that Gelato does not control, and a slow or misconfigured AIOStreams instance turns into slow or failed imports. The advice to lower the addon timeout is really an acknowledgement of that.
The documentation also points to Remux, a media server written in Rust that the author describes as the next evolution of Gelato: it replaces Jellyfin instead of plugging into it, supports local libraries, remote sources and Stremio addons, and works with existing Jellyfin clients. That is a different architecture with a different operational profile, and a team that is starting fresh rather than extending a Jellyfin install should look at that comparison before settling on a plugin.
Editorial conclusion
Gelato suits a Jellyfin operator who already runs AIOStreams and wants addon catalogs to behave like ordinary library items, searchable, playable in any Jellyfin client and requestable through Seerr. It does not suit anyone without AIOStreams, since the documentation states support for AIOStreams only, and it does not suit a server you cannot upgrade carefully, because the Jellyfin 10.11 to 12 path loses every Gelato title if the final 10.11 release is not installed first. Before adopting, confirm your AIOStreams instance has at least one search-capable catalog such as TMDB enabled, and if you are on Jellyfin 10.11, install the final 10.11 release of Gelato and shut the server down normally once before upgrading.
Frequently asked questions
What does the Gelato Jellyfin plugin do?
Gelato connects Jellyfin to an AIOStreams addon so that addon titles show up in Jellyfin search, and the catalogs you pick are imported into your library on a schedule. The imported titles behave like ordinary library items and can be played in any Jellyfin client.
Does Gelato download the media it imports?
No. Streams are found when you press play, and nothing is downloaded in advance. The streams go through Jellyfin as a proxy, so a debrid service sees a single IP address.
How do I upgrade to Jellyfin 12 without losing my Gelato titles?
First update Gelato to its final 10.11 release and shut the server down normally at least once, because that release empties the Gelato folders on shutdown. Without it, the first Jellyfin 12 start deletes every Gelato title, and the Repair watch state task can bring back titles that still have watch state.
Which addons does Gelato support?
Gelato supports only AIOStreams, which the documentation states both in the setup steps and in the notes. You need at least one search-capable catalog such as the TMDB addon turned on in AIOStreams, plus one addon that finds streams.
How do I connect Gelato to Jellyseerr or Overseerr?
In Seerr go to Settings, Notifications, Webhook, and set the URL to http://<your-jellyfin>:8096/gelato/seerr with the Authorization Header MediaBrowser Token="<API key>" using a key from Jellyfin's Dashboard under API Keys. Leave the JSON payload at its default and enable Request Approved and Request Automatically Approved.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lostb1t-gelato)Was this useful?