Plex2Stash is a custom Plex Metadata Provider that seamlessly integrates with StashApp, designed for Plex Media Server. It bridges StashApp's rich metadata (scenes, performers, studios, tags) into Plex, enabling automatic metadata lookup and enrichment for your media library.
Runs on Docker and Synology NAS, with a Web UI for configuration and log viewing.
| Dashboard | Stash Configuration | Log Viewer |
|---|---|---|
![]() |
![]() |
![]() |
- Real Stash GraphQL integration — Scenes, performers, studios, tags mapped to Plex metadata
- Score Override — Forces Plex to accept match results (solves Japanese title mismatch; Plex silently rejects scores < 80)
- TV Show hierarchy — Show → Season → Episode structure with
/childrenendpoints - fieldSync — Per-stash metadata field filtering (title, summary, date, studio, tags, performers, poster, background)
- Image proxy — Plex fetches images without needing Stash API key
- Multi-provider fallback — Priority-based; primary stash fallback when no match found
- LRU caching — Match 5min, metadata 30min (avoids Stash SQLite DB lock)
- File-based logging — Daily JSONL logs with Web UI viewer (date, level, stashId filters)
- i18n — English, 繁體中文, 简体中文, 日本語
- Synology NAS Docker-ready — @eaDir defense (
.dockerignore, Dockerfile cleanup, layout design)
# docker-compose.yml
services:
plex2stash:
image: pomelosky/plex2stash:latest
ports:
- "8787:8787" # API (Plex provider)
- "3000:3000" # Web UI
volumes:
- /path/to/data:/data
restart: unless-stoppeddocker compose up -d- Open the Web UI at
http://NAS_IP:3000and add your Stash instance(s). - In Plex: Settings → Agents → Movies (or Shows) → Plex Movie → Manage.
- Add a custom metadata provider with URL:
http://NAS_IP:8787/providers/YOUR_STASH_ID - Run a metadata refresh on your library.
| Method | Path | Description |
|---|---|---|
| GET | /providers/:stashId |
Provider root (Plex discovery) |
| POST | /providers/:stashId/library/metadata/matches |
Match |
| GET | /providers/:stashId/library/metadata/:id |
Metadata |
| GET | /providers/:stashId/library/metadata/:id/children |
Children (Show→Season, Season→Episode) |
| GET | /providers/:stashId/library/metadata/:id/images |
Images |
| GET | /providers/:stashId/imageProxy?url=<encoded> |
Image proxy |
| Method | Path | Description |
|---|---|---|
| GET | /api/config/stashes |
List stashes |
| POST | /api/config/stashes |
Create stash |
| PUT | /api/config/stashes/:id |
Update stash (incl. fieldSync) |
| DELETE | /api/config/stashes/:id |
Delete stash |
| POST | /api/config/stashes/:id/ping |
Test connection |
| PUT | /api/config/stashes/reorder |
Reorder priorities |
| GET | /api/config/cache |
Cache stats |
| DELETE | /api/config/cache |
Clear cache |
| GET | /api/logs |
Query logs |
| GET | /api/logs/dates |
List available log dates |
Config is stored at /data/config.json. Example with fieldSync:
{
"stashes": [
{
"id": "default",
"name": "My Stash",
"endpoint": "http://192.168.1.100:9999",
"apiKey": "your-stash-api-key",
"enabled": true,
"priority": 0,
"fieldSync": {
"title": true,
"summary": true,
"date": true,
"studio": true,
"tags": true,
"performers": true,
"poster": true,
"background": true
}
}
]
}- Initial public release
- Stash GraphQL integration, Score Override, TV Show hierarchy, fieldSync, image proxy, multi-provider fallback, LRU cache, file-based logging with Web UI, i18n, Synology NAS support
Contributions are welcome. Please open an issue or pull request on GitHub.
MIT License — see LICENSE for details.


