lr-mcp
This MCP server lets an AI client access and manage Adobe Lightroom cloud photos through the Lightroom Partner API.
Sign in to Adobe via browser OAuth and store/refresh tokens.
Check subscription status and cloud storage usage.
List and search albums by path name.
Search photos by album, capture date/time, rating, pick/reject flag, camera, lens, filename, ISO, and f-number.
Get detailed photo metadata: capture info, title, caption, keywords, sizes, orientation, GPS, and edit-settings summary.
View edited JPEG renditions directly as images, up to 12 at a time.
Download edited JPEGs at several sizes, with incremental skipping of unchanged files.
Create, populate, and delete project albums owned by the server; existing Lightroom albums and photo edits/ratings are read-only.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@lr-mcp Show me the edited JPEGs of my five newest photos"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
lr-mcp
An unofficial MCP server for Adobe Photoshop Lightroom — the cloud-based Lightroom app, not Lightroom Classic. It talks to the Lightroom Partner API (https://lr.adobe.io) with your own Adobe credentials.
This project is not affiliated with, endorsed by, or sponsored by Adobe. Adobe, Photoshop and Lightroom are either registered trademarks or trademarks of Adobe in the United States and/or other countries.
Tools
Tool | What it does |
| Browser OAuth sign-in (only needed when tokens are missing or expired) |
| Subscription status and cloud storage usage |
| Search albums by path and get their ids |
| Filter by album, capture date, time of day, rating, pick/reject flag, camera, lens, aperture, ISO, file name; album results keep the album's own (custom) order. One line per photo: |
| Capture info, title, caption, keywords, original and cropped size, orientation, GPS when present, plus a summary of the photo's edit settings (XMP) |
| Return edited JPEG renditions as images the model can see (up to 12) |
| Save 640 – 2560 px or full-size JPEGs to disk; when saving into the same folder again (album or explicit |
| Manage project albums owned by this server |
Limits of the Partner API
Edits (develop settings) and ratings of existing photos are read-only.
Photos cannot be deleted.
Albums you created in Lightroom cannot be modified; only project albums created through the API can.
Preset contents cannot be read.
Related MCP server: stillport
Setup
Setup takes about ten minutes. Steps marked [human] need a person at a browser; an AI agent can do the rest (see For AI agents).
Prerequisites
An Adobe account with a Lightroom plan or trial.
uv (
uv --version). It installs Python 3.12+ itself if needed.openssl(openssl version). Preinstalled on macOS and most Linux distributions.
0. Install
uv tool install lr-mcp
lr-mcp doctorThis puts an lr-mcp command in ~/.local/bin (run uv tool update-shell and open a new terminal if the shell cannot find it). All later steps use it. Update with uv tool upgrade lr-mcp.
doctor checks the setup in order and prints the first thing to fix.
1. Create an Adobe credential [human]
Each user needs their own credential: until Adobe reviews an integration it accepts only 25 beta users, so a shared client ID is not practical.
Sign in to the Adobe Developer Console and click Create new project.
In the project, click Add API, choose Lightroom Services, then pick the OAuth Web App credential type.
Set Default redirect URI to
https://localhost:8000/callbackand Redirect URI pattern tohttps://localhost:[0-9]+/callback, then save. The pattern allows any port, so sign-in can use another one when 8000 is busy. A changed pattern can take a few minutes to apply.Open Lightroom Services in the project's left menu, click Manage beta users, and add the email of the Adobe account you will sign in with. Without this, the API refuses the account.
Open Credentials → OAuth Web App and click Download to save the credential as JSON. It contains the client secret; step 2 reads it and can delete it.
2. Save the credential
lr-mcp setup --from ~/Downloads/<credential>.json --deletesetup needs lr-mcp 0.3.0 or later (uv tool upgrade lr-mcp). It reads the client ID and secret from the downloaded file (the project JSON from the project overview's Download also works) and writes ADOBE_CLIENT_ID and ADOBE_CLIENT_SECRET to .env in the state directory, which doctor prints on its first line (~/.config/lr-mcp/ by default). The file gets mode 600 and keeps any other lines. Only the first characters of the client ID are printed. --delete removes the downloaded file afterwards; without it, delete the file yourself. The MCP server reads .env only when it starts: if it is already registered in an MCP client (step 5), restart the client after setup (quit and reopen Claude Desktop, or start a new Claude Code session).
Variable | Required | Description |
| yes | Client ID (also called API key) |
| yes | Client secret |
| no | Sign-in callback port. Default |
To enter the values by hand instead, put ADOBE_CLIENT_ID=… and ADOBE_CLIENT_SECRET=… lines in .env and chmod 600 it. Environment variables with the same names override the file, but keep the client secret in .env: an MCP client's "env" / -e stores it in plain text in the client's config. Variables exported only in your shell are not seen by an MCP client started from the GUI, so put settings in .env.
To keep the state somewhere else, set the environment variable LR_MCP_HOME to a directory. It cannot go in .env (it says where .env is), so it must also be set for lr-mcp login and in the MCP client config ("env" in step 5). If XDG_CONFIG_HOME is set, the default is $XDG_CONFIG_HOME/lr-mcp; if it is set only in your shell, the MCP client will not see it, so set LR_MCP_HOME in the client config to the directory doctor prints.
3. Sign in [human]
lr-mcp loginA browser window opens on the Adobe sign-in page. If port 8000 is busy, login first prints which port it uses instead. Sign in with the account added as a beta user and allow access. Adobe then redirects to https://localhost:<port>/callback (8000 unless it was busy), which uses a self-signed certificate, so the browser shows a certificate warning: choose Advanced → Proceed to localhost (Chrome) or Show Details → visit this website (Safari). The page then says "Signed in" and the terminal prints where the tokens were saved. Tokens are stored with mode 600 and refreshed automatically.
4. Check
lr-mcp doctorEvery line should start with [ok], ending in Catalog found. Setup is complete. Otherwise it prints a fix: for the first problem and exits with status 1.
5. Add to your MCP client
Claude Desktop. Edit the config file (create it if missing):
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
Add an entry under mcpServers, keeping any existing ones (if a lightroom entry already exists, check what it runs and whether it sets "env" before replacing it). Claude Desktop does not read your shell's PATH, so use the absolute path printed by which lr-mcp:
{
"mcpServers": {
"lightroom": {
"command": "/Users/<you>/.local/bin/lr-mcp"
}
}
}If you set LR_MCP_HOME, add "env": {"LR_MCP_HOME": "/path/to/dir"} to the entry. Quit Claude Desktop completely and reopen it; the lr_* tools then appear in the tools menu. On macOS the server log is ~/Library/Logs/Claude/mcp-server-lightroom.log.
Claude Code:
claude mcp add lightroom -s user -- "$(which lr-mcp)"The absolute path avoids depending on the PATH Claude Code was started with; check that which lr-mcp prints a path first, or an empty command gets registered. If claude mcp get lightroom shows an existing server, check what it runs and its environment, then remove it with claude mcp remove lightroom -s user before adding. Start a new Claude Code session for the lr_* tools to appear. If you set LR_MCP_HOME, add -e LR_MCP_HOME=/path/to/dir before --.
The client config can be added before or after signing in; without tokens the tools reply "Not signed in" and lr_login can do the sign-in from the chat.
Troubleshooting
Symptom | Fix |
| Run |
| Change |
| Step 2: run |
| Download only the OAuth Web App credential (step 1.5) instead of the whole project, and retry. |
The Adobe sign-in page shows an error right away | Usually a wrong |
|
|
| The signed-in account is not a beta user (step 1.4) or has no Lightroom plan. |
The browser lands on | Adobe silently falls back to the default redirect URI when the requested one does not match the pattern. Set the pattern to |
The sign-in redirect shows another app's page or never loads | Something else listens on the port ( |
| The browser stopped at the certificate warning; proceed past it next time. |
| Run |
Tools missing in Claude Desktop | Use the absolute path to |
For AI agents
If a user asks you to set this server up:
Never ask the user to paste the client secret into the chat, and never read or print the downloaded credential JSON or the contents of the state directory (
.env,.tokens.json,.certs/, editor backups such as.env~). Save the credential withlr-mcp setup --from <file> --delete(step 2). Only pass the file's path; listing file names, e.g.ls -t ~/Downloads/*.json, is fine. If more than one file could be it, ask the user which.setupreplaces only theADOBE_CLIENT_*lines in.env, so it is safe to run on an existing file.Install (step 0) and run
lr-mcp doctorfirst. If it already printsSetup is complete., skip to step 5. Rundoctoragain after every step; afix:that starts with[human]is something to hand to the user.The user must create the credential, add the beta user, download the credential JSON, and finish the browser sign-in. Give them the exact console steps from step 1; the redirect URI values are the same for everyone.
Put only
LR_MCP_HOMEorLR_MCP_PORTin a client's"env"/-e, neverADOBE_CLIENT_IDorADOBE_CLIENT_SECRET.lr-mcp loginblocks for up to 5 minutes while the user signs in; the[human]part is the browser sign-in. You may run it in the background, but first tell the user a browser window will open on their screen and warn them about the certificate page. Rundoctorafterwards to confirm the sign-in.The MCP server reads
.envonly when it starts. If the client already had the server registered and running when you ransetup, tell the user to restart the client (quit and reopen Claude Desktop, or start a new Claude Code session) before using thelr_*tools.Setup is done when
doctorprintsCatalog found. Setup is complete.Add the client config (step 5) before or after that. If alightroomentry already exists in the client, show the user what it runs and ask before replacing it. When readingclaude mcp getoutput orclaude_desktop_config.json, show only commands and env variable names, never env values: they may hold other servers' secrets. For Claude Desktop, merge into the existing JSON instead of overwriting it, use the absolute path fromwhich lr-mcp, passLR_MCP_HOMEin"env"if it is set, and tell the user to quit and reopen the app. For Claude Code, register the absolute path and tell the user to start a new session.
Development
git clone https://github.com/longfin/lr-mcp && cd lr-mcp
uv sync
uv run lr-mcp doctor
uv run pytestTo run a checkout from an MCP client, use uv run --directory /path/to/lr-mcp lr-mcp as the command. Without installing, uvx lr-mcp <command> also works.
License
Available Tools
10 toolslr_accountA
Account info: subscription status and cloud storage usage.
Inputs: no named parameters. Returns: result
lr_add_to_project_albumB
Add photos to a project album. Albums the user created cannot be modified.
Inputs: album_id (required), asset_ids (required). Returns: result
lr_create_project_albumB
Create a project album owned by this server (shown under Connections in Lightroom). Adds asset_ids right away if given.
Inputs: name (required), asset_ids. Returns: result
lr_delete_project_albumA
Delete a project album created by this server. Only the album is removed; photos stay in the catalog.
Inputs: album_id (required). Returns: result
lr_download_photosA
Save photos as JPEG files. Pass either asset_ids or album_id (the whole album). size: '640' | '1280' | '2048' | '2560' | 'fullsize' (original resolution with edits; slower). dest_dir defaults to ~/Downloads/lightroom/. Files are named after the original file name with a .jpg extension. <dest_dir>/.lr-mcp.json records what was saved; on the next call into the same folder, photos whose file, size and edit time are unchanged are skipped. This needs a stable folder: album_id or an explicit dest_dir (asset_ids alone get a new export- folder each time). force=True re-downloads everything, e.g. if a saved file looks stale.
Inputs: size, force, album_id, dest_dir, +1 more. Returns: result
lr_get_photoB
Details for one photo: capture info, rating/flag, title, caption, keywords, original file, original and cropped pixel size, orientation (EXIF value; 6 and 8 are 90-degree rotations; the sizes are as stored and are not swapped for it), GPS when present, and a summary of its edits.
Inputs: asset_id (required), include_develop. Returns: result
lr_list_albumsB
List albums as 'Folder / Album' paths with their ids. query: case-insensitive substring of the path, e.g. 'kyoto' or '2024'. Folders are tagged [folder]; project albums created by this server are tagged [project].
Inputs: query, include_folders. Returns: result
lr_list_photosA
List photos matching filters, oldest capture first (in an album: the album's order, see sort). album_id: search inside one album; omit to search the whole catalog (then narrow it with captured_after). sort (with album_id only): 'album' (default) keeps the album's own order as set in Lightroom (custom order, or capture date ascending/descending); 'captured' forces oldest capture first. The first line names the album's order, e.g. 'album order: customAsc'; limit applies after sorting. Without album_id, sort is ignored and results are always oldest capture first. captured_after / captured_before: 'YYYY-MM-DD' or 'YYYY-MM-DDTHH:MM:SS'. min_rating: minimum star rating (1-5). flag: 'pick' or 'reject'. camera / lens / filename: case-insensitive substrings. min_iso: minimum ISO. hour_from / hour_to: time of day in the camera's local capture time, 0-23 inclusive; wraps past midnight when hour_from > hour_to (e.g. 19 and 4 for night shots). max_fnumber / min_fnumber: f-number bounds, e.g. max_fnumber=2 for f/2 or wider, min_fnumber=8 for f/8 or narrower. Useful when lens info is missing (manual lenses). Photos without the needed capture time or f-number are excluded when these are set. A scan stops after 20000 assets or 60 s; the first line then says the results are partial, so on a large catalog narrow with captured_after up front. Each line: id | file | captured | rating | flag | exposure | camera + lens | title: ... | caption: ... Empty fields are left out; title and caption are cut to 60 characters (lr_get_photo has them in full).
Inputs: flag, lens, sort, limit, +11 more. Returns: result
lr_loginA
Sign in to Adobe in the browser and store tokens. Only needed when another tool reports that the user is not signed in or the token refresh failed. Waits up to 5 minutes for the user to finish signing in. The callback is https://localhost:8000/callback (or LR_MCP_PORT). If port 8000 is busy, another port is used, which needs the redirect URI pattern https://localhost:[0-9]+/callback in the Adobe console; with an older pattern such as https://localhost:8000/.* the browser lands on the other app at :8000 and sign-in times out. The reply says when this happened.
Inputs: no named parameters. Returns: result
lr_view_photosA
Fetch photos as images to look at them (JPEG with edits applied). Up to 12 per call. size: 'thumbnail2x' (small, for scanning many) | '640' | '1280' | '2048'.
Inputs: asset_ids (required), size.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 10 tools
The three photo-access tools (lr_view_photos, lr_get_photo, lr_download_photos) could superficially be confused, but their descriptions clearly separate visual inspection, metadata retrieval, and saving to disk. Album tools split cleanly into list/create/add/delete, and lr_login/lr_account are self-explanatory.
All names share an lr_ prefix and most follow a verb_noun pattern (lr_list_albums, lr_create_project_album, lr_add_to_project_album). Minor deviations: lr_account is a bare noun and lr_login has no object, but the convention is otherwise predictable.
Ten tools is well-scoped for a Lightroom catalog server: one auth, one account, four album operations, and four photo read/export operations. No tool appears redundant or trivial.
Reading and exporting are thorough, but the album lifecycle is asymmetric: you can add to a project album but there is no tool to remove photos from one, and no way to create/rename/delete user-owned albums. Metadata is also read-only (no rating/flag/keyword/title updates), leaving obvious gaps for an agent asked to curate a catalog.
Maintenance
Related MCP Connectors
Search photos and video moments by visual meaning, people, dates, and folders across local libraries, Apple Photos, and OneDrive. Manage collections, groups, favorites, people, and duplicate review. Synced metadata remains searchable while the desktop is offline; local and Apple Photos media access needs the owning device online with remote access enabled. OneDrive media can be accessed directly from the cloud. OAuth or Bearer API keys. Paid Cloud Access required; hosted visual search uses prepaid credits. Text-in-image search is semantic matching, not guaranteed exact OCR. Setup: https://organizewith.ai/en/guides/connect-ai-assistants
Generate, manage and explore your Switch AI image and video library, scoped to your account.
Connect your Trioly account to your AI assistant. Creators can browse and organize their own video vault, upload new footage, edit work details, check earnings, and put works on sale or take them off. Buyers can search real footage, photos and art made by people, check license terms, and get the link to license on the Trioly website (nothing is charged through the AI). Every work has a certificate of original registration, and copyright stays with the creator. Files in your vault are not used for AI training.
Upload, generate, organize, search, and transform images, videos, and files with AI-powered tools.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables AI agents to control Adobe Lightroom Classic on macOS for professional photo editing and catalog management. It allows users to inspect photos, apply develop settings, and automate workflows through a secure local bridge without direct catalog database manipulation.2595MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to search, list, preview, and export photos from Apple Photos, Google Photos Picker sessions, and local Google Takeout archives using native search and metadata inspection.6 npmMIT
- AlicenseCqualityCmaintenanceEnables AI agents to control Adobe Lightroom Classic develop settings, manage presets and catalogs, and perform round-trip handoffs with Adobe Photoshop for advanced retouching. Provides native socket bridging for exposure, color grading, search, ratings, keywords, collections, and export workflows.40MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to drive Adobe Lightroom Classic directly — searching and organizing catalogs, reading and writing the full set of develop parameters, building geometric and AI-generated masks (sky, subject, mountains, water, people), applying presets, and rendering previews, histograms, and exports. All capabilities are exposed as 167 MCP tools over a Lua plugin bridge, with write-confirmation sentinels so silently dropped edits surface as explicit errors.Apache 2.0