A beautiful, open-source photo library that scales to huge collections. Bring your own storage, agent/MCP-native. Early concept.
- ✓Open-source license (Apache-2.0)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Documented (README)
git clone https://github.com/jay-the-maker/albumenTools overview
# Albumen
Albumen: the open-source alternative to iCloud Photos, Google Photos and Frame.io.
The commitment is [DESIGN_PHILOSOPHY.md](DESIGN_PHILOSOPHY.md). Read it before changing this repository.
**First principle: metadata and original quality are never lost. Sources are read-only, forever.** A user's archive may be their only copy.
Originals are stored bit-exact: Albumen does not recompress, transcode, or strip them. EXIF, XMP, IPTC, and GPS stay. Sidecars stay. Live Photo pairs, RAW+JPEG pairs, and Android motion photos stay. Edits are non-destructive and are stored alongside the originals. Timestamps and filenames are preserved. Every copy is checked with SHA-256 and fails loudly on mismatch. The default path never removes or alters a source. Scan, export, and upload read a source only through a read-only open. A destination inside that source is refused, and there is no override.
Albumen is an open-source photo library with the feel of classic iPhoto, built to keep working when the library is hundreds of thousands of items and multiple terabytes. You bring the storage. Agents can read the library; they do not get tools that delete or rewrite originals.
**Status: early-stage.** `albumen-mcp` is in this repository. It speaks MCP over stdio. Search and browse are on, including metadata search (capture date, camera, lens, a GPS box, and XMP/IPTC keywords and captions). Export and upload are off until that process is started with `--enable-export` or `--enable-upload`. There is no delete tool. The native apps and the on-disk catalog are not built yet. Ingest copies an original plus its sidecars, preserves filename and mtime, and verifies SHA-256. It does not delete sources.
## Vision
Open the library and browse by time, place, and faces the way iPhoto did: quiet, fast, and obvious. The library underneath has to be boringly careful. A photo you took in 2009 is still that file in 2039, with the same bytes, the same name, and the same time and place.
Albumen is not a hosting service. Storage stays where you put it:
- Local disk, NAS, SMB, SFTP, WebDAV, S3, and Backblaze B2, reached directly or through rclone.
- Google Drive and Dropbox through the synced folder you already have. Albumen treats that folder as a filesystem.
- An iCloud Photos download, export, or Photos library copy imports into the library you choose, with those originals kept bit-exact.
Clients:
- macOS, SwiftUI and AppKit.
- iOS, Swift, with automatic camera-roll backup.
- Android, Kotlin, with automatic camera-roll backup.
The backup apps call the same ingest path as a drag-and-drop import. They do not recompress on the way in.
## Install from source
The toolchain in CI is Rust 1.99.1. The workspace asks for 1.94 or newer. Metadata search needs ExifTool on `PATH`. `scripts/install-exiftool.sh` downloads Image-ExifTool 13.59 and checks its SHA-256. It does not use a distro package.
```bash
git clone https://github.com/jay-the-maker/albumen.git
cd albumen
cargo build --release --locked
export PATH="$(scripts/install-exiftool.sh):$PATH"
./target/release/albumen-mcp --library ./library
./target/release/albumen export --from ./library --to /backup/library --apply
```
`albumen export` and `albumen-receive` print a plan and write nothing until `--apply` or `--execute`. `albumen scan` only reads. The safety ladder, the per-binary threat model, and how to check a release are in [docs/test-ladder.md](docs/test-ladder.md), [docs/threat-model.md](docs/threat-model.md), and [docs/release-verify.md](docs/release-verify.md).
That build produces `albumen-mcp`, `albumen`, and `albumen-receive`.
The container is the same server. The image entrypoint is `albumen-mcp --library /library`, and the image contains that pinned ExifTool. Search and browse only read the mounted directory. Append `--enable-export` or `--enable-upload` to turn those tools on. There is still no delete tool.
```bash
docker build -t albumen-mcp .
docker run --rm -i --mount type=bind,src="$PWD/library",dst=/library,readonly albumen-mcp
```
That mount is read-only. A writable directory for opt-in export or upload is a separate mount at `/destination`, not the library of originals. Tag `v0.1.1` publishes `ghcr.io/jay-the-maker/albumen-mcp:0.1.1` and the [server.json](server.json) entry `io.github.jay-the-maker/albumen` to the MCP Registry. [glama.json](glama.json) names the maintainer for Glama. This repository does not submit Glama, Smithery, PulseMCP, or mcp.so by itself.
## Ingest core
`ingest/` is the `albumen-ingest` crate. The operation that matters is `copy_verify`:
1. Discover XMP and Apple AAE sidecars, plus RAW+JPEG and Live Photo pairs beside the file.
2. Copy the bytes. Do not open them with an image codec.
3. Keep the filename. Refuse a rename. Refuse to overwrite a file that is already there.
4. Keep the mtime. On S3, store it in object metadata (`albumen-mtime-ns`). `Last-Modified` is the upload time and is not the photo's timestamp.
5. Read the destination back, compute SHA-256, and compare. On mismatch, delete the destination copy and return an error that names both hashes. The source is left as it was.
6. If a later file in the asset fails, delete the destination copies this call wrote. Sources stay.
`copy_verify` is the only default path. There is no move in the CLI. `copy_verify_quarantine` cannot target a source: it returns an error and does not copy or rename. There is no flag that turns that off. Nothing in the CLI or the MCP server calls it.
```rust
use albumen_ingest::{copy_verify, discover, LocalStore};
let asset = discover("IMG_0001.jpg")?;
let report = copy_verify(&asset, &LocalStore::new("/library/originals"))?;
```
S3-compatible stores use `S3Store` (`ALBUMEN_S3_ENDPOINT`, `ALBUMEN_S3_BUCKET`, `ALBUMEN_S3_ACCESS_KEY`, `ALBUMEN_S3_SECRET_KEY`). The CI credentials are disposable test values, not secrets.
SFTP, WebDAV, and Backblaze B2 use `RcloneStore`. rclone is the transport and is not vendored. `put_verified` uploads, reads the bytes back, and checks SHA-256. The exact mtime is kept in a sibling `.{filename}.albumen-verify` object because those backends do not store nanoseconds. CI runs SFTP and WebDAV with `rclone serve` and points the B2 leg at MinIO.
## Export
`albumen export` copies a whole library, including sidecars and pairs, with `copy_verify`. The source is not modified. A file already at the destination with the same SHA-256 is left in place, so the command can be run again. A different file at that relative path is an error and is not overwritten.
```bash
albumen export --from ./library --to /backup/library
albumen verify-manifest --manifest /backup/library/ALBUMEN-MANIFEST.txt --against /backup/library
albumen export --from ./library --to s3://my-bucket/library --manifest ./library-manifest.txt
albumen verify-manifest --manifest ./library-manifest.txt --against s3://my-bucket/library
```
The manifest lists SHA-256, byte length, and the relative path. `verify-manifest` hashes the destination bytes and fails if a file is missing, extra, or different. S3 uses the same `ALBUMEN_S3_*` variables as ingest.
## Google Takeout
`albumen import-takeout` reads a Google Takeout download of `.zip` and `.tgz` parts, or an extracted folder, read-only. Each file is `copy_verify`'d. Takeout JSON is kept byte-for-byte next to its original. Capture time and GPS are restored into a new `.albumen.json` sidecar and are not written into the original. The reconciliation report names every unmatched file. Without `--apply` or `--execute` the command prints a plan and writes nothing. With `--apply` it exits non-zero unless the count in equals the count out and every SHA-256 matches.
```bash
albumen import-takeout --from ~/Downloads/takeout --to ~/library --report ~/takeout-report.jsonl --apply
```
The design note is [docs/importers/takeout.md](docs/importers/takeout.md).
## iCloud Photos
`albumen import-icloud` copies an iCloud Photos download, a Photos export, or a copy of a Photos library. A download may be several zip parts plus Photo Details CSVs. The source is opened read-only. Originals and edited versions stay bit-exact. Live Photo pairs and AAE/XMP sidecars are kept, and the CSVs are copied byte-for-byte. Album, favorite, caption, capture time, and GPS are exported beside the original. The database is opened in SQLite read-only immutable mode and is not modified. Without `--apply` or `--execute` the command prints a plan and writes nothing. With `--apply` it exits non-zero unless the count in equals the count out and every SHA-256 matches.
```bash
albumen import-icloud --from ~/Pictures/Photos\ Library.photoslibrary --to ~/library --report ~/icloud-report.jsonl --apply
```
The design note is [docs/importers/icloud.md](docs/importers/icloud.md).
## Read-only macOS trial
`albumen scan <dir> --manifest <out>` walks a library without opening it for write and records path, size, mtime, SHA-256, pairs, sidecars, and key metadata in a JSONL manifest. If the size or mtime changes while a file is read, that line also records `drift` with the before and after values, and the source file is left as it is. The manifest has to resolve outside the library. Run the same command again to resume. `albumen verify-manifest` re-hashes a scan manifest and reports drift. The exact commands for a subset of a large volume are in [docs/trial-macos.md](docs/trial-macos.md).
## Tests
The merge gate copies the fixture corpus through the local filesystem, through MinIO, and through rclone (SFTP, WebDAV, and a MinIO stand-in for B2), then compares SHA-256, filename, mtime, and an ExifTool metadata dump. Filesystem identity tags that any copy changes (directory, inode change time, access time, permissions, and the absolute path) are the only tags ignored. `FileModifyDate`, `FileName`, and every embedded EXIF, XMP, IPTC, GPS, and QuickTime tag must match.
```bash
export PATH="$(scripts/install-exiftool.sh):$PATH"
scripts/with-minio.sh cargo test --lockedWhat people ask about albumen
What is jay-the-maker/albumen?
+
jay-the-maker/albumen is tools for the Claude AI ecosystem. A beautiful, open-source photo library that scales to huge collections. Bring your own storage, agent/MCP-native. Early concept. It has 1 GitHub stars and its last recorded update is dated 2026-10-19.
How do I install albumen?
+
You can install albumen by cloning the repository (https://github.com/jay-the-maker/albumen) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is jay-the-maker/albumen safe to use?
+
Our security agent has analyzed jay-the-maker/albumen and assigned a Trust Score of 87/100 (tier: Trusted). See the full breakdown of passed checks and flags on this page.
Who maintains jay-the-maker/albumen?
+
jay-the-maker/albumen is maintained by jay-the-maker. The last recorded GitHub activity is dated 2026-10-19, with 22 open issues.
Are there alternatives to albumen?
+
Yes. On ClaudeWave you can browse similar tools at /categories/tools, sorted by popularity or recent activity.
Deploy albumen to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/jay-the-maker-albumen)<a href="https://claudewave.com/repo/jay-the-maker-albumen"><img src="https://claudewave.com/api/badge/jay-the-maker-albumen" alt="Featured on ClaudeWave: jay-the-maker/albumen" width="320" height="64" /></a>More Tools
A single CLAUDE.md file to improve Claude Code behavior, derived from Andrej Karpathy's observations on LLM coding pitfalls.
An AI skill that provides design intelligence for building professional UI/UX across multiple platforms.
🪨 why use many token when few token do trick. Viral skill + proxy for coding agents that cuts 65% of tokens by talking like a caveman.
Use Claude Code, Codex, VSCode, Pi, and OpenCode (and 6 other harnesses) for free (1.3B+ free tokens) from your terminal, app, IDE, or phone, and now from the browser with native browser sessions (multi-harness + multi-model) like OpenClaw (voice supported + ToS friendly)
The fastest, litest AI Gateway. Rust core with Python SDK. Call 100+ LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]
Wrap Antigravity, ChatGPT Codex, Claude Code, Grok Build, Muse Code, Devin as an OpenAI/Gemini/Claude/Codex compatible API service, allowing you to enjoy the free Gemini Series, GPT Series, Grok Series, Claude model through API