A command-line digital asset manager built in Rust, designed for large collections of images, videos, and other media spread across multiple storage devices.
- Content-addressable storage — files identified by SHA-256 hash, enabling deduplication and integrity verification
- Multi-volume support — manage assets across external drives, NAS, and offline storage (terabytes scale)
- Variant grouping — automatically groups related files (RAW + JPEG + XMP) into a single asset by filename stem
- Recipe management — tracks processing sidecars from CaptureOne, Lightroom/XMP, RawTherapee, DxO, and ON1
- EXIF/XMP extraction — camera metadata, keywords, ratings, color labels, and descriptions extracted at import
- Bidirectional XMP sync — rating, tag, description, and label changes written back to
.xmprecipe files - Preview generation — thumbnails for images, RAW files (via dcraw/LibRaw), videos (via ffmpeg), waveform strips for audio (via ffmpeg), and info cards for documents
- Audio indexing — duration, sample rate, channels, bitrate and embedded tags extracted at import; optional key/BPM detection via external analyzers (
maki audio analyze);key:/bpm:/duration:filters and an in-browser player - Watch mode —
maki watchpolls directories and imports new files once they stop changing - Edit history & undo — every metadata edit is journaled;
maki undo/maki historyrevert or inspect field-level changes - Doctor & trash —
maki doctorchecks sidecar ↔ catalog consistency; deletions go to a retention-based trash (maki trash list/restore/empty) - Integrity verification — detect bit rot and corruption by re-hashing files against stored checksums
- Stacks — group burst shots and similar-scene images into collapsible stacks, showing only the "pick" in the browse grid
- Hierarchical tags — tree-structured keywords with Lightroom
lr:hierarchicalSubjectinterop - Saved searches & collections — smart albums (dynamic queries) and static albums (curated lists)
- AI auto-tagging — zero-shot image classification using SigLIP / SigLIP 2 vision-language models (four variants, including multilingual) for automated tag suggestions, visual similarity search via stored embeddings, and natural language image search via
text:filter (MAKI Pro) - Face recognition — detect faces with YuNet, generate ArcFace embeddings, auto-cluster into people groups, and manage named people across your catalog (MAKI Pro)
- Interactive shell —
maki shellREPL with named variables ($picks = search "rating:5"), tab completion, session defaults,.makiscript files, andsourcefor script composition - Web UI — browser-based interface with search, inline editing, batch operations, keyboard navigation, lightbox viewer, dark mode, grid density controls, calendar heatmap, faceted sidebar, visual similarity stroll page, per-tag review of AI suggestions before applying, and OS integration (reveal in Finder, open terminal)
- Flexible output — JSON on all commands, custom format templates, quiet mode for scripting
cargo build --release
# Initialize a catalog
maki init
# Register a storage volume
maki volume add "Photos 2024" /Volumes/PhotosDrive
# Import files
maki import /Volumes/PhotosDrive/Photos/
# Search and browse
maki search "tag:landscape rating:4+"
maki stats --all
# Start the web UI
maki serve
# Open http://127.0.0.1:8080
# Or use the interactive shell
maki shell
# photos> $picks = search "rating:5 date:2024"
# photos [picks=38]> export $picks /tmp/best
53 commands (95 leaf commands counting subcommands) covering setup, import, search, editing, maintenance, and more:
init · volume add/list/combine/split/rename/remove/set-purpose · import · watch · delete · export · contact-sheet · describe · search · show · preview · tag rename/split/delete/clear/scan/expand-ancestors/fix-unicode/export-vocabulary · edit · group · split · auto-group · auto-tag · auto-stack · embed · ai export-vocabulary · audio analyze · faces detect/download/status/cluster/clean/similarity/dump-aligned/people/name/merge/delete-person/unassign/export · stack create/add/remove/pick/dissolve/list/show/from-tag · duplicates · dedup · trash list/restore/empty · generate-previews · fix-roles · fix-dates · fix-recipes · create-sidecars · rebuild-catalog · undo · history · doctor · migrate · relocate · update-location · verify · sync · sync-metadata · refresh · cleanup · writeback · backup-status · status · stats · serve · doc · licenses · saved-search save/list/run/delete · collection create/list/show/add/remove/delete · shell
Global flags: --json, --log, --verbose, --debug, --time. Run maki --help or maki <command> --help for usage.
See the Command Reference for detailed documentation of every command, or the Search Filters Reference for the 40+ filter types available in maki search.
The system uses a two-tier storage model:
- YAML sidecar files are the source of truth for all metadata (human-readable, diffable, never lost)
- SQLite catalog is a derived index for fast queries (rebuildable from sidecars via
maki rebuild-catalog)
Assets live on media volumes (external drives, NAS) while the catalog stays local with enough data (index + thumbnails) to browse without media mounted.
See doc/architecture-overview.md for the system design and doc/component-specification.md for detailed component specs.
The full User Manual covers:
- User Guide — workflow-oriented guides from setup through maintenance
- Reference Guide — man-page style docs for every command, filter, and config option
- Developer Guide — REST API, module reference, and build/test instructions
Configuration is documented in the Configuration Reference. All settings live in maki.toml at the catalog root; every field is optional with sensible defaults.
- dcraw or LibRaw (dcraw_emu) — RAW file preview extraction
- ffmpeg — video thumbnail extraction and audio waveform strips
- ffprobe — video metadata (duration, codec, resolution, framerate); ships with ffmpeg
- curl — model file download for AI auto-tagging (only needed with
--features ai) and VLM image descriptions (maki describe) - keyfinder-cli and beat_this (optional) — musical key and BPM detection for
maki audio analyze; substitutes configurable via[audio]inmaki.toml
Install on macOS: brew install libraw ffmpeg curl
Install on Linux: sudo apt install libraw-bin ffmpeg curl (Debian/Ubuntu)
Install on Windows: winget install LibRaw.LibRaw Gyan.FFmpeg cURL.cURL or scoop install libraw ffmpeg curl
When missing, RAW and video files get an info card preview instead (audio files get an info card without the waveform strip, and maki audio analyze skips the missing analyzer). maki prints a warning on first use when a tool is not found.
Download the MAKI Pro binary or build with cargo build --features pro to enable AI-powered commands. This uses SigLIP vision-language models (via ONNX Runtime) for zero-shot image classification against a configurable tag vocabulary. Four models are available: SigLIP ViT-B/16-256 (~207 MB, default), SigLIP ViT-L/16-256 (~670 MB, higher accuracy), and the multilingual SigLIP 2 base/large variants (~410 MB / ~920 MB). Select with --model or [ai] model in maki.toml. Model files are downloaded from HuggingFace on first use. Commands: maki auto-tag for tag suggestion/application, maki embed for batch embedding generation, maki search "similar:<id>" for visual similarity search, maki search --image <file> to find the catalog assets similar to a local image that is not in the catalog (e.g. the original behind a preview — exact copies are matched by content hash first; in the web UI: the Find by image button, drag-and-drop, or paste), and maki search "text:\"sunset on the beach\"" for natural language image search. The web UI includes a Stroll page (/stroll) for graph-based visual exploration — pick an asset, see its nearest visual neighbors arranged radially, click through to explore connections. The "Suggest tags" and "Auto-tag" buttons also store embeddings opportunistically. Similarity search uses an in-memory index for sub-millisecond results at any scale. See the Configuration Reference for [ai] settings.
GPU acceleration (macOS): The pre-built macOS Pro binary includes CoreML support for hardware-accelerated inference on Apple Silicon (Neural Engine) and Intel Macs (Metal). Falls back to CPU automatically when CoreML is unavailable. Configure via [ai] execution_provider in maki.toml ("auto", "cpu", "coreml"). When building from source on macOS, add ai-gpu: cargo build --features pro,ai-gpu.
Download the MAKI Pro binary or build with cargo build --features pro. Uses two ONNX models: YuNet for face detection (bounding boxes + 5-point landmarks, ~230 KB) and ArcFace ResNet-100 FP32 for recognition (512-dim embeddings, ~261 MB). Each detected face is aligned to a canonical 112×112 template via a 5-point similarity transform before embedding — matching InsightFace's reference preprocessing.
CLI workflow: detect faces → cluster into groups → name people:
maki faces download # download YuNet + ArcFace models
maki faces detect --query "type:image" --apply # detect + embed faces
maki faces cluster --apply # group similar faces (HAC, default threshold 0.35)
maki faces people # list unnamed person groups
maki faces name <person-id> "Alice" # name a person
Diagnostic commands for tuning clustering:
maki faces similarity --query <scope> # histogram of pairwise similarities
maki faces dump-aligned --query <scope> # save aligned 112x112 crops for visual check
maki faces clean --apply # delete unassigned orphan faces
maki faces status # show per-model face counts and stale-embedding warnings
Web UI: /people page with person gallery and per-cluster browse links (works for both named people and unnamed clusters), asset detail face chips with assign/unassign, browse filter by faces: and person: that persists across pagination.
Data persistence: Face records (including recognition_model stamp for migration safety), people, and embeddings live in both SQLite and files (YAML + binary) for rebuild resilience.
Search filters: faces:any / faces:none / faces:N / faces:N+ (face count), person:<name> (matches name or person UUID). Config: [ai] face_cluster_threshold (default 0.35), [ai] face_min_confidence (default 0.7).
Download the MAKI Pro binary or build with cargo build --features pro to enable VLM-powered image descriptions. Works with any OpenAI-compatible API server (Ollama, LM Studio, vLLM).
ollama pull qwen2.5vl:3b # download a VLM
maki describe "description:none" --apply # describe undescribed assets
maki describe "date:2024-06" --mode tags --apply # suggest tags via VLM
maki describe --mode both --volume "Photos" --apply # both in one pass
maki import --describe /Volumes/Photos/NewShoot/ # auto-describe during import
Web UI: "Describe" button on asset detail page, batch "Describe" in browse toolbar. VLM availability is detected at server startup.
Auto-describe on import: maki import --describe generates descriptions for newly imported assets. Enable permanently with [import] descriptions = true in maki.toml. Silently skips if VLM endpoint is not available.
Config: [vlm] section in maki.toml — endpoint, model, max_tokens, temperature, timeout, mode, prompt, concurrency. CLI flags override config. Set concurrency to process multiple assets in parallel during batch describe. See the Configuration Reference for [vlm] settings.
Rust, SQLite, clap, axum, askama, htmx. See Cargo.toml for the full dependency list.
- Rust 2021 edition, Rust 1.89 or newer
- macOS, Linux, or Windows
Licensed under the Apache License, Version 2.0. See NOTICE for attribution.
