Skip to content

RandomSynergy17/PlexArrAI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

89 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PlexArr.AI

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.


How It Works

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

The 4-Tab Workflow

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.

Features

  • 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

Quick Start

1. Deploy with Docker Compose

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-stopped
docker compose up -d

2. Open the UI

Navigate to http://your-server:8080 and go to Settings.

3. Configure (minimum required)

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

4. Optional Enhancements

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.


Environment Variables

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

Architecture

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 │
└─────────────────────────────────────────────┘

Key Design Decisions

  • 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.

Claude AI Authentication

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.


Metadata Providers

OMDb (Recommended)

  • 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

TMDB

  • 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

Embedding Providers

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
Google 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.


Data Persistence

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.


Troubleshooting

Analysis stuck or showing stale progress

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.

Scan works but analysis fails

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.

Collections not appearing in Plex

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.

OMDb/TMDB enrichment not working

  1. Verify the API key works using the "Test" button in Settings
  2. Check that the Metadata Provider dropdown is set (not "None")
  3. Re-run a scan — enrichment happens during scanning for unenriched movies

License

MIT


Built with Claude AI and RandomSynergy17

About

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.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors