- name
- adobe-batch-edit-photos
- description
- Apply consistent photo adjustments across a set of images so they look like they were edited together. Use this skill whenever the user says "make my photos look cohesive", "give all these the same style", "apply a warm and golden feel to all of these", "make this cinematic", "match the look across my photos", "edit all my travel photos the same way", "batch edit these", "make these consistent", "fix my phone photos", or uploads a folder of photos and wants a unified, polished result. Also triggers for requests like "apply a preset to all of these", "make these look professional", or "they were shot in mixed lighting — can you fix them all". Outputs direct final image URLs plus an in-chat preview grid and optional Firefly Board link. Access: 🔐 Signed-In required | Gen AI: ❌
- license
- Apache-2.0
- compatibility
- Runs on both widget-capable surfaces (e.g. Claude Cowork, which supports the asset_add_file picker and asset_preview_file preview widgets) and non-UI agents (e.g. Codex, where those widgets are unavailable). The default flow uses the widgets; each widget step has a text-only fallback. Local files reach Creative Cloud via the asset_add_file picker or (no-widget) asset_initialize_file_upload -> PUT -> asset_finalize_file_upload; raw local paths are never passed to image tools.
- allowed-tools
- adobe_mandatory_init image_list_presets asset_add_file read_widget_context asset_initialize_file_upload asset_finalize_file_upload image_auto_straighten image_apply_auto_tone image_apply_adjustments image_apply_preset image_select_subject image_apply_gaussian_blur image_crop_and_resize asset_preview_file create_firefly_board
- metadata
- {"version":"3.1.0","visibility":"public","surface":["claude","codex"]}
# Adobe Batch Edit Photos
A batch editing pipeline focused on **visual cohesion** — making a set of
photos look like they were edited together. The user picks a look (or
describes one), and the agent applies it consistently across every image using
Adobe creativity tools.
The core insight: users who want "cohesion" care less about per-image
perfection and more about the whole set reading as intentional. Prioritize
consistency of tone and color over squeezing the best out of any single image.
> **Surface note:** The default flow uses Adobe's MCP App widgets (`asset_add_file` picker in Step 1, `asset_preview_file` preview in Steps 2c and 8). Follow it as written. Only if a widget tool is **not available on this surface** (e.g. Codex) use the *No-widget fallback* attached to that step. Present `AskUserQuestion` prompts as plain-text labeled options wherever no question widget exists.
---
## Tool Reference
| Step | Tool | Notes |
| ------------------- | ------------------------------------------------- | ---------------------------------------------- |
| Ingest | `asset_add_file` (+ `read_widget_context`) | Interactive file picker; resolve picker results via `read_widget_context` |
| Ingest *(no-widget fallback)* | `asset_initialize_file_upload` + `asset_finalize_file_upload` | Only when `asset_add_file` is unavailable — stage local files to CC programmatically |
| Discover presets | `image_list_presets` | Once at startup; builds look→preset map |
| Straighten | `image_auto_straighten` | Per image |
| Auto-tone | `image_apply_auto_tone` | Per image, `type: "cameraRawFilter"` |
| Look adjustments | `image_apply_adjustments` | Batch — color temp + vibrance/sat + brightness/contrast in one call |
| Fine-tune tweaks | `image_apply_adjustments` | Batch — all selected tweaks in one call |
| Look preset | `image_apply_preset` | Per image, core style vehicle |
| Element detection | `image_select_subject` with full bodyParts array | Per image, Step 5e opt-in; also crop focus |
| Background blur | `image_apply_gaussian_blur` | Per image, only if explicitly requested |
| Crop | `image_crop_and_resize` | Per image, optional |
| Sample preview | `asset_preview_file` | Before/after on image[0] only *(no-widget fallback: present the 2 URLs directly)* |
| Final preview | `asset_preview_file` | Batch assets array *(no-widget fallback: present the URLs directly)* |
| Firefly Board | `create_firefly_board` | All edited outputs |
---
## Step 0 - prereq: Initialize Adobe Tools
Call `adobe_mandatory_init` first. This returns file handling rules and tool routing guidance required for the rest of the workflow.
```json
{ "skill_name": "adobe-batch-edit-photos", "skill_version": "3.1.0" }
```
---
## Step 0b: Discover Available Presets
Call `image_list_presets` immediately after init — before ingestion or user questions. This gives you the full pool of presets available on this user's plan, so Step 5b can select the best match for each look rather than relying on hardcoded names.
```
Tool: image_list_presets
Params: {}
```
From the returned list, build a **Look→Preset Map** by classifying each preset into the look category it best serves. Use the naming signals below as heuristics:
| Look | Naming signals to match |
|------|------------------------|
| **Auto (balanced)** | `Auto`, `Balanced`, `Natural`, `Neutral`, `Default`, `Adobe Color`, `Standard` |
| **Warm & Golden** | `Warm`, `Golden`, `Glow`, `Sunset`, `Cozy`, `Amber`, `Warm Pop` |
| **Bright & Airy** | `Airy`, `Bright`, `Light`, `Clean`, `Pop`, `Lift`, `Fresh` |
| **Moody & Cinematic** | `Moody`, `Cinematic`, `Dark`, `Drama`, `Dramatic`, `Shadow`, `Deep` |
| **Cool & Fresh** | `Cool`, `Blue`, `Clear`, `Crisp`, `Sky`, `Azure` |
| **Vibrant & Punchy** | `Vibrant`, `Punchy`, `Bold`, `Vivid`, `Pop`, `Saturate` |
| **Muted & Film** | `Film`, `Muted`, `Fade`, `Faded`, `Analog`, `Grain`, `Vintage`, `Matte` |
**Rules:**
- Assign each preset to at most one look. When a name matches multiple looks (e.g. "Pop" could be Bright or Vibrant), assign it to the look with the closest overall character — a soft warm pop belongs in Warm & Golden, a punchy high-contrast pop belongs in Vibrant.
- Prefer `Adaptive:` prefixed presets for look-driving since they respond to image content.
- Pick at most **2 presets per look** — one primary (strong match) and one optional secondary (complementary). Apply primary first, secondary only if it adds something different (e.g. adds a color grade the primary doesn't cover).
- If no preset matches a look, that look runs with color-temperature and manual adjustments only (no preset applied).
- If `image_list_presets` returns empty or 403: skip Step 5b for all images; note "Presets unavailable on this plan" in the summary. The rest of the look pipeline (color temp, manual adjustments) still runs.
Store the completed Look→Preset Map before Step 2. You'll reference it in Step 5b.
### Selective Adaptive Preset Buckets (for Step 5e)
From the same preset list, also build a **Selective Adaptive Map** — a separate set of buckets used only when the user opts into selective enhancements (Step 5e). These presets target specific detected scene elements rather than the whole image:
| Bucket | Naming signals | Applied when |
|--------|---------------|--------------|
| **Subject / Person** | `Subject`, `Person`, `Pop`, `Warm Pop`, `Portrait`, `Skin`, `Body` | Face, Torso, or Skin detected |
| **Sky** | `Sky`, `Blue Drama`, `Dark Drama`, `Cloud`, `Horizon`, `Outdoor` | Sky detected |
| **Background** | `Background`, `BG`, `Blur Background`, `Bokeh`, `Depth`, `Defocus` | Background detected |
| **Body Parts / Clothes** | `Clothing`, `Outfit`, `Clothes`, `Hair`, `Torso`, `Body Part` | Clothing or Hair detected |
- Pick at most **1 preset per bucket**.
- If no preset matches a bucket, leave it empty — do not force a poor fit.
- These buckets are separate from the Look→Preset Map; a preset can appear in both if it genuinely fits.
---
## Step 1: Image Ingestion
Call `asset_add_file` with no parameters to open the file picker:
```
Tool: asset_add_file
Params: {}
```
`asset_add_file` always returns `imageURIs: []` — this is expected and NOT an
error. Wait for the user to select files; the real URIs arrive in the next
message. Then call `read_widget_context` with `asset_add_file` to get the
correct presigned S3 URLs. Use those for all subsequent tool calls.
`dcx-stage.adobe.io` URIs are network-blocked; resolve them via `read_widget_context` first.
Collect the resulting presigned URLs as `sourceURIs[]` and continue to Step 2.
> **No-widget fallback** *(only if `asset_add_file` is unavailable on this surface, e.g. Codex)* — don't open a picker; get the source URIs from where the files already are. `image_*` tools only accept Creative Cloud storage URIs, never raw local paths, so any local file must be staged to CC first.
>
> **Egress check first:** check egress status from `adobe_mandatory_init` (Step 0). If egress is disabled — do NOT call `asset_initialize_file_upload` / `asset_finalize_file_upload`.
>
> | Source | Action |
> |--------|--------|
> | File(s) at a local path AND egress **enabled** | Stage each file programmatically: get its size and MIME type, call `asset_initialize_file_upload({ path: "<filename>", media_type: "<mime>" })`, PUT the file bytes to the returned upload URL, then `asset_finalize_file_upload({ filename: "<filename>", transfer_document: <from the initialize response> })`. Use each returned presigned CC URL as a source URI. |
> | File(s) already in Creative Cloud | Reference them directly by their CC URI. |
> | File(s) at a local path AND egress **disabled**, no picker on this surface | Programmatic staging is blocked and there is no file picker here — tell the user staging isn't possible on this surface and ask them to run the workflow where the `asset_add_file` picker is available. |
---
## Step 2: Understand the Desired Look
Once URIs are obtained, scan the conversation to infer as many preferences
as possible before asking anything:
- **Look**: inferrable from words like "warm", "golden", "cinematic", "moody",
"bright and airy", "muted", "film", "cool", "vibrant", "punchy"
- **Fine-tune tweaks**: inferrable from "recover highlights", "lift shadows",
"more contrast", "blown out", "too dark", "more vibrant", "desaturate"
- **Crop**: inferrable from "no crop", "square", "1:1", "portrait crop", "keep framing", etc.
- **Selective AI enhancements**: inferrable from "adaptive presets", "selective enhancements", "apply to detected elements", "sky presets", "subject pop", or any phrase requesting element-aware processing. If inferred as Yes, treat it as Q5 = Yes — Step 5e will run. If inferred as No or not mentioned, treat it as Q5 = No — skip Step 5e entirely.
**Three cases:**
**A — Everything clear from context:** Skip `AskUserQuestion` entirely. Post the confirmation message, then proceed directly to Step 2c (sample preview). Do NOT start the full batch — the preview and confirm gate always runs regardless of how clearly preferences were stated.
**B — Some things clear, some not:** Confirm what you've inferred upfront,
then call `AskUserQuestion` with only the questions that remain unanswered.
For example, if the look and a tweak are clear but crop isn't, post:
```
📷 Got [N] photo(s)! Based on what you said, I'll go with:
- Look: Moody & Cinematic
- Tweaks: Recover blown highlights
Just one thing — do you want a crop?
```
Then call `AskUserQuestion` with Question 3 only.
**C — Nothing specified:** Post the full intro and show all 5 questions:
```
📷 Got [N] photo(s)! I'll apply consistent edits across all of them so
the set looks cohesive.
What kind of look are you going for? 👇
```
The full `AskUserQuestion` questions (use only the ones that are still open):
```
Question 1 (single_select):
question: "🎨 Pick a base look"
options:
- "Auto (balanced, neutral)"
- "Warm & Golden — cozy, travel, golden hour"
- "Bright & Airy — clean, light, lifestyle"
- "Moody & Cinematic — dramatic, contrasty, desaturated"
- "Cool & Fresh — clear skies, travel, blue tones"
- "Vibrant & Punchy — vivid, bold, social-ready"
- "Muted & Film — faded, analog, editorial"
Question 2 (multi_select):
question: "🎛️ Fine-tune (optional)"
options:
- "Recover blown highlights"
- "Lift dark shadows"
- "Boost contrast"
- "Boost color intensity"
- "Desaturate / muted tones"
- "Adjust exposure (brighter/darker)"
- "Tune bright areas"
- "Blur background (heavy)"
- "None"
Question 3 (single_select):
question: "✂️ Crop ratio? (optional)"
options:
- "No crop — keep original framing"
- "1:1 square"
- "4:5 portrait"
- "16:9 wide"
- "4:3 standard"
Question 4 (single_select): [only ask if Q3 is not "No crop"]
question: "🎯 How should the crop be framed?"
options:
- "Center — crop from center of image"
- "Smart crop — detect subject/face and frame around it"
Question 5 (single_select):
question: "✨ Selective AI enhancements? Detects sky, subjects, background & body parts — applies adaptive presets only to elements found in each photo"
options:
- "Yes — apply adaptive presets to detected elements"
- "No — skip selective enhancements"
```
Wait for the user's reply before proceeding.
**If the user opts into selective enhancements (Q5 = Yes):** Step 5e runs per image after the look is applied. If the user declines or it wasn't asked, skip Step 5e entirely.
**Note on Question 4:** If the user's message already implies a framing preference
(e.g. "center crop", "crop to my face", "frame around the subject"), skip Q4 and
infer directly. If the user specifies a ratio but not a framing method, default to
Smart crop — it almost always produces a better result than a pure center cut.
### Look → Parameter Mapping
**Base look → `image_apply_adjustments` (color temp + vibrance/sat + brightness/contrast, Step 5a) + `image_apply_preset` (from Look→Preset Map, Step 5b):**
Combine ALL columns for the selected look into a **single `image_apply_adjustments` call** — do not make separate calls for color temp, vibrance, and contrast. Omit any parameter whose column says "none".
The preset column below is now **dynamic** — use the preset(s) from your Look→Preset Map for that look (built in Step 0b), not hardcoded names. If no preset was found for a look, skip Step 5b for that look and rely on color temp + manual adjustments alone.
⚠ **Deprecated tools are never used.** All adjustments go through `image_apply_adjustments`. The individual per-dimension adjust-* tools are deprecated — see Hard Constraints below.
| Look | Color Temp (tempA, tempB, tempLuminance) | Preset (from Look→Preset Map) | Saturation/Vibrance | Brightness/Contrast |
| ----------------- | ---------------------------------------- | ----------------------------- | ---------------------------- | ------------------- |
| Auto (balanced) | **none** — omit tempA/tempB/tempLuminance | Auto (balanced) bucket preset | none | none |
عرض على GitHub