Lightroom Classic MCP Server
This server is an unofficial bridge for automating non-generative photo workflow tasks in Adobe Lightroom Classic, using an asynchronous job queue so tools return a job_id immediately while the plugin processes work in the background.
Import photos: Queue the import of files or folders into a Lightroom Classic catalog, with options to move files or add them to a specific collection.
Export photos: Queue the export of selected photos, collections, or recently imported photos to a chosen output directory, with support for advanced export settings.
Apply develop settings: Apply a non-destructive set of develop adjustments (e.g., exposure, contrast, highlights, shadows, texture, clarity, vibrance, temperature) to photos without altering original files.
Apply develop presets: List available develop presets and apply existing ones by name or UUID non-destructively.
Generate previews: Render fast, low-resolution sRGB JPEG previews of the current develop state for multimodal AI vision or user inspection.
Adaptive editing: Queue AI-authored adaptive edits using mask group-based corrections (e.g., subject, sky, background).
Read develop settings: Read a photo's full develop settings, including mask-based corrections, for AI analysis.
Job management: Check status, retrieve results or errors, list recent jobs (up to 200), or cancel queued/running jobs.
Server configuration: Display the effective non-secret server configuration (bridge host, port, directories, etc.).
The server does not generate, synthesize, or AI-edit pixels — it automates existing Lightroom Classic catalog and workflow tasks only.
Click on "Install 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., "@Lightroom Classic MCP ServerImport ~/Desktop/photo.dng, apply 'B&W' preset, export as JPEG"
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.
Lightroom Classic MCP Server
WIP warning: this project now supports a minimal local Lightroom Classic workflow, but it is not a full automation suite. Use a single test image first, and keep imports/exports scoped to explicit files, selections, or collections.
Unofficial Lightroom Classic MCP server for local Adobe Lightroom Classic automation. It gives MCP clients such as Claude Desktop, Codex, ChatGPT-compatible MCP hosts, and other Model Context Protocol clients a structured way to queue non-generative Lightroom Classic work on your own computer.
This project is also discoverable as an Adobe Lightroom Classic MCP server, MCP for Lightroom Classic, and Claude/Codex/ChatGPT Lightroom Classic automation bridge.
Unofficial Project
This is not Adobe software. It is not affiliated with, endorsed by, sponsored by, or supported by Adobe. Adobe, Lightroom, and Lightroom Classic are trademarks of Adobe Inc. This project is an independent local automation bridge for users who already run Adobe Lightroom Classic. It is also not a generative image editor: it does not create, synthesize, replace, or AI-edit pixels.
Related MCP server: Photoshop MCP Server
What It Does
The goal is practical, non-generative photo workflow automation. This server does not create images and does not call image generation models. It is designed for Lightroom Classic catalog and workflow tasks such as:
importing files or folders into a Lightroom Classic catalog;
applying develop settings or preset-driven adjustments;
exporting selected photos, collections, or batches to a chosen folder;
updating metadata, collection membership, or workflow tracking fields;
coordinating batch workflow steps that may take longer than a chat client request.
Current Status
Minimal usable workflow. The TypeScript MCP server, local HTTP bridge, job queue, single-process lock, structured logging, and Lightroom Classic Lua plugin are in place.
The included Lightroom Classic plugin polls the bridge, claims jobs, imports files into the active catalog, applies a small allowlisted set of non-destructive develop settings, lists and applies existing Lightroom develop presets, renders low-resolution JPEG previews of the current develop state, and exports selected/imported/collection photos as JPEGs. Metadata editing, Lightroom named export presets, recursive collection lookup, and larger batch workflow features are still future work.
For this repository's immediate self-use goal, "working" means this local Mac can install the plugin/server, import one real photo into Lightroom Classic, apply non-generative develop settings, export a JPEG to /Users/yopiesuryadi/Documents/leica, and verify the output file exists.
Why Async Jobs
Lightroom Classic operations can take longer than an MCP client timeout. Large imports, previews, exports, preset application, metadata writes, and batch workflows may run for minutes. If an MCP tool tries to do all of that inside one synchronous request, Claude, Codex, ChatGPT, or another MCP host can time out before Lightroom finishes.
This server uses an async job queue instead:
The MCP client calls a tool such as
start_importorstart_export.The Node server stores a job and immediately returns a
job_id.The Lightroom Classic plugin polls the local bridge for queued work.
The plugin claims the job, performs Lightroom-side work, and reports progress.
The client polls
job_statusorlist_jobsuntil the job succeeds or fails.
That design keeps the chat/MCP request short while allowing Lightroom Classic to continue the real desktop operation in the background.
Requirements
macOS with Adobe Lightroom Classic installed.
Node.js 20 or newer.
An MCP-capable client, such as Claude Desktop, Codex, a ChatGPT MCP host, or another Model Context Protocol client.
Quickstart
git clone https://github.com/yopiesuryadi/lightroom-classic-mcp-server.git
cd lightroom-classic-mcp-server
npm install
npm run build
npm run install:plugin
npm run verify:plugin
npm startThe installer copies this repository's plugin to:
~/Library/Application Support/Adobe/Lightroom/Modules/LightroomClassicMCPServer.lrpluginIt deliberately uses a distinct folder name and preserves any older LightroomMCP.lrplugin folder. If an existing LightroomClassicMCPServer.lrplugin already looks like this project, the installer moves it to a timestamped backup before copying the current plugin; it refuses to replace unrelated folders unless you explicitly pass --force. Disable older duplicate plugin entries in Lightroom Classic if more than one appears in Plug-in Manager.
In Lightroom Classic, after installing or updating the plugin:
Open
File > Plug-in Manager.Confirm
Lightroom Classic MCP Server Bridgeis present and enabled.If it is not listed, click
Addand select the installedLightroomClassicMCPServer.lrpluginfolder above.Keep Lightroom Classic open so the plugin can poll the local bridge.
If Lightroom Classic was already running when you installed the plugin, quit and reopen Lightroom Classic, or manually add/reload the plugin in Plug-in Manager. Lightroom does not always load a newly copied .lrplugin folder until that happens.
Then add the MCP server command to your MCP client configuration and restart that client.
For a real local smoke test on this Mac, keep Lightroom Classic open with the plugin enabled, then run:
npm run build
npm run install:plugin
npm run smoke:local -- --input "/absolute/path/to/test-photo.jpg" --output-dir "/Users/yopiesuryadi/Documents/leica"The smoke script starts the local bridge, queues import, edit, and export jobs, waits for the Lightroom Classic plugin to claim and finish them, and verifies that an exported file exists.
Install From This Repository
npm install
npm run build
npm run install:plugin
npm run verify:pluginThe built server entrypoint is:
dist/index.jsThe source Lightroom Classic plugin folder in this repository is:
lightroom-classic-mcp-server.lrpluginThe installed Lightroom Classic plugin folder is:
~/Library/Application Support/Adobe/Lightroom/Modules/LightroomClassicMCPServer.lrpluginInstaller Commands
npm run install:lightroom-plugin
npm run install:plugin
npm run verify:plugininstall:lightroom-plugin is kept as a descriptive alias for install:plugin. The installer creates the Lightroom Modules folder if needed, backs up same-project installs, and copies the repository plugin into place without overwriting unrelated plugin folders. The verifier checks the installed plugin folder, expected toolkit identifier, Lightroom Classic process status, and the local bridge health endpoint if the MCP server is already running.
Configuration
Configuration is provided through environment variables.
LRC_MCP_BRIDGE_HOST=127.0.0.1
LRC_MCP_BRIDGE_PORT=58765
LRC_MCP_INPUT_DIR=~/Pictures
LRC_MCP_OUTPUT_DIR=~/Documents/leica
LRC_MCP_STATE_DIR=~/.lightroom-classic-mcp-server
LRC_MCP_LOG_FILE=~/.lightroom-classic-mcp-server/server.log
LRC_MCP_LOCK_FILE=~/.lightroom-classic-mcp-server/server.lockDefaults:
bridge host:
127.0.0.1bridge port:
58765input directory:
~/Picturesoutput directory:
~/Documents/leicastate directory:
~/.lightroom-classic-mcp-serverlog file:
~/.lightroom-classic-mcp-server/server.loglock file:
~/.lightroom-classic-mcp-server/server.lock
MCP Config Examples
Use an absolute path to dist/index.js after running npm run build.
Claude Desktop
{
"mcpServers": {
"lightroom-classic": {
"command": "node",
"args": [
"/Users/yopiesuryadi/Documents/leica/mcp/dist/index.js"
],
"env": {
"LRC_MCP_OUTPUT_DIR": "/Users/yopiesuryadi/Documents/leica"
}
}
}
}Codex
[mcp_servers.lightroom-classic]
command = "node"
args = ["/Users/yopiesuryadi/Documents/leica/mcp/dist/index.js"]
[mcp_servers.lightroom-classic.env]
LRC_MCP_OUTPUT_DIR = "/Users/yopiesuryadi/Documents/leica"ChatGPT-Compatible MCP Host
Use the same stdio command shape if your ChatGPT or OpenAI-compatible MCP host supports local MCP servers:
{
"name": "lightroom-classic",
"command": "node",
"args": [
"/Users/yopiesuryadi/Documents/leica/mcp/dist/index.js"
],
"env": {
"LRC_MCP_BRIDGE_PORT": "58765"
}
}Exact file locations and schema names vary by host. The important parts are the node command, the absolute dist/index.js path, and any LRC_MCP_* environment variables you want to override.
MCP Tools
start_import: queue a Lightroom Classic import and return ajob_id.start_export: queue a Lightroom Classic export and return ajob_id.start_edit_tracking: queue a non-destructive develop-setting workflow and return ajob_id.get_develop_settings: queue a job that reads the target photo's full develop settings (including mask-based corrections) for AI inspection.start_adaptive_edit: queue an AI-authored adaptive (masked) edit; Lightroom computes Select Subject / Sky AI masks when the generated preset is applied. See the AI-Adaptive Editing Loop section for value-scale rules.get_preview: queue a fast, low-resolution sRGB JPEG render of the current develop state and return ajob_id.job_resultthen returns the absolute preview path(s) and the JPEG as inline MCP image content for multimodal AI vision.list_develop_presets: queue a job that enumerates develop preset folders, preset names, and UUIDs.apply_develop_preset: queue a job that applies an existing develop preset (by name or UUID) non-destructively.job_status: inspect one job.job_result: inspect a completed job result without the full job envelope.job_error: inspect a failed job error without the full job envelope.list_jobs: list recent jobs.cancel_job: cancel a queued or running job.server_config: show effective non-secret server configuration.
AI-Adaptive Editing Loop
The preview and develop-setting tools support an AI-adaptive editing loop without changing Lightroom's non-destructive model:
Perceive: call
get_preview, polljob_status, then inspect the absolute JPEG preview path or inline preview image fromjob_result.Decide: compare the preview against the intended photographic direction and choose a small develop-setting or preset adjustment.
Act: call
start_edit_trackingwith allowlisted develop settings, or callapply_develop_presetwith a UUID fromlist_develop_presets.Verify: call
get_previewagain and compare the new current develop state before making another adjustment or exporting.
Beyond existing presets, start_adaptive_edit accepts raw MaskGroupBasedCorrections, so the model can author per-area corrections (subject / sky / background) with free values instead of a fixed preset matrix. Local values use XMP scale (LocalExposure2012 ±1.0 = ±4 stops); out-of-range values are silently dropped by Lightroom, and a new adaptive edit replaces all previous mask corrections.
For wiring this into an OpenClaw Telegram assistant, see docs/openclaw.md and the agent playbook example in docs/playbook-example.md.
Adaptive preset selection is still an experiment. Preset enumeration and application are available, but the model or operator is responsible for choosing appropriate presets, avoiding duplicate or ambiguous names by preferring UUIDs, and verifying the result with a preview before export.
Why get_preview Is Async
get_preview deliberately follows the existing async job pattern. The only channel into Lightroom Classic is the plugin's bridge poll loop (roughly every 2 seconds), and develop renders — especially of RAW files — can exceed an MCP client timeout. A synchronous tool would have to block the MCP request on both the poll interval and the render, so async is the safer choice here. The multimodal payoff still works: once the job succeeds, job_result attaches the rendered JPEG as inline MCP image content alongside the JSON result.
Preview behavior:
Previews render through
LrExportSessionas sRGB JPEGs constrained tomax_dimension(default 1200 px, capped at 2048) at JPEGquality(default 70).Preview files are written to
~/.lightroom-classic-mcp-server/previews/<job_id>/. The plugin deletes preview entries older than 24 hours on startup.One preview job renders at most 8 photos;
result.truncatedistruewhen the target contained more.job_resultinlines up to 4 preview images (up to ~3.5 MB each); the absolute path(s) are always in the JSON result regardless.
Worked Example: Preview → Analyze → Edit → Verify
Assume one photo was just imported (target: "last_import"):
Call
get_previewwith{ "target": "last_import" }and polljob_statusuntil it succeeds.Call
job_result. The vision-capable client sees the preview image inline plusresult.preview_path.The AI observes, for example: underexposed midtones, a warm cast, flat contrast. It queues
start_edit_tracking:
{
"target": "last_import",
"operation": "apply_develop_settings",
"parameters": {
"exposure": 0.4,
"contrast": 12,
"shadows": 18,
"temperature": -300,
"vibrance": 8,
"vignette": -12,
"grain_size": 25,
"grain_frequency": 50
}
}Call
get_previewagain and compare. If highlights now clip, follow up with a smaller correction such as{ "highlights": -20, "exposure": -0.1 }and re-verify.For a black-and-white treatment, send
{ "black_white": true }(boolean), or apply a B&W preset viaapply_develop_preset.When the preview matches the intent, call
start_exportfor the full-resolution output.
Supported develop-setting aliases include black_white/grayscale (boolean ConvertToGrayscale), vignette (PostCropVignetteAmount), grain/grain_amount, grain_size, and grain_frequency, in addition to the tone/color/crop keys listed in the start_edit_tracking tool description.
Adaptive Presets (Select Subject / Select Sky): Experiment Status
Lightroom Classic ships "Adaptive: Subject" and "Adaptive: Sky" preset groups that create AI masks when applied. Honest status: applying adaptive presets through this bridge is untested and may not compute masks headlessly. Adaptive presets do appear in LrApplication.developPresetFolders() on recent Lightroom Classic versions and photo:applyDevelopPreset accepts them, but the Select Subject/Select Sky mask computation runs in Lightroom's own ML pipeline, and Adobe does not document whether SDK-applied adaptive presets trigger it reliably outside the Develop module UI.
Manual experiment procedure (run once on your machine and record the outcome):
Import a test photo with a clear subject and visible sky, and select it in Lightroom.
Call
list_develop_presetswith{ "name_filter": "adaptive" }and note the preset UUIDs (folders typically namedAdaptive: SubjectandAdaptive: Sky).Call
apply_develop_presetwith one of those UUIDs andtarget: "selection".Verify in Lightroom's Develop module: open the Masking panel and confirm a
SubjectorSkymask was actually created with adjustments attached — not just a preset entry in the History panel.Call
get_previewbefore and after and compare renders visually; an adaptive preset that silently no-ops produces an unchanged preview.If the mask is missing or empty, fall back to the manual step: select the photo in Lightroom, open the Presets panel in the Develop module, and click the adaptive preset there (the UI path always triggers mask computation). The rest of the loop — preview, verify, export — stays automated.
If the experiment succeeds on your Lightroom version, adaptive presets work inside the loop like any other preset. If it fails, treat adaptive presets as the one manual step in an otherwise automated loop.
Example Workflow
Ask your MCP client to import one image into Lightroom Classic.
The client calls
start_importand receives ajob_id.Ask for the job status, or have the client poll
job_status.After import completion, queue a small edit job, for example:
{
"target": "last_import",
"operation": "apply_develop_settings",
"parameters": {
"exposure": 0.15,
"contrast": 8,
"vibrance": 10
}
}Queue an export job with
selected_only: true, acollection, or no target after an import. With no target, the plugin exports the last photo(s) imported by this plugin session, then falls back to the current Lightroom selection. The default export folder is~/Documents/leica.
For long imports or exports, prefer polling status over asking the client to wait silently.
Smoke Test
Use a single disposable image for the end-to-end test. The import is catalog-only and the develop settings are Lightroom non-destructive edits; the export writes a new JPEG and should not overwrite originals.
npm install
npm run build
npm run install:plugin
npm run verify:plugin
npm startThen in Lightroom Classic, confirm the plugin is enabled in File > Plug-in Manager.
For the direct local harness:
npm run smoke:local -- --input "/absolute/path/to/test-image.jpg" --output-dir "/Users/yopiesuryadi/Documents/leica"From an MCP client, run:
server_configstart_importwithpaths: ["/absolute/path/to/test-image.jpg"]job_statusuntil it succeedsstart_edit_trackingwithtarget: "last_import",operation: "apply_develop_settings", and a small settings objectstart_exportwithoutput_dir: "~/Documents/leica"job_resultto inspect the exported file path
Troubleshooting
The MCP client cannot start the server
Run
npm run buildand confirmdist/index.jsexists.Use an absolute path in your MCP config.
Confirm Node.js 20 or newer with
node --version.Check
~/.lightroom-classic-mcp-server/server.log.
Lightroom Classic does not appear to receive jobs
Confirm the
.lrpluginfolder is installed in Lightroom Classic Plug-in Manager.Confirm Lightroom Classic is open.
Confirm the server is listening on
127.0.0.1:58765, or updateLRC_MCP_BRIDGE_PORTconsistently.Look at
~/.lightroom-classic-mcp-server/server.logand the Lightroom plugin logs.
Startup fails because another server is running
The server uses a lock file to avoid multiple local bridge processes fighting for the same Lightroom Classic connection. Stop the older Node process, or inspect:
cat ~/.lightroom-classic-mcp-server/server.lockIf the process in the lock file is no longer running, a new server should replace the stale lock on startup.
Jobs stay queued
Queued jobs usually mean the Node MCP server is running but the Lightroom Classic plugin has not claimed work. Check that the plugin is installed, enabled, and configured for the same bridge host and port.
For local smoke testing, a timeout before the import job changes from queued means the Lightroom plugin is not polling the bridge. Restart Lightroom Classic or add/reload LightroomClassicMCPServer.lrplugin in Plug-in Manager, then rerun npm run smoke:local.
Jobs fail immediately
Check the returned error field with job_error. Common causes are a missing import path, no selected photo, a collection name that does not exist, unsupported source file format, Lightroom catalog write-access timeout, or an export destination that Lightroom cannot write.
Development
npm install
npm run build
npm run typecheck
npm run lintRead docs/design.md for more detail on the timeout failure mode, async job queue, local bridge, and stale process strategy.
Available Tools
9 toolscancel_jobC
Cancel a queued or running Lightroom Classic job.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the burden. It only states 'Cancel' but does not disclose what happens after cancellation (e.g., irreversibility, success/failure indication, side effects). The behavioral profile is minimally defined.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no fluff. However, it could include brief parameter details without sacrificing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity (1 param, no output schema), the description is incomplete. It lacks usage context, parameter details, and behavioral expectations, making it insufficient for an agent to reliably invoke the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has one parameter 'job_id' with 0% description coverage. The description does not explain what 'job_id' is (e.g., format, how to obtain it, or its purpose). No added meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Cancel a queued or running Lightroom Classic job.' It uses a specific verb ('Cancel') and resource ('job'), and distinguishes from sibling tools like 'list_jobs' and 'job_status' which have different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. It does not mention prerequisites (e.g., the job must be queued or running) or when cancellation is appropriate compared to other job-related tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
job_errorC
Get the error message for a failed Lightroom Classic job.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It minimally states it returns an error message for a failed job, but does not disclose behavior for non-failed jobs, return format, or authentication requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One concise sentence, front-loaded with purpose, but could include more useful details without adding verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and minimal description, the tool lacks completeness about what is returned or how to interpret the error message. Siblings are listed but not differentiated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for the single parameter job_id. The description does not add meaning beyond the parameter name, such as format or constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get' and the resource 'error message for a failed Lightroom Classic job', distinguishing it from sibling tools like job_status or list_jobs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives, such as only after checking job_status or job_result, or that it is only applicable for failed jobs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
job_resultC
Get the result for a completed Lightroom Classic job.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description lacks behavioral details such as what happens if the job is not completed, authorization requirements, or rate limits. It only states it's a 'get' operation without elaboration.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single concise sentence, but it is too brief to be fully informative. No wasted words, but under-specification reduces effectiveness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and simple input, the description should explain return values, error conditions, and usage context. It lacks these details, making it incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The sole parameter job_id has 0% schema description coverage, and the tool description does not explain its meaning, format, or constraints. The description adds no value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the action (get) and resource (result for a completed Lightroom Classic job). It distinguishes from siblings like job_status and job_error, though it could be more explicit about the 'completed' qualifier.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives like job_status or job_error. No mention of prerequisites (e.g., job must be completed) or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
job_statusC
Get the current status of a queued Lightroom Classic job.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description does not disclose any behavioral traits such as read-only nature, error handling, authentication needs, or response format. The agent has no insight into side effects or constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence, but it is overly minimal. While front-loaded, it sacrifices necessary detail, making it barely adequate.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple tool with one parameter and no output schema, the description fails to explain what 'current status' means, possible values, or how the response looks. It does not differentiate from sibling status-related tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description adds no meaning for the job_id parameter beyond its name. No format, range, or example is given.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get' and the resource 'current status of a queued Lightroom Classic job'. It distinguishes this tool from siblings like cancel_job, job_error, and job_result, which have different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives such as job_error or job_result. The description does not mention contexts or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_jobsC
List recent Lightroom Classic jobs.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description must fully convey behavioral traits. It mentions 'recent' but does not define recency (e.g., time window) nor indicate read-only nature or any side effects. Missing critical context for safe invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise with a single sentence that communicates the core purpose. No wasteful repetition, but could be improved by front-loading critical context like return type.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a simple tool with one optional parameter and no output schema, the description should at least hint at the response format (e.g., list of job IDs/statuses) or default ordering, but it does not. Incomplete for an agent to fully understand what the tool returns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter (limit) is present, fully defined in the schema with default, min, max. The description adds no additional meaning beyond the schema, but schema coverage is 100% for that parameter, so baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool lists Lightroom Classic jobs, with a specific verb and resource. However, it does not differentiate from sibling tools like job_status or job_error, which may also list jobs with different scopes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. Siblings include cancel_job, job_error, job_result, job_status, etc., but the description does not explain that this list is for recent jobs or how it differs from job_status.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
server_configB
Show effective non-secret server configuration.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so description must fully disclose behavior. It implies a read operation but omits details like authentication requirements, rate limits, or what 'effective' means.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, front-loaded, zero waste. Perfectly concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters and no output schema, description is minimal. It explains the basic purpose but lacks details on return format or additional context, making it merely adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters, so schema coverage is 100%. Description adds meaning beyond schema by specifying the output scope (non-secret server configuration), earning a baseline 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'Show' and resource 'effective non-secret server configuration'. It is distinct from job-related siblings, though no explicit differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. Siblings are job-focused but no explicit when-not or context provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_edit_trackingA
Queue a Lightroom-side non-destructive develop settings job.
| Name | Required | Description | Default |
|---|---|---|---|
| target | Yes | Target understood by the plugin: selection, selected, last_import, or last_imported. | |
| operation | Yes | Use apply_develop_settings, apply_settings, or apply_preset. | |
| collection | No | Optional top-level collection name to edit. | |
| parameters | No | Develop settings object. Supported keys include exposure, contrast, highlights, shadows, whites, blacks, texture, clarity, dehaze, vibrance, and saturation. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully disclose behavior. It mentions 'non-destructive' and 'queue' implying an async job, but omits important details: what is returned (job ID?), safety, side effects, error handling, or whether multiple jobs can be queued. The disclosure is incomplete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence with no unnecessary words. Every part contributes to understanding the tool's function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 4 parameters, no output schema, and no annotations, the description covers the basic purpose and one behavioral aspect (non-destructive). However, it lacks return value info, async behavior confirmation, and error scenarios. It is adequate but not comprehensive for a moderately complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, but the description adds value especially for the 'parameters' object by listing supported keys (exposure, contrast, etc.), which is not fully covered by the schema's generic description. For 'target' and 'operation', it clarifies permissible values beyond schema constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool queues a non-destructive develop settings job, specifying verb ('queue'), resource ('develop settings job'), and context ('Lightroom-side, non-destructive'). It distinguishes from siblings like start_export and start_import which serve different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool vs alternatives. The description does not mention prerequisites, when not to use it, or contrast with related tools in the sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_exportB
Queue a Lightroom Classic export job and return immediately with a job_id.
| Name | Required | Description | Default |
|---|---|---|---|
| preset | No | Reserved for future Lightroom export preset support. | |
| collection | No | Collection to export from. | |
| output_dir | No | Export destination folder. | /root/Documents/leica |
| selected_only | No | Export current Lightroom selection only. | |
| export_settings | No | Optional advanced Lightroom export settings table override. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, description correctly states async behavior (queues, returns immediately with job_id), but does not disclose error conditions, capacity limits, or side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence conveying action, resource, and async behavior; efficient and to the point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Lacks information on how to retrieve export results or monitor progress, despite presence of sibling job-query tools; no output schema means description should hint at return format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers all parameters with descriptions; description adds no extra semantic value beyond what schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verb 'queue' and resource 'Lightroom Classic export job', clearly distinguishing from sibling import/edit tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool vs alternatives; lacks context about prerequisites or alternatives like start_edit_tracking.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_importA
Queue a Lightroom Classic import job and return immediately with a job_id.
| Name | Required | Description | Default |
|---|---|---|---|
| paths | Yes | Files or folders to import into Lightroom Classic. | |
| move_to | No | Optional destination folder for Lightroom's import move/copy flow. | |
| collection | No | Optional collection name to add imported photos to. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description must convey behavioral traits. It mentions the async queue behavior and immediate return of job_id, but omits details like error handling, permission requirements, or potential side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that efficiently conveys the core functionality without extraneous words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 3 parameters, no output schema, and no annotations, the description is minimally adequate. It explains the immediate return of job_id but doesn't clarify how to use it (e.g., polling with job_status), which limits completeness for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 100% coverage with descriptions for all three parameters. The tool description adds no extra meaning beyond the schema, so baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Queue'), the resource ('Lightroom Classic import job'), and the async nature ('return immediately with a job_id'). It distinguishes from siblings like start_export and cancel_job.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives such as start_export, or any prerequisites. The description lacks context for selecting this tool over sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
9 tool updates
v0.1.0- First observed
cancel_job - First observed
job_error - First observed
job_result - First observed
job_status - First observed
list_jobs - First observed
server_config - First observed
start_edit_tracking - First observed
start_export - First observed
start_import
TDQS
Scored across 9 tools
Each tool has a distinct purpose: job management tools (cancel, error, result, status, list) are clearly separated from action starting tools (import, export, edit tracking) and server configuration. No overlap.
All tool names follow a consistent verb_noun pattern in snake_case. Prefixed verbs like cancel_, list_, start_ and noun prefixes like job_, server_ maintain predictability.
Nine tools is appropriate for a Lightroom Classic server. It covers job management and core operations without being too few or overly numerous.
The tool set covers job lifecycle (create, monitor, cancel, get results) and main operations (import, export, edit). Missing a delete job tool but the core workflow is fully supported.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
A Model Context Protocol server for Wix AI tools
Model Context Protocol server for the Apideck Unified API. Connect any MCP-compatible agent framework to 100+ accounting systems, HRIS platforms, file storage providers, and more through one integration. More information https://www.apideck.com/mcp-server
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
A Model Context Protocol (MCP) server for Selise Blocks Cloud integration
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.592MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI clients to control Adobe Photoshop on macOS through AppleScript using the Model Context Protocol.-
- AlicenseNot gradedqualityAmaintenanceGives AI agents access to ComfyUI generation, workflows, installed models, recent assets, and job controls through the Model Context Protocol.MIT
- AlicenseAqualityBmaintenanceAgent-driven RAW photo manager and non-destructive editor with Lightroom-style library and develop tools, controllable via MCP and REST.144MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/yopiesuryadi/lightroom-classic-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server