Plex Sync

:placard: Summary Refresh Plex metadata when scene updated in Stash. Requires the StashPlexAgent.bundle agent.
:link: Repository https://github.com/stashapp/CommunityScripts/tree/main/plugins/PlexSync
:information_source: Source URL https://stashapp.github.io/CommunityScripts/stable/index.yml
:open_book: Install How to install a plugin?

Stash Plugin updating your Plex metadata automatically

This plugin solves the problem of ā€œI have many files in my Plex, but they don’t get any of the changes I do in Stash, and doing a refresh all metadata takes too much timeā€.

With this, Stash behaves as the main source for all your Stash scenes in Plex, and it keeps Plex in sync with changes done via Stash.

Install

Install the plugin in Stash first, and then install the updated StashPlexAgent.bundle on your Plex server.

Stash side

  1. Install plugin via the CommunityScripts repository.

  2. Go to the install directory and install requirements: python3 -m pip install -r requirements.txt -t . – or, install the required packages globally python3 -m pip install stashapi unidecode requests

  3. Configure the plugin in Stash UI.

Plex side

Do this after making sure the Stash side is complete.

  1. After installing the newest version of this agent, make sure that AddPlexURL is enabled (ā€œAdds the Plex media ID to the scene in Stash; allows Stash to update Plex metadata.ā€)

  2. Refresh all metadata in Plex for the libraries using this agent.

Now, you should see scenes being updated in Stash, adding this URL to the scenes: plex/library/metadata/12345 (12345 being the metadata ID of the scene in Plex)

Usage

Update your scenes in Stash like normal, and these scenes will be automatically refreshed in Plex. :tada:

Warnings

  • If you have the ā€œclean titlesā€ option enabled in plugin, all titles are processed with unidecode. Basically, all non-ASCII characters in your titles will be converted; Cyrillic script for example will be taken away.

  • This plugin connects to your Plex via TLS, but it ignores cert errors. But this is not really a problem, as your Stash is most likely on the same host as your Plex…

4 Likes

How do you install the python modules when you run in docker?

I don’t use Stash in Docker, but it should be straightforward enough: on your host running the container, do docker exec -it stash /bin/sh – and now you’re inside the container.

Once inside the container, you can then cd ~/.stash/plugins/community/PlexSync. Then python3 -m pip install -r requirements.txt -t . and then all dependencies are installed.

You could also run something like apk add py3-unidecode inside the container and that’d fix the missing unidecode globally, as I assume that’s the only module missing from Stash vanilla container.

(Already replied on Github but better here for visibility :))

4 Likes

Usually my scenes are added to Plex immediately and then are scanned and added to Stash nightly. How do I ensure when they are added to Stash Plex gets updated with the identified scene?

Subject: Major Rewrite of Plex-Stash Integration - Seeking Guidance on Next Steps

I wanted to reach out before submitting a pull request, as my project scope evolved significantly from the original concept. What began as an attempt to add queuing functionality when Plex is down resulted in a complete rewrite of the integration.

I’ve been experiencing a persistent issue with my nightly backup process. When content arrives during the backup window, Plex either fails to identify it and assign metadata, or indexes it before Stash can process it. This resulted in unidentified content requiring manual intervention—a recurring frustration for several months.

Development Approach

After exploring ā€œvibe codingā€ techniques and experimenting with a tool called GSD, I attempted to address the core issue. However, the solution evolved into a comprehensive rewrite rather than incremental feature additions.

Current Implementation

The rewritten version eliminates the need for the Plex plugin, as it now pushes metadata directly from Stash. Current features include:

  • Updates: poster/background images, tags, collections, descriptions, performers, and titles

  • Planned: Configurable toggles for each metadata field

  • Event-driven: Creates a queue when scenes are updated in Stash (excludes scan/generate commands)

  • Comprehensive logging: Error, info, warning, and debug levels (refinement ongoing)

Repository & Installation

Repository: GitHub - trek-e/Stash2Plex: Plex synchronization tool

Installation: Add https://raw.githubusercontent.com/trek-e/PlexSync/main/index.yml as a source Note: Currently shares the same name as the community version, requiring removal of the existing plugin before installation.

Testing & Performance

  • Several hours of testing completed

  • Library filtering available (specify library by title for large servers)

  • Optimized for performance (tested with 30,000+ titles)

  • Multiple search methods implemented

Next Steps

Given that this project originated from your work, I wanted to consult with you before proceeding. Would you prefer that I: A) Rename this as a separate project, or B) Work toward incorporating it into the existing codebase?

I’m open to either direction and appreciate your guidance.

Hi! Then please use a different name, especially with such a large method change, to not induce confusion nor force a large change on anyone auto-updating.

Unfortunately, I have a condition where I often become physically sick when codereviewing vibe’d stuff, so I won’t dig deep into this… nothing personal… but a quick read shows some design flaws if I understand correctly:

  1. The plex.matcher has inefficient ways to match items (doing title search, and/or a full scan of library). And then you in the end do many different queries to ensure Media.Part.file path matches?
  2. How do you handle when there’s several different Plex libraries containing the same files? They get unique Plex metadata keys, but have the same Stash ID of course.
  3. What happens in reverse situation: where you’ve ingested stuff into Stash, but not yet into Plex?

If I was to do a big new thing like you, I’d instead go in the direction of building something via Plex’s ā€œnew Metadata Agentsā€ functionality. Though I’m not sure if that informs Stash what the final metadata ID was…

Or rather, tackle the initial problem:

When content arrives during the backup window, Plex either fails to identify it and assign metadata, or indexes it before Stash can process it.

You mean that some items in Plex are ā€œunmatchedā€, like @adrock63 wrote? An easy thing for you to vibe up would be to check /library/sections/${LIBRARYID}/all?unmatched=1&limit=1000&X-Plex-Token=… and then iterate PUT /library/metadata/${RATINGKEY}/refresh?force=1&X-Plex-Token=… ? And then it will refresh metadata on those in Plex → metadata refresh queries Stash → all matched properly. Because if the Plex library has only StashPlexAgent.bundle as its agent, media items will always remain unmatched if it didn’t get any correct match from Stash.

I still like the basic idea about your methods, because who knows when Plex will fully kill off unofficial Agents… but it’s way too overengineered for my taste – which is par for the course when vibing.

So thanks for asking, but no thank you. Please feel free to clarify more about any issues you were receiving, if it wasn’t specifically that ā€œPlex items go into an unmatched stateā€. Thanks!

no worries. I get the allergies. I have to take pills in the morning and at night to keep them at bay, and stay employed for the 12 or so more years before I can retire unless I win the lottery. It’s an exercise in teaching myself in my off hours.

With the PlexSync the problem I would have is my work flow is that the file gets put on the hard drive, and then the thing that puts it there tells stash and plex at the same time that its there. Plex almost immediately does its thing, while stash does all the generation stuff and then identifies the file. at that point, the ā€˜reverse update’ thing with the url linkages didn’t ever seem to take.

90% of the time, you could ā€˜refresh metadata’ and it’d fix it, the other 10% came around when my plex server goes down to do a nightly incremental backup. those have to be ā€˜find match’ first, then they update.