This application helps organize an existing Lychee photo library into albums using artificial intelligence. It connects to a Lychee photo database and uses AI to generate descriptions for photos and albums, then provides intelligent suggestions for organizing unsorted photos.
The application supports two AI providers:
- Ollama: Local, open-source AI models (recommended for privacy and cost)
- OpenAI-compatible APIs: Including OpenAI, Azure OpenAI, and other compatible services
- Database: Running Lychee photo database (MySQL, PostgreSQL, or SQLite)
- AI Provider: Either:
- Ollama: Local instance with required models (recommended), OR
- OpenAI-compatible API: API endpoint and key
Add AI description columns to your Lychee database:
-- Add AI description columns to base_albums table
ALTER TABLE `base_albums`
ADD COLUMN `_ai_description` TEXT DEFAULT NULL,
ADD COLUMN `_ai_description_ts` TIMESTAMP NULL DEFAULT NULL;
-- Add AI description columns to photos table
ALTER TABLE `photos`
ADD COLUMN `_ai_description` TEXT DEFAULT NULL,
ADD COLUMN `_ai_description_ts` TIMESTAMP NULL DEFAULT NULL;-- Add AI description columns to base_albums table
ALTER TABLE base_albums
ADD COLUMN _ai_description TEXT DEFAULT NULL,
ADD COLUMN _ai_description_ts TIMESTAMP DEFAULT NULL;
-- Add AI description columns to photos table
ALTER TABLE photos
ADD COLUMN _ai_description TEXT DEFAULT NULL,
ADD COLUMN _ai_description_ts TIMESTAMP DEFAULT NULL;-- Add AI description columns to base_albums table
ALTER TABLE base_albums
ADD COLUMN _ai_description TEXT DEFAULT NULL;
ALTER TABLE base_albums
ADD COLUMN _ai_description_ts DATETIME DEFAULT NULL;
-- Add AI description columns to photos table
ALTER TABLE photos
ADD COLUMN _ai_description TEXT DEFAULT NULL;
ALTER TABLE photos
ADD COLUMN _ai_description_ts DATETIME DEFAULT NULL;Install Ollama and pull the recommended models:
ollama pull qwen2.5vl:3b # For image analysis
ollama pull qwen3:8b # For description synthesisYou can use OpenAI, Azure OpenAI, or any OpenAI-compatible API service. You'll need:
- API endpoint URL
- API key
- Model names (e.g.,
gpt-4ofor vision,gpt-4o-minifor text)
-
Copy the example configuration:
cp config.example.json config.json
-
Edit
config.json:With Ollama (using MySQL database):
{ "database": { "type": "mysql", "host": "localhost", "port": 3306, "username": "your_db_user", "password": "your_db_password", "database": "lychee" }, "ai": { "provider": "ollama", "endpoint": "http://localhost:11434", "image_analysis_model": "qwen2.5vl:3b", "description_synthesis_model": "qwen3:8b", "context_window": 40960 }, "server": { "host": "localhost", "port": 8080 }, "lychee": { "base_url": "https://your-lychee-installation.com" }, "albums": { "blocklist": [], "pinned_only": false } }With OpenAI (using MySQL database):
{ "database": { "type": "mysql", "host": "localhost", "port": 3306, "username": "your_db_user", "password": "your_db_password", "database": "lychee" }, "ai": { "provider": "openai", "endpoint": "https://api.openai.com", "api_key": "your-api-key-here", "image_analysis_model": "gpt-4o", "description_synthesis_model": "gpt-4o-mini", "temperature": 0.7 }, "server": { "host": "localhost", "port": 8080 }, "lychee": { "base_url": "https://your-lychee-installation.com" }, "albums": { "blocklist": [], "pinned_only": false }
}
Set `max_concurrent_requests` inside the `ai` block to control how many photo/album descriptions are generated in parallel (defaults to 4). Increase it only if your AI provider and database can comfortably handle the additional load.
**PostgreSQL Configuration Example:**
```json
{
"database": {
"type": "postgresql",
"host": "localhost",
"port": 5432,
"username": "your_db_user",
"password": "your_db_password",
"database": "lychee"
},
"ai": {
"provider": "ollama",
"endpoint": "http://localhost:11434",
"image_analysis_model": "qwen2.5vl:3b",
"description_synthesis_model": "qwen3:8b",
"context_window": 40960
},
"server": {
"host": "localhost",
"port": 8080
},
"lychee": {
"base_url": "https://your-lychee-installation.com"
},
"albums": {
"blocklist": [],
"pinned_only": false
}
}
SQLite Configuration Example:
{
"database": {
"type": "sqlite",
"database": "/path/to/lychee.db"
},
"ai": {
"provider": "ollama",
"endpoint": "http://localhost:11434",
"image_analysis_model": "qwen2.5vl:3b",
"description_synthesis_model": "qwen3:8b",
"context_window": 40960
},
"server": {
"host": "localhost",
"port": 8080
},
"lychee": {
"base_url": "https://your-lychee-installation.com"
},
"albums": {
"blocklist": [],
"pinned_only": false
}
}- Blocklist: Exclude specific album IDs from AI processing and suggestions
- Pinned Only: Restrict suggestions to pinned albums only (
is_pinned = true)
Common to all providers:
provider: Either"ollama"or"openai"endpoint: API endpoint URLimage_analysis_model: Model name for analyzing imagesdescription_synthesis_model: Model name for generating text descriptionstemperature: Sampling temperature (0.0-1.0, optional)top_p: Top-p sampling (0.0-1.0, optional)
Ollama-specific:
context_window: Maximum context length (recommended forqwen3:8b: 40960)options: Additional Ollama parameters
OpenAI-specific:
api_key: Your API key (required)
The old "ollama" configuration format is still supported for backward compatibility, but the new "ai" format is recommended.
brew install cdzombak/oss/lychee-ai-organizerInstall my Debian repository if you haven't already:
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://dist.cdzombak.net/keys/dist-cdzombak-net.gpg -o /etc/apt/keyrings/dist-cdzombak-net.gpg
sudo chmod 644 /etc/apt/keyrings/dist-cdzombak-net.gpg
sudo mkdir -p /etc/apt/sources.list.d
sudo curl -fsSL https://dist.cdzombak.net/cdzombak-oss.sources -o /etc/apt/sources.list.d/cdzombak-oss.sources
sudo chmod 644 /etc/apt/sources.list.d/cdzombak-oss.sources
sudo apt updateThen install lychee-ai-organizer via apt-get:
sudo apt-get install lychee-ai-organizerPre-built binaries for Linux and macOS on various architectures are downloadable from each GitHub Release. Debian packages for each release are available as well.
git clone https://github.com/cdzombak/lychee-ai-organizer.git
cd lychee-ai-organizer
make build
cp out/lychee-ai-organizer $INSTALL_DIR-
Run (if installed via package manager):
lychee-ai-organizer -config config.json
-
Run (if built locally):
./out/lychee-ai-organizer -config config.json
-
Access: Open
http://localhost:8080in your browser
Docker images are available for a variety of Linux architectures from Docker Hub and GHCR. Images are based on the scratch image and are as small as possible.
Run them via, for example:
docker run --rm -v /path/to/config.json:/config.json cdzombak/lychee-ai-organizer:1 -config /config.json
docker run --rm -v /path/to/config.json:/config.json ghcr.io/cdzombak/lychee-ai-organizer:1 -config /config.json- Generate Photo Descriptions: Click "Describe Photos" to analyze all unsorted photos
- Generate Album Descriptions: Click "Describe All Albums" to create album summaries
- Monitor Progress: Real-time updates show processing status
Important: Always run "Describe Photos" first, then "Describe All Albums" for optimal results.
- View Photos: Unsorted photos appear in the bottom filmstrip
- Navigate: Click thumbnails or use arrow keys to browse photos
- Get Suggestions: Three AI-recommended albums appear at the top
- Organize: Click an album button to move the photo
- Continue: The interface automatically advances to the next photo
- Retry Album Failures: Reprocess any albums that failed during description generation
- Navigation: Use Previous/Next buttons or arrow keys
- Photo Info: View title, date, and AI-generated description for each photo
Database Connection Failed
- Verify database credentials and connectivity
- Ensure schema modifications are applied
- For SQLite: Ensure the database file path is correct and writable
- For PostgreSQL: Ensure the database exists and user has proper permissions
Ollama Connection Failed
- Check Ollama is running on specified endpoint
- Verify models are pulled and available
No Photos Found
- Ensure unsorted photos exist in database
- Check
photo_albumtable reflects current organization
Prompt Truncation
- Increase
context_windowto 32768 or higher - Monitor Ollama logs for truncation warnings
- Image analysis requires significant computational resources
- Processing time scales with photo count and model size
- Consider using smaller models on limited hardware
GET /api/photos/unsorted- List unsorted photosGET /api/photos/suggestions?photo_id=<id>- Get album suggestionsPOST /api/photos/move- Move photo to albumPOST /api/rescan- Trigger AI processingWS /ws- WebSocket for real-time updates
- Designed for local, personal use only
- No authentication implemented
- Secure your MySQL database appropriately
- Do not expose to untrusted networks
GNU General Public License v3.0; see LICENSE in this repository.
Claude Code wrote this code with management by Chris Dzombak (dzombak.com / github.com/cdzombak).
