darktable-mcp
Enables Claude and other AI assistants to control darktable for photo management and editing through its Lua API.
Ask AI about darktable-mcp
Powered by Claude Β· Grounded in docs
I know everything about darktable-mcp. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Darktable MCP Server
A Model Context Protocol (MCP) server that exposes darktable operations to MCP clients (Claude Desktop, Claude Code, etc.). The AI lives in the client; this server drives darktable.
Tools
Library operations (require darktable-mcp install-plugin and an open darktable session):
view_photos(filter?, rating_min?, limit?)β Browse the library by filename substring and minimum rating. Returns id, filename, absolute file path, and rating per match β the path drops straight intoexport_images'sphoto_ids.rate_photos(photo_ids, rating)β Apply -1..5 star ratings (-1 = reject, 0 = unrated).import_batch(source_path, recursive?)β Register a folder as a film roll.list_styles()β Enumerate installed darktable styles (presets), returning name + description per entry.apply_preset(photo_ids, preset_name)β Apply a named darktable style to one or more photos. Uselist_stylesfirst to discover exact names.
Camera ingest (headless):
import_from_camera(destination?, camera_port?, timeout_seconds?)β Detect a camera via libgphoto2 and copy photos to a local directory. Auto-merges hybrid setups (one card on PTP, the other mounted as USB Mass-Storage) into a single import β Nikon DSLRs in particular show up that way and the previous behavior silently halved the import.
Vision-rating workflow (headless, file-based β no library required, needs [vision] extra):
extract_previews(source_dir, output_dir?, max_dim?, thumb_dim?, overwrite?)β Pull auto-rotated JPEG previews + small thumbs out of raws (NEF/CR2/ARW/DNG/...), with an EXIF summary per file. Per-file details (paths, EXIF, errors) land in<output_dir>/.extract_previews.jsonl; the tool response keeps only counts and the side-file path so 700+ NEFs don't overflow the agent's context.apply_ratings_batch(source_dir, ratings, log?)β Write XMPxmp:Ratingsidecars for a{stem: rating}batch + an append-onlyratings.jsonllog.open_in_darktable(source_dir, rating?, rating_min?, rating_max?)β Launch the GUI on a folder. Auto-registers as a film roll; pre-applies any rating filter (exact, β₯, β€, or inner range) viadt.gui.libs.collect.filter.
Export:
export_images(photo_ids, output_path, format, quality?)β Export to JPEG/PNG/TIFF viadarktable-cli. Runs in an isolated config dir under$XDG_CACHE_HOME/darktable-mcp/cli-config/, so exports work even when the GUI is open (nodatabase is lockedrace against the user's~/.config/darktable/library.db). Per-file results land in<output_path>/.export_images.jsonl; the tool response is bounded β counts, side-file path, and the first error if any.
Design rules
Use only the official darktable APIs: darktable-cli for export, the Lua API for everything else. No direct library.db reads or writes. Tools that return data to the AI must be headless; the GUI may launch only when the tool's purpose is to show the human something.
Why some tools are parked
darktable-cli doesn't load the user's library and darktable --lua brings up the full GUI, so there's no headless one-shot path for library reads/writes. Iteration 2 (spec: docs/superpowers/specs/2026-04-27-ipc-bridge-mvp-design.md) shipped a long-running Lua plugin loaded into the user's interactive darktable session, with a file-based JSON RPC bridge. The library tools (view_photos, rate_photos, import_batch, list_styles, apply_preset) all ride on it.
adjust_exposure was retired during iteration 3 β see docs/superpowers/specs/2026-04-28-iter3-design.md. The darktable Lua API in 9.6.0 exposes neither image.modules nor image.history, and dt.gui.action requires an active darkroom view (single-image, GUI-driven). The realistic future paths (pre-created .dtstyle exposure presets + apply_preset, or darktable-cli --style for export-only) are workable but not "set +N EV from Lua" tools.
Installation
pip install darktable-mcp
# Optional: vision-rating workflow extras
pip install 'darktable-mcp[vision]'
# Install the Lua plugin into ~/.config/darktable/, then restart darktable
darktable-mcp install-plugin
You also need darktable (with darktable-cli) on PATH. The [vision] extra pulls in rawpy, Pillow, and pyexiv2, which need system libraw and libexiv2.
Configuration
Add to your Claude Desktop config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"darktable": {
"command": "darktable-mcp"
}
}
}
Vision-rating workflow
When darktable's library doesn't yet know about your shoot β typically straight off a card β you can rate by vision before any import:
extract_previewswrites auto-rotated JPEGs and an EXIF summary so the client can iterate efficiently.- The client reads previews, decides ratings, and calls
apply_ratings_batchto write XMP sidecars next to the raws. open_in_darktablelaunches the GUI with the folder as a film roll, lighttable filtered to the rating range you want.
No SQLite poking, no half-imported state, no GUI launch until step 3.
Requirements
- Python 3.8+
- darktable 4.0+ (with
darktable-clionPATH) - An MCP-compatible client (Claude Desktop, Claude Code, etc.)
Contributing
Contributions welcome. Any change that reads or writes library.db directly will be rejected.
License
MIT β see LICENSE.
