Send any image to your Samsung Frame TV with one click.
"Docent finally made this click for me. In ~7 years I've never gotten images onto my Frame this easily." — community contributor
"This thing is spectacular... this should make life soo much easier to deal with my Frame TVs." — Frame TV owner
"Brilliant, found my next weekend project." — The Verge
Docent is a local web app that puts art on your TV. Drop an image in, press "Display on Frame," and it appears on your screen — no Samsung app, no USB drive, no cloud upload. It also manages your full gallery with a museum-quality interface: browse, organize into collections, crop to 16:9, and swap what's showing anytime. Add AI art identification, weather-aware recommendations, and Google Drive import.
- One-click display — browse your gallery and press "Display on Frame" to instantly show any artwork on your TV. No Samsung app needed
- Drag-and-drop upload with 16:9 compliance checking and built-in crop editor — images go straight to your TV's storage
- Dense gallery grid with hover title overlays, lazy-loaded thumbnails, lightbox preview, and keyboard navigation
- Automatic year grouping with adaptive bucketing and a sticky group navigation bar
- Matte selection (shadow box, modern, panoramic) and bulk operations
- Collections for organizing artwork into named groups
- Dynamic favicon that recolors to match the currently displayed artwork
- AI art analysis — two-stage pipeline using Google Vision for identification and Claude or OpenAI for rich analysis (artist, title, year, medium, movement, mood)
- Wikipedia integration — every metadata field (artist, school, medium, year, title) links to Wikipedia; group headers when sorted by artist or movement become entry points too
- Atmosphere — weather-aware recommendations that present three curated picks matched to local conditions, with poetic curator's notes and a variety engine that avoids repeats
- Google Drive sync — import artwork from a shared folder
- Art Mode toggle, brightness/color temperature controls, and slideshow configuration
- API usage tracking with per-model token counts and cost estimates
- Health check endpoint (
/health) for Docker and monitoring — returns data file integrity, directory writability, and uptime - Museum gallery design with light palette, serif typography, and curated motion
- One-click
Docent.commandlauncher with guided setup for non-technical users
Prerequisites: A Samsung Frame TV (2016+) on your local network. Python 3.10+ and uv are installed automatically if needed.
Linux users: Pillow may need system libraries. On Debian/Ubuntu:
sudo apt install libjpeg-dev zlib1g-dev
Double-click Docent.command in Finder. On first run, a guided setup wizard walks you through:
- TV connection — enter your Frame TV's IP address (found at TV Settings → General → Network → Network Status)
- AI art analysis — optionally configure Claude or OpenAI for automatic artwork identification
- Reverse image search — optionally add a Google Vision API key for web-based identification
All steps are skippable — you can configure them later in Settings. The script installs uv if needed, creates your .env and ai_config.json, starts the server, and opens your browser.
# Clone and enter the project
git clone https://github.com/danmunz/docent.git
cd docent
# Configure your TV's IP address
cp .env.example .env
# Edit .env and set DOCENT_TV_IP to your Frame's IP
# (find it at: TV Settings > General > Network > Network Status)
# Install and run
uv run python3 server.pyAlternatively, if you prefer pip:
pip install -r requirements.txt
python3 server.pyOpen http://localhost:8000 in your browser.
On first connection, your TV will prompt you to allow the remote connection — accept it on the TV. A token is saved locally so you won't need to re-authorize.
A sample artwork is included in assets/sample/ — drag it into the upload zone to get started. It's not 16:9, so the crop editor will open automatically; this is a good way to see how it works.
Docent's analysis pipeline has two stages:
- Google Vision (optional) — reverse-image searches museum databases and art sites to identify the painting. Free for 1,000 images/month. Results are passed as context to Stage 2.
- Claude or OpenAI — analyzes the artwork image (with Vision hints when available) and returns artist, title, year, medium, art movement, mood, and a description.
Configure everything through the Settings modal (gear icon in the header):
- Identification — toggle Google Vision on/off and enter your Cloud Vision API key
- Analysis — choose Claude or OpenAI, select a model, and enter your API key
- Automation — enable auto-analysis on upload
Artwork is analyzed on upload (if auto-analyze is enabled), or manually via the "Analyze" button in the detail panel. Batch analysis is available in Settings.
| Provider | Model | Input / Output per MTok | Est. per image |
|---|---|---|---|
| Claude | Sonnet 4 (default) | $3 / $15 | ~0.2c |
| Claude | Haiku 4.5 | $0.80 / $4 | ~0.06c |
| Claude | Opus 4 | $15 / $75 | ~1c |
| OpenAI | GPT-4.1 | $2 / $8 | ~0.1c |
| OpenAI | GPT-4.1 Mini | $0.40 / $1.60 | ~0.02c |
| OpenAI | GPT-4.1 Nano | $0.10 / $0.40 | ~0.005c |
| OpenAI | GPT-4o | $2.50 / $10 | ~0.13c |
Rough monthly example with Sonnet 4: upload 20 images (~4c), daily Atmosphere for a month (~6-18c), batch-analyze 100 images (~20c). The weather APIs (NWS and Open-Meteo) are free with no key required.
Click the cloud icon in the header. Docent reads your local weather via browser geolocation and the National Weather Service API (with Open-Meteo as fallback), matches it against your gallery's mood metadata, and presents three curated picks — each with a short curator's note. The top recommendation is marked "Curator's pick." Artwork titles link to Wikipedia so you can keep reading.
Click "Display" on any card to send it to your Frame. Click "Try Again" to exclude all three and get fresh suggestions. Exclusions persist for 24 hours via localStorage, so reopening the modal continues where you left off. A variety engine tracks recommendation history and weights candidates to avoid repeating the same picks across sessions.
Once artwork is analyzed, every metadata field in the detail panel becomes a quiet Wikipedia link — hover to reveal the ↗ indicator, click to open in a new tab. Artist names link to biographies, art movements to their Wikipedia articles, years to "YYYY in art" pages, and titles to search results.
When you sort the gallery by Artist, School, or Medium, the group headers become links too. The links are invisible until you hover — they reward curiosity without adding visual noise. No API keys required; all URLs are constructed client-side from existing AI metadata.
| Key | Action |
|---|---|
Escape |
Close lightbox / crop editor / settings / detail panel (innermost first) |
Left / Right |
Navigate between artworks in the detail panel or lightbox |
S |
Toggle selection mode |
R |
Refresh artwork grid |
Delete / Backspace |
Delete selected artwork (when in selection mode) |
Docent uses environment variables for server configuration and a browser-based Settings UI for AI keys and preferences.
Copy .env.example to .env and edit:
| Variable | Default | Description |
|---|---|---|
DOCENT_TV_IP |
(required) | Your Samsung Frame TV's IP address |
DOCENT_TV_MAC |
(unset) | TV's MAC address. When set, Docent sends a Wake-on-LAN packet to wake a sleeping Frame before retrying a connection. Find it with arp -n <tv-ip>. |
DOCENT_TV_PORT |
8001 |
TV WebSocket port |
DOCENT_TV_TIMEOUT |
10 |
Per-attempt TV connection/operation timeout in seconds |
DOCENT_TV_ATTEMPTS |
3 |
How many times to retry establishing a TV connection (the Frame often accepts the socket without answering the art handshake) |
DOCENT_TV_RETRY_DELAY |
2 |
Seconds to wait between TV connection attempts |
DOCENT_RELOAD |
(off) | Set to 1 to enable uvicorn auto-reload (development only — off by default so writing data files can't restart the server mid-operation) |
DOCENT_HOST |
0.0.0.0 |
Server bind address |
DOCENT_PORT |
8000 |
Server port |
DOCENT_LOG_LEVEL |
INFO |
Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
DOCENT_DATA_DIR |
project root | Directory for data files (.tv-token, caches, JSON config) |
API keys for Claude, OpenAI, and Google Vision are managed through the Settings modal in the browser — not via environment variables or config files. Settings are stored locally in ai_config.json (auto-created, git-ignored).
docent/
Docent.command # Double-click launcher with first-run setup wizard
server.py # FastAPI backend — TV control, AI pipeline, Drive sync
index.html # Single-page frontend (vanilla HTML/CSS/JS)
assets/ # Logo, fonts, and sample artwork
tests/ # 90 integration tests, run via pre-commit hook
pyproject.toml # Dependencies and project metadata
.env.example # Environment variable template
Data files are auto-created on first run and git-ignored: .tv-token, ai_config.json, api_usage.json, drive_sync.json, artwork_meta.json, collections.json.
Docker is the easiest way to run Docent on Linux, Unraid, Synology, or any home server.
Quick start (pre-built image, single copy-paste command):
docker run -d --network host -e DOCENT_TV_IP=192.168.1.XXX -v docent-data:/data --name docent ghcr.io/danmunz/docent:latestOpen http://localhost:8000 in your browser. Replace 192.168.1.XXX with your Frame TV's IP address.
Docker Compose (if you prefer):
git clone https://github.com/danmunz/docent.git
cd docent
cp .env.example .env
# Edit .env and set DOCENT_TV_IP
docker compose up -d--network host is recommended so the server can reach your TV on the local network. Data (artwork metadata, caches, TV token) persists in the docent-data volume.
The image includes a HEALTHCHECK that polls /health every 30 seconds. Container orchestrators (Docker, Portainer, Unraid) will automatically mark the container unhealthy if data files are corrupt or the data directory is unwritable.
# Run the server
uv run python3 server.py
# Run tests
uv run python3 -m pytest
# Install with test dependencies
uv pip install -e ".[test]"A pre-commit hook runs the full test suite and blocks commits that contain secret files (.env, ai_config.json, .tv-token) or API key patterns.
Built on:
- samsung-tv-ws-api by xchwarze (LGPL-3.0) — Samsung Smart TV WebSocket communication with Art Mode support. The core dependency.
- FastAPI (MIT), Uvicorn (BSD-3-Clause), Pillow (HPND), httpx (BSD-3-Clause), python-multipart (Apache-2.0)
AI identification uses the Google Cloud Vision API. Analysis supports the Claude Messages API and OpenAI Chat Completions API.
Sample artwork: Vincent van Gogh, The Starry Night (1889). Public domain, sourced from the Museum of Modern Art via Wikimedia Commons.
Inspired by ha-samsungtv-smart by TheFab21, which demonstrated the scope of Samsung's Art Mode API.
