Smart Collection Builder for Plex — Let AI organize your movie library into meaningful collections.
PlexArr.AI scans your Plex movie library, uses Claude AI to identify franchises and cinematic universes, and lets you chat with AI to create custom collections by director, actor, theme, mood, or anything else you can think of. When you're happy with the results, sync them back to Plex with one click.
1. Scan → Cache your Plex library locally
2. Analyze → Claude AI identifies franchises & series
3. Review → Approve, reject, or customize suggestions
4. Chat → Ask for collections by theme, mood, decade...
5. Sync → Push approved collections to Plex
| Tab | What It Does |
|---|---|
| Scan & Analyze | Select a library, scan movies, then let Claude batch-analyze them for franchise groupings (Star Wars, MCU, etc.) |
| Review | Browse AI suggestions with movie thumbnails. Approve, reject, or bulk-action. Filter by status. |
| Chat & Customize | Conversational collection builder. Ask things like "Make a collection of Christopher Nolan films" or "Movies with a rainy noir vibe" |
| Sync to Plex | One-click sync of approved collections to your Plex server. Creates new collections and updates existing ones. |
- AI-Powered Analysis — Claude examines your entire library and suggests franchise/series groupings with explanations
- 3 Analysis Modes — Fresh Start, Smart Update (incremental for new movies), or Full Rescan
- Conversational Builder — Chat naturally with Claude to create bespoke collections
- Metadata Enrichment — Optionally enrich movies with genres, cast, director, and plot via OMDb or TMDB
- Vector Search — Semantic similarity search in chat ("movies like Inception") using Google or Voyage AI embeddings
- Quick Prompts — Preset ideas like "Director filmographies" or "Movies by decade"
- Dark Theme UI — Clean, modern interface inspired by GitHub's dark mode
- Background Workers — Long-running AI analysis happens in the background with live progress
- Fuzzy Matching — "Star Wars" matches "Star Wars Collection" when syncing to Plex
Create a docker-compose.yml:
services:
plexarr-ai:
image: ghcr.io/randomsynergy17/ransynsrv:latest
container_name: plexarr-ai
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
volumes:
- ./data:/data
ports:
- "8080:80"
restart: unless-stoppeddocker compose up -dNavigate to http://your-server:8080 and go to Settings.
| Setting | Where to Get It |
|---|---|
| Plex URL | Your Plex server address (e.g., http://192.168.1.100:32400) |
| Plex Token | Finding your Plex token |
| Claude AI | API key from console.anthropic.com — or use Claude CLI with OAuth |
| Feature | Provider Options | What It Adds |
|---|---|---|
| Metadata Enrichment | OMDb (free, 1k req/day) or TMDB (free) | Genres, director, cast, plot — improves AI accuracy |
| Vector Search | Google (text-embedding-004) or Voyage AI (voyage-3-lite) | Semantic search in chat: "movies with a dystopian feel" |
All optional features are configured in the Settings tab with test buttons to verify connectivity.
All settings can be configured via the web UI (saved to a JSON file inside the container) or via environment variables. The UI takes priority over env vars.
| Variable | Description | Default |
|---|---|---|
PLEX_URL |
Plex server URL | http://localhost:32400 |
PLEX_TOKEN |
Plex authentication token | — |
ANTHROPIC_API_KEY |
Claude API key | — |
METADATA_PROVIDER |
Metadata source: none, omdb, or tmdb |
none |
OMDB_API_KEY |
OMDb API key | — |
TMDB_API_KEY |
TMDB API key | — |
EMBEDDING_PROVIDER |
Embeddings: none, google, or voyage |
none |
EMBEDDING_API_KEY |
Embedding provider API key | — |
PUID / PGID |
User/Group ID for file permissions | 1000 |
TZ |
Timezone | UTC |
PHP_MEMORY_LIMIT |
PHP memory limit | 256M |
PHP_MAX_EXECUTION_TIME |
Max script execution time (seconds) | 300 |
PlexArr.AI is a single-container app built on RanSynSrv, an Alpine Linux base with Nginx, PHP-FPM 8.4, and s6-overlay process supervision.
┌─────────────────────────────────────────────┐
│ Browser (Alpine.js SPA) │
│ ├── app.js — UI logic & state │
│ ├── app.css — Dark theme styles │
│ └── index.php — SPA template │
├─────────────────────────────────────────────┤
│ PHP API Layer │
│ ├── scan.php — Library scanning │
│ ├── analyze.php — AI analysis trigger │
│ ├── chat.php — Conversational builder │
│ ├── collections.php — CRUD & Plex sync │
│ ├── settings.php — Configuration │
│ ├── status.php — Connection status │
│ ├── thumb.php — Plex thumbnail proxy │
│ └── logs.php — Application log viewer │
├─────────────────────────────────────────────┤
│ Shared Includes │
│ ├── config.php — Constants & helpers │
│ ├── db.php — SQLite connection │
│ └── log.php — Application logger │
├─────────────────────────────────────────────┤
│ Background Workers │
│ ├── analyze-worker.php — Batch AI calls │
│ ├── chat-worker.php — Chat responses │
│ ├── enrich-worker.php — Metadata & embeds│
│ └── sync-worker.php — Plex sync │
├─────────────────────────────────────────────┤
│ Integrations │
│ ├── plex.php — Plex API client │
│ ├── claude.php — Claude AI client │
│ ├── tmdb.php — TMDB metadata │
│ ├── omdb.php — OMDb metadata │
│ └── embeddings.php — Vector search │
├─────────────────────────────────────────────┤
│ Data │
│ └── SQLite (plexarrai.db) │
│ ├── movies — Cached library │
│ ├── collections — AI suggestions │
│ ├── movie_embeddings — Vector store │
│ ├── scan_history — Scan log │
│ └── app_logs — Application logs │
└─────────────────────────────────────────────┘
- SQLite — Zero-config database, persists in the container volume. No external DB needed.
- Background workers — AI analysis runs as a background PHP process with status-file polling, so the browser never times out on long operations.
- Packed float32 BLOBs — Embeddings stored as raw binary in SQLite. Cosine similarity computed in PHP (~2ms for 1,600 movies).
- UPSERT preservation — Re-scanning a library preserves enrichment data (genres, cast, etc.) instead of wiping it.
- Graceful degradation — No metadata key? No enrichment. No embedding key? No vector search. Everything still works.
PlexArr.AI supports three ways to authenticate with Claude:
| Method | How | Best For |
|---|---|---|
| API Key | Enter your sk-ant-api... key in Settings |
Most users |
| CLI OAuth | Run claude login in the web terminal |
Claude Max subscribers |
| Bearer Token | Pass an OAuth token via env var | Advanced setups |
The app uses Claude Sonnet for analysis (good balance of speed and quality). Each analysis batch processes ~250 movies.
- Free tier: 1,000 requests/day
- Signup: omdbapi.com/apikey.aspx
- Advantage: Uses IMDB IDs from Plex for direct lookup — no search needed, very reliable
- Provides: Genres, director, cast (top 4), full plot
- Free tier: Unlimited (with attribution)
- Signup: themoviedb.org/settings/api
- Advantage: Richer data including keywords and collection groupings (e.g., "Star Wars Collection")
- Provides: Genres, director, cast (top 5), plot, keywords, TMDB collection name
- Note: May be geo-restricted in some regions
Embeddings enable semantic search in the chat tab — ask for "movies similar to Interstellar" and get results based on meaning, not just keyword matching.
| Provider | Model | Dimensions | Free Tier |
|---|---|---|---|
| text-embedding-004 | 768 | Generous free quota | |
| Voyage AI | voyage-3-lite | 512 | Free tier available |
Embeddings are generated automatically during library scans and stored in SQLite as packed float32 BLOBs.
All data lives in the /data volume mount:
/data/
├── databases/
│ ├── plexarrai.db # SQLite database (movies, collections, embeddings)
│ └── plexarrai_settings.json # Saved settings (API keys, preferences)
├── webroot/public_html/ # Application code
├── log/ # Nginx & PHP logs
└── scripts/ # User scripts
Back up the databases/ directory to preserve your collections and settings.
The app tracks worker PIDs and detects stale status files (>3 minutes without update). If a worker dies, the next poll will show an error instead of spinning forever. Click "Analyze" again to restart.
Check that your Claude API key is valid in Settings (use the "Test" button). If using CLI OAuth, make sure you've run claude login in the web terminal first.
Make sure you've approved the collections in the Review tab, then clicked Sync to Plex in the Sync tab. Only approved collections are synced.
- Verify the API key works using the "Test" button in Settings
- Check that the Metadata Provider dropdown is set (not "None")
- Re-run a scan — enrichment happens during scanning for unenriched movies
MIT
Built with Claude AI and RandomSynergy17