使用说明
Lightroom Classic MCP Server
Lets Claude (and other AI assistants) talk to your Adobe Lightroom Classic photo catalog. Search photos, set ratings, edit develop settings, manage collections, import/export — all by chatting.
Works with: Claude Desktop, Claude Code, Codex CLI, Cursor, Windsurf, VS Code. Needs: Lightroom Classic on macOS or Windows. Nothing else — no programming required. Other languages: 繁體中文
Install (Claude Desktop — easiest, 3 steps)
This is the recommended path. Takes ~2 minutes, no terminal needed.
1. Download the installer
Go to the latest release page and download the file ending in .mcpb (it's near the top, called lightroom-mcp-<version>.mcpb).
2. Double-click the downloaded file
Claude Desktop opens automatically and asks: "Install Lightroom Classic extension?". Click Install.
Don't have Claude Desktop yet? Get it free from claude.com/download. It runs on Mac and Windows.
3. Turn on the plugin in Lightroom
- Quit and reopen Lightroom Classic. (The plugin needs a restart to show up.)
- In Lightroom, click File in the menu bar → Plug-in Manager.
- In the left list, click Lightroom MCP.
- On the right, click the Start Server button.
- You should see "Server running" appear. Done!
Try it
Open Claude Desktop and type:
List all my Lightroom collections.
Claude will list every collection in your catalog.
Some other things to try:
- "Find all my 5-star photos from last summer."
- "Add the keyword 'portfolio' to the photos I have selected in Lightroom."
- "Apply the 'Vivid' develop preset to these photos."
- "Compare my approved 'John Warm v3' preset with the current candidate."
- "Create a versioned preset checkpoint from this representative photo and export it."
- "Export the selected photos to my Desktop as JPEGs at 2000px wide."
Install (other AI tools)
Already using Claude Code, Codex, Cursor, Windsurf, or VS Code? Pick your tool below. All paths still end with the Lightroom step from the section above — restart Lightroom and click Start Server in Plug-in Manager.
The npm server requires Node.js 20 or later.
Claude Code
Load the Claude plugin from a checkout to get the MCP server and the bundled skill together:
git clone https://github.com/Automaat/lightroom-mcp.git
claude --plugin-dir ./lightroom-mcp
Use /plugin to check that lightroom is loaded. The skill is available as
/lightroom:raw-photo-lightroom-preset. Node.js 20 or later is required: the
plugin starts the published npm server with npx. That package includes the Lua bundle and
installs it on first start when no Lightroom MCP plug-in is already installed.
Restart Lightroom and click Start Server in Plug-in Manager.
The same .mcpb file as Claude Desktop also works. To install only the MCP server:
claude mcp add lightroom -- npx -y @mskalski/lightroom-mcp
Codex CLI
codex mcp add lightroom -- npx -y @mskalski/lightroom-mcp
The Lightroom plugin installs itself the first time Codex talks to the server.
Cursor / Windsurf / VS Code (Continue, Cline, Roo, ...)
Open your client's MCP settings and add:
{
"mcpServers": {
"lightroom": {
"command": "npx",
"args": ["-y", "@mskalski/lightroom-mcp"]
}
}
}
The plugin installs itself the first time your client starts the server. If your client only starts the server on first tool call, you can install the plugin upfront:
npx -y @mskalski/lightroom-mcp install-plugin
No Node.js installed? Use the standalone binary
-
Download the right file from the latest release:
- Mac (Apple Silicon, M1/M2/M3/M4):
lightroom-mcp-darwin-arm64 - Mac (Intel):
lightroom-mcp-darwin-x64 - Windows:
lightroom-mcp-windows-x64.exe
- Mac (Apple Silicon, M1/M2/M3/M4):
-
macOS only — make it runnable and bypass Gatekeeper (the binary isn't signed):
chmod +x ~/Downloads/lightroom-mcp-darwin-arm64 xattr -d com.apple.quarantine ~/Downloads/lightroom-mcp-darwin-arm64 -
Download
LightroomMCP-macos.lrplugin.zip(orLightroomMCP-windows.lrplugin.zip) from the same release and extract it next to the binary, so theLightroomMCP.lrpluginfolder sits beside it. Then install the Lightroom plugin:~/Downloads/lightroom-mcp-darwin-arm64 install-plugin -
Point your AI tool at the binary's full path. Example for Codex:
codex mcp add lightroom -- /Users/you/Downloads/lightroom-mcp-darwin-arm64
Install the Lightroom plugin manually (any client)
If you'd rather drop the plugin in by hand:
- Download the matching zip from the latest release:
- Mac:
LightroomMCP-macos.lrplugin.zip - Windows:
LightroomMCP-windows.lrplugin.zip
- Mac:
- Unzip it. You get a folder called
LightroomMCP.lrplugin. - Move that folder into Lightroom's Modules folder:
- Mac:
~/Library/Application Support/Adobe/Lightroom/Modules/ - Windows:
%APPDATA%\Adobe\Lightroom\Modules\ - (If the
Modulesfolder doesn't exist, create it.)
- Mac:
- Restart Lightroom → Plug-in Manager → Start Server.
Something not working?
- Open Lightroom → File → Plug-in Manager → Lightroom MCP → Show Status. Both sockets should say
connected: true. If not, click Start Server. - Make sure you fully quit and reopened Lightroom after install (Cmd+Q on Mac, Alt+F4 on Windows). "Reload Plug-in" alone is not enough.
- See Troubleshooting below for specific errors.
Tools
By default, the server exposes only core catalog and metadata tools. Set LIGHTROOM_MCP_TOOLSETS in your MCP client’s server environment to develop, masks, develop,masks, or all to add those tools. Core stays enabled. Restart the server after changing the setting; its tool list stays fixed for the session, and disabled tools cannot be called. In the desktop bundle, use Enabled toolsets.
Set LIGHTROOM_MCP_READ_ONLY to true or 1 to hide write tools and refuse calls to them before they reach Lightroom, including when this server forwards through another bridge. The switch applies within the enabled toolsets. Exports (export_photos, export_photo_metadata, export_develop_preset) write files and are blocked. Read tools for masks and other Develop settings can briefly switch the module, photo or selected mask, then restore the previous view; they do not change photo data. Previews return image data in memory using Lightroom's preview cache. In the desktop bundle, enable Read-only mode. Restart the server after changing this setting.
The Develop toolset includes presets, settings, snapshots, virtual copies, style summaries, Lens Blur, Denoise and Remove spots. The masks toolset includes all local mask tools. The table below lists every tool, including opt-in tools.
| Tool | What it does |
|---|---|
search_photos |
Search by filename, keywords, rating, date, camera, lens, ISO, focal length (mm), flag, color label, edited status, file type or folder; filters intersect. |
get_selected_photos |
Photos selected in Lightroom (or filmstrip). |
get_photo_metadata |
Keywords (names and full paths), EXIF, GPS, IPTC location and copyright for one photo_id or up to 100 photo_ids. Batch results return photos in request order and missing identifiers. Pass sections: ["developSettings"] to include develop settings for each. |
summarize_develop_settings |
Read-only medians and ranges of numeric Develop settings by camera and ISO (1–400, 401–1600, 1601–6400, 6401+, unknown). Rating ≥4 by default; optional exported filter intersects rating. Reads up to 200 photos; reports matched/scanned/truncated and settings omitted to keep each group under 6,000 characters. Excludes crop, perspective and white balance. |
get_photo_preview |
JPEG preview of one photo (raw files too), optionally cropped to a rendered-frame region. size: "cull" requests 512 for culling; "detail" requests 1024 for inspecting details. Numeric sizes 64–2048 and the default 512 remain supported. |
get_photo_previews |
Up to 20 ordered JPEG thumbnails with per-photo errors and partial timeout results. |
get_photo_stats |
Rendered-preview luminance histogram, clipping fractions, mean luminance and sharpness for up to 20 photos; errors stay with each photo. |
find_duplicate_groups |
Find near-duplicate and burst groups using JPEG dHash and raw capture time (up to 100 photos; defaults 5 s / 10 bits; 25 s partial-result budget) |
set_gps |
Set the GPS position (decimal degrees) of photos. |
set_location |
Set the IPTC location (sublocation, city, state, country, ISO code) of photos. |
set_ai_metadata |
Store or clear private AI scores (0–100) and reasons (up to 1024 characters). |
get_ai_metadata |
Read private AI scores and reasons for up to 1000 photos in one batch. |
set_metadata |
Set title, caption, headline, creator and copyright fields of photos. |
list_folders |
Catalog folders in tree order, with full paths and direct photo counts (paginated). |
get_folder_photos |
Photos by full folder path, optionally including subfolders (paginated). |
list_collections |
All collections and collection sets. |
create_smart_collection |
Save search_photos filters as a smart collection; requires a filter and supports parent collection set paths. |
create_collection |
New collection, optionally inside a collection set path (Trips / 2026); missing sets are created. |
add_to_collection |
Add photos to a collection, by name or by its list_collections path. |
get_collection_photos |
Photos in a collection, regular or smart (paginated). |
remove_from_collection |
Remove photos from a collection (they stay in the catalog). |
delete_collection |
Delete a collection (its photos stay in the catalog). |
set_keywords |
Add or remove keywords on photos, by name or by hierarchy path (Places|Europe|Paris). |
remove_keyword_subtree |
Detach a parent keyword and its descendants from selected photos, or explicitly from the whole catalog. Keyword nodes stay in the catalog. |
list_keywords |
The keyword hierarchy as full paths, with synonyms. |
rename_keyword |
Rename a keyword everywhere it is used. |
undo_last_step |
Undo one step in Lightroom’s shared history with confirm: true; this includes user and other plug-in actions. |
set_rating_and_flag |
Set a 0-5 star rating, a pick flag (pick, reject, none), or both in one write. |
remove_photos_from_catalog |
Remove up to 100 specified photos from the catalog with confirm: true (Lightroom Classic 14.3+). Files stay on disk; catalog edits and metadata are lost. Restores module, sources and surviving selection; Library remains in grid view. Include all virtual copies when removing a master. |
set_color_label |
Set a red, yellow, green, blue or purple label, or clear it. |
import_photos |
Import a file or folder into the catalog. |
export_photos |
Export with format / quality / dimensions. |
export_photo_metadata |
Write metadata (incl. keyword paths) for many photos, or the selection, to a JSON file. |
list_develop_presets |
Discover presets and plugin checkpoints by name (query) or exact folder, with limit (default 100) and offset. Returns name, folder, scope, uuid, total count and has_more; use get_develop_preset for file. |
get_develop_preset |
Read settings and backing-file metadata for one exact preset. |
compare_develop_presets |
Diff an approved historical preset against a candidate. |
create_develop_preset |
Capture explicit settings from a photo as a versioned plugin checkpoint. |
export_develop_preset |
Copy a custom/checkpoint preset backing file without overwriting. |
apply_develop_preset |
Apply an exact preset by UUID or disambiguated name; recomputes AI masks per photo (LrC 13.3+). |
copy_develop_settings |
Copy develop settings between photos; recomputes copied AI masks per photo (LrC 13.3+). |
match_photo_style |
Match global style after a confirmed snapshot per target; preserves framing, white balance, lens corrections and local masks. Returns snapshot IDs for restoration. |
set_develop_settings |
Write SDK setting key/values directly. |
get_lens_blur |
Read Lens Blur state, controls, focal range and bokeh (LrC 13.3+, Process Version 3+); restores the Develop view. |
set_lens_blur |
Set Lens Blur controls after enabling depth computation; validates runtime ranges and saved readback, then restores the view. |
set_process_version |
Set photos to Version 1–6 with confirmation; refuses masked-photo downgrades and reports previous/actual versions. |
list_develop_snapshots |
List a photo’s saved develop snapshots. |
create_develop_snapshot |
Save current develop settings; set replace to update an existing name. |
create_virtual_copies |
Create named virtual copies of up to 25 photos; return master and copy IDs and restore selection. |
apply_develop_snapshot |
Restore a saved develop snapshot. |
delete_develop_snapshot |
Delete one saved develop snapshot. |
apply_auto_adjustments |
Apply Lightroom Auto Tone, Auto White Balance, or both, restoring the Develop view afterwards. |
reset_develop_adjustments |
Reset all develop adjustments on up to 100 photos; requires confirm: true. Recover edits through Lightroom History. |
apply_denoise |
Turn on AI Denoise at an amount (LrC 15+); drives the Develop module photo by photo. |
list_spots |
List Remove spots with their indices and complete SDK parameters (LrC 14.1+) |
update_spot |
Change a Heal spot's uppercase params.Opacity from 0 to 1 |
delete_spot |
Delete one Remove spot by index with confirm: true |
list_masks |
List a photo's masks with their ids, names, hidden state and component tools, and the stored range of each range mask tool, including the color sample's l, a and b (LrC 11+); briefly opens the photo in Develop. |
create_gradient_mask |
Place a linear or radial gradient mask from normalized image coordinates, as a new mask or a component of one; optional adjustments sets a new mask's sliders in the same call (cannot combine with mask_id); guarded write, LrC 15.6 only; briefly opens the photo in Develop. |
update_gradient_mask |
Move or reshape an existing linear or radial gradient by tool id; same guarded write. |
create_brush_mask |
Paint a brush mask from strokes (points in normalized image coordinates, radius, flow, feather, density, erase), as a new mask or a component of one; optional adjustments sets a new mask's sliders in the same call (cannot combine with mask_id); guarded write, LrC 15.6 only; briefly opens the photo in Develop. |
add_brush_strokes |
Paint more strokes into an existing brush by tool id; same guarded write. |
create_range_mask |
Create a luminance, color or depth range mask (one color sample point given as Lightroom's own l, a and b, which list_masks reads from a color range made in Lightroom, not as sRGB, or copied from an existing color range with copy_sample_from; depth needs a photo with device depth such as an iPhone Portrait HEIC), as a new mask or an add/subtract component of one; optional adjustments sets a new mask's sliders in the same call (cannot combine with mask_id); guarded write, LrC 15.6 only; briefly opens the photo in Develop. |
delete_masks |
With photo_id, delete masks or components by id, or all masks (LrC 11+); unknown ids delete nothing; briefly opens Develop. With only photo_ids, delete empty masks from up to 1000 photos without opening Develop or changing selection (LrC 14+). |
set_mask_adjustments |
Change any subset of a mask's local sliders (local_Exposure, local_Contrast, ...) by mask id; out-of-range values are rejected before anything is written (LrC 11+); briefly opens the photo in Develop. |
get_mask |
Read local adjustments, curves and Point Color in one Develop session; optional kinds selects adjustments, curves or point_colors (default all). Returns supported kinds and named errors for unsupported versions. |
invert_mask |
Invert a mask by id, in place or as an inverted copy that keeps the original (LrC 11.4+); briefly opens the photo in Develop. |
create_mask |
Create Subject/Sky/Background masks (LrC 11+) with optional adjustments, or People parts/Landscape categories (guarded LrC 15.6 / process 15.4) with type: "people", parts: [...] or type: "landscape", categories: [...]. Returns mask ids; missing AI parts leave no new masks. People/Landscape reject adjustments; use set_mask_adjustments afterwards. A single person cannot be chosen. |
create_mask_batch |
Add the same Subject, Sky or Background mask with the same adjustments to up to 200 photos, each mask recomputed for its own photo; opens only the first photo in Develop; guarded write, LrC 15.6 only. |
set_mask_curves |
Set a mask's local tone curve per channel (main, red, green, blue) by mask id (LrC 12.3+); briefly opens the photo in Develop. |
edit_mask_point_colors |
Add, update, delete or clear a mask's local Point Color swatches by mask id (LrC 13.2+); briefly opens the photo in Develop. |
combine_mask |
Add, subtract or intersect a Subject, Sky or Background component on an existing mask by id and get the component's id (LrC 11+); briefly opens the photo in Develop. |
Full schemas and parameter docs: server/src/list-tools-handler.ts.
AI scores and reasons stay in the catalog's private plug-in metadata. They do
not appear in the Metadata panel, searches, keywords, IPTC, XMP, or exports.
set_ai_metadata leaves omitted fields unchanged; pass "" to clear a score
or reason. get_ai_metadata omits unset fields and reports missing photo IDs.
The initial provider schema is version 1: aiScore and aiReason are strings
(the tools convert the score to and from an integer). Changes to these
persistent field definitions require a schema version bump and migration;
incompatible field changes also require a field version bump.
copy_develop_settings and apply_develop_preset accept dry_run: true to
preview without writes or AI recomputation. Replies include per-setting totals
and detail for at most five targets. detail_truncated flags omitted detail;
missing_count and one-based missing_indices identify missing inputs when
missing_truncated limits their path detail.
Preset previews compare only declared settings whose current values the SDK
exposes. preview_scope states this limit, and unknown_current_totals counts
unreadable values excluded from the diff. unknown_effects lists effects that
remain unpredicted: SDK-generated values such as GrainSeed and preset
bookkeeping. This preview does not predict the complete result of applying a
preset.
First-pass cull workflow
Use vision as a first-pass reject filter for clear blur, closed eyes, missed focus and near-duplicates. Leave star ratings of the surviving photos to the user; thumbnails do not reliably distinguish a four-star photo from a five.
- Collect photo IDs with
search_photos. Read existing flags and labels withget_photo_metadata, and private reasons withget_ai_metadata. - Call
get_photo_previewswith at most 20 IDs at a time. The default minimum edge is 256 pixels; returned JPEGs have no edge over 2000 pixels and share an 8 MiB byte budget. Text maps eachrequested_idto its 1-basedimage_index. Inspect errors separately. Retryremaining_idswhencompleteis false. - Propose rejects with a reason per photo and show the list to the user before writing. Keep uncertain shots for review; do not reject them automatically.
- For approved clear failures, call
set_rating_and_flagwithflag: "reject". Mark uncertain photos withset_color_labelusinglabel: "yellow"for “needs a look”. Preserve existing labels unless the user approves replacing them. Store each decision's reason withset_ai_metadatain itsreasonfield (private plug-in fieldaiReason), never as keywords. - Verify flags and labels with
get_photo_metadata, and reasons withget_ai_metadata. Undo a reject withset_rating_and_flagandflag: "none"; restore the previous label and reason when undoing the whole decision.
This workflow deletes nothing and removes no photos from the catalog.
Iterative preset workflow
Use a representative photo or virtual copy rather than a master edit:
- Read an approved historical preset with
get_develop_preset. - Apply bounded setting changes to the representative and export a Lightroom-rendered JPEG.
- Create a uniquely named checkpoint such as
John Warm v4withcreate_develop_preset. - Compare it with the approved preset using
compare_develop_presets. - Repeat the render/inspect cycle; export the accepted checkpoint with
export_develop_preset.
create_develop_preset uses Adobe's plugin preset API. These checkpoints are intentionally hidden from the Develop panel and are listed with scope: "plugin". They are versioned instead of overwritten. export_develop_preset refuses existing destinations and preserves the backing file format Lightroom supplies. Built-in presets without a backing file cannot be exported.
Point curves
set_develop_settings accepts Lightroom's composite and per-channel point curve
keys: ToneCurvePV2012, ToneCurvePV2012Red, ToneCurvePV2012Green, and
ToneCurvePV2012Blue. Each value is a flat list of 2 to 32 input/output pairs.
Values are integers from 0 to 255, inputs must be strictly increasing, and each
curve must start at input 0 and end at input 255.
{
"photo_id": "283615",
"settings": {
"ToneCurveName2012": "Custom",
"ToneCurvePV2012": [0, 0, 40, 25, 128, 132, 220, 240, 255, 250],
"ToneCurvePV2012Blue": [0, 0, 64, 58, 192, 198, 255, 255]
}
}
Scope, write safety and limits
Your local Classic catalog
This server works with the catalog open in Lightroom Classic on your computer through a Lightroom plug-in. Use it to organize photos, adjust edits and masks, and export Lightroom-rendered images. Lightroom Classic must be running. See How it works for the connection and Security for local access and authentication.
Safeguards when changing photos
- Deleting a collection with
delete_collectionkeeps its photos in the catalog (collection handler). - Mask tools that write Lightroom's undocumented mask format check the Lightroom version, the photo's process version and the format of existing masks before writing. They read the result back and attempt to restore the previous masks if it differs; an unconfirmed restoration is reported as an error. These checks live in GuardedMaskWrite.lua. They apply to those mask writes, not to every edit.
- Connections require the local token described in Security, checked by PluginInfoProvider.lua.
What Lightroom's plug-in SDK does not expose
The SDK is Adobe's interface for plug-ins. Its reference provides no documented calls for these operations:
- Reading raw sensor histograms, individual pixel data or detected face regions.
get_photo_statsmeasures the rendered JPEG preview;get_photo_previewreturns that image for visual inspection. - Running an HDR or panorama merge; producing a print or book; creating or editing a slideshow. The SDK does support slideshow playback, but this server has no playback tool.
- Running Super Resolution or Raw Details through a documented call.
- Stack create or unstack operations on photos already in the catalog, or auto-stacking. The SDK's import operation can add a new photo to a stack.
- Folder create, move or delete operations in the catalog, or catalog open or close operations. Importing photos and managing collections are separate operations.
- Spot creation with the healing tools; Assisted Culling; Dust Removal; or Render to DNG.
- Running an HTTP server inside the plug-in. The connection uses the SDK's sockets instead; see How it works.
Pixel-based AI edits have another limit: copying a table of develop settings does not copy their generated image data. Since Lightroom Classic 15.0, Lightroom stores heavy edits, including AI edits, in .acr sidecars when saving metadata to files. Copying develop-settings tables alone does not transfer those sidecar contents.
How it works
┌─────────────┐ stdio ┌──────────────────┐ TCP :58763 → ┌──────────────────┐
│ AI client │ ◄─────────► │ MCP server │ ──────────────► │ Lightroom plugin │
│ (Claude/ │ │ (Node TCP) │ ←────────────── │ (LrSocket) │
│ Codex/...) │ └──────────────────┘ ← TCP :58764 └──────────────────┘
└─────────────┘ │
▼
catalog:withReadAccessDo
Plugin binds two LrSocket servers on localhost (58763 request, 58764 response). Server connects as TCP client. Frame: line-delimited JSON, \n terminator. Auto-reconnect on both sides. Same dual-port pattern as MIDI2LR.
CLI reference
lightroom-mcp [stdio] Run MCP over stdio (default)
lightroom-mcp install-plugin Copy bundled plugin into Lightroom Modules folder
lightroom-mcp --help | --version
Env vars:
| Var | Default | Purpose |
|---|---|---|
LIGHTROOM_MCP_REQUEST_PORT |
58763 |
Plugin request port. |
LIGHTROOM_MCP_RESPONSE_PORT |
58764 |
Plugin response port. |
LIGHTROOM_MCP_TOOLSETS |
core |
Comma-separated core, develop, masks, or all; core is always enabled. |
LIGHTROOM_MCP_READ_ONLY |
false |
true or 1 hides and refuses write tools; false, 0, unset or empty disables the switch. Values are case-sensitive and surrounding whitespace is ignored. Invalid values fail startup. |
LIGHTROOM_MCP_TOKEN_PATH |
~/.config/lightroom-mcp/token |
Auth token file. |
If you change ports on the server side, change them in Plug-in Manager → Lightroom MCP to match.
Security
The plugin generates a 256-bit token in ~/.config/lightroom-mcp/token on Start Server. The MCP server attaches it to every request. Localhost-only — no remote attack surface.
Develop
mise install # tools (node, bun, lua + luarocks, selene)
mise run install # npm ci
mise run build # tsc
mise run test # jest
mise run mcpb # build .mcpb bundle
mise run binary # build single-file binaries via Bun
mise run lua:lint # selene-lint the Lua plugin
mise run lua:test # busted specs for the Lua plugin
Repo layout:
server/— TypeScript MCP server (ESM, NodeNext).plugin/LightroomMCP.lrplugin/— Lua plugin loaded by Lightroom Classic.mcpb/manifest.json—.mcpbbundle manifest.scripts/build-mcpb.mjs— pack the .mcpb.scripts/build-binary.mjs— Bun--compileper-target binaries.manual-test.mjs— direct TCP probe (bypasses MCP).
Adding a new tool
- Add a new
Handler*.luaunderplugin/LightroomMCP.lrplugin/. - Register it in the
DISPATCHtable inPluginInfoProvider.lua. - Add a contract entry in
server/src/tool-contracts.ts. - Declare any new LR globals in
lightroom.yml(selene std).
Troubleshooting
failed to open localhost:58763after Reload Plug-in — old async task still owns the port. Quit Lightroom (Cmd+Q on macOS / Alt+F4 on Windows) and reopen.- Server not running right after Lightroom starts — Lightroom Classic runs the plugin's start-up script only once its window is first brought to the front, even with
LrForceInitPlugin. Seen on LrC 15.6 macOS: launched in the background (open -g), the plugin did nothing for 90 s and started the moment the window was activated. A Lightroom opened hidden (a login item set to hide,open -g, a script) therefore has no server until you switch to it once. The plugin log showsPlugin initialized, auto-start onwhen the script runs. - Plugin not connected — the server now self-restarts after a Reload Plug-in that tore down a running instance. If it's still stopped, click Start Server in Plug-in Manager; it reconnects within ~1s.
- Lightroom hangs on "performing shutdown tasks" when quitting, or warns that "a shutdown task for the plug-in became unresponsive" — fixed by removing the plugin's shutdown hooks.
LrShutdownApprequires the script to return a table whoseLrShutdownFunctioncalls Lightroom'sdoneFunction; without it Lightroom waits out a no-progress timeout on every quit, and even with it the shutdown dialog still costs about a second. The hooks bought nothing: Lightroom cancels the plugin's function context on quit, disable and reload, and that cleanup handler already closes both ports. Measured on macOS: 7.7 s with the hooks, 0.1 s without. If a future change needs work done at quit, re-registerLrShutdownAppand return that table. - Timeout errors — handler may be scanning a large catalog without filters; add
rating,filename,keywords, or date filters to narrow. - macOS "cannot be opened because the developer cannot be verified" (binary path) —
xattr -d com.apple.quarantine /path/to/binary. Or right-click → Open the first time. - Windows SmartScreen blocks the .exe — More info → Run anyway.
Logs:
| Component | macOS | Windows |
|---|---|---|
| Plugin | ~/Documents/LrClassicLogs/LightroomMCP.log |
%USERPROFILE%\Documents\LrClassicLogs\LightroomMCP.log |
| Claude Desktop | ~/Library/Logs/Claude/mcp*.log |
%APPDATA%\Claude\Logs\mcp*.log |
The plugin resolves its log path via the OS (LrPathUtils), so on Windows with
OneDrive-redirected Documents the file follows the redirect. The exact resolved
path is shown as Log file: in Plug-in Manager → Show Status — use that if
the table path above is empty.
License
MIT