Field report · verified 5 August 2026

Driving Adobe from Claude

Every route that exists today between an AI model and Illustrator, InDesign or Photoshop — what is real, what is marketing, what is outright false, and exactly how to build on each one. Every section opens with a plain-English summary, then gives the implementer everything.

Scope Illustrator · InDesign · Photoshop · Claude Design · Firefly Services Verified 2026-08-05 Target platform Windows 11 (macOS differences called out)
Section 01

The whole landscape in one page

In plain terms

There are four fundamentally different ways to let an AI operate Adobe software, and they are not variations on a theme — they have different costs, different failure modes, and wildly different capabilities. Route A is a direct line: Adobe built a small server into Illustrator that Claude Code can talk to, so Claude clicks Illustrator's own buttons on your behalf. Route B is Adobe's own AI assistant living inside the app — you type at a panel in the corner, and it does the work, but only inside that one document. Route C is third-party bridges built by outside developers to fill the gaps Adobe left, especially in InDesign and Photoshop. Route D is the oldest and dullest: have Claude write a script file, and you double-click it. Route D sounds primitive and is quietly the most reliable of the four.

The single most useful thing to know is that the coverage is lopsided, and lopsided in the direction nobody expects. Illustrator — historically the least scriptable of the big three — is the only app with a real built-in AI connection. Photoshop, which has the most mature plugin technology in the entire suite, has no built-in AI connection at all and depends on a free community project. InDesign, the app most people want to automate because it does the boring repetitive layout work, has the least direct AI access of all and its only serious API sits behind an enterprise contract. If you plan around the marketing, you will plan backwards.

For the implementer
Claude Code / Desktop your machine A · Built-in MCP server Illustrator (Beta) only · 40 tools http://localhost:18412/v1/mcp B · Adobe AI Assistant In-app panel · not driven by Claude Ai · Id (Beta) · Ps (Beta) C · Third-party MCP server Duet · Sidekick · photoshop-mcp stdio · npx / installer D · Generated script .jsx / .psjs / .idjs written by Claude you double-click it E · Firefly Services cloud REST no desktop app involved · enterprise Illustrator A · B · D · E InDesign B · C · D · E Photoshop B · C · D · E Adobe cloud no desktop needed
The five routes. Solid teal is the only path where Claude directly and officially drives a desktop Adobe app. Dashed lines are paths Claude does not drive — the AI Assistant is Adobe's own model behind Adobe's own panel, and the cloud API needs no desktop app at all.

The capability matrix — everything, in one table

CapabilityIllustratorInDesignPhotoshop
Built-in MCP server (Claude drives the app) YES Beta, 40 tools NO verified 404 NO verified 404
Adobe AI Assistant (in-app panel) YES docs 19 Jun 2026 YES Beta 21.4+, docs 3 Aug 2026 BETA public beta 10 Mar 2026
UXP plugins (modern extensibility) INTERNAL Adobe-only in 2026 YES mature YES most mature in suite
UXP scripts (single-file, no plugin) NO YES .idjs YES .psjs
ExtendScript .jsx YES only script option YES YES
CEP panels (legacy HTML/JS) CONTESTED see §6 LEGACY LEGACY
C++ SDK YES YES YES
Cloud REST API v1 illustrator-api.adobe.io v3 indesign.adobe.io v2 GA image.adobe.io
Headless server product NO YES InDesign Server ~$2,100/yr NO
Best free third-party MCP on Windows n/a built-in wins NONE free options are macOS-only STRONG 89 tools, MIT
Open interchange format .ai is PDF-compatible; SVG in/out IDML open XML zip .psd — spec reverse-engineered

Route selection: the decision you actually have to make

RouteWhat it isWho paysBest atFails at
A — built-in MCP Illustrator Beta exposes 40 tools over HTTP; Claude Code connects with a bearer token. Your Claude tokens. Adobe bills nothing. Interactive, exploratory vector work. Real layers. Export by object ID. Illustrator only. Beta only. One document at a time.
B — AI Assistant Adobe's model, Adobe's panel, inside the app. Adobe credits (undisclosed daily allowance). One-off edits by a designer who is already in the app. Not programmable. Not scriptable. Cannot be called by Claude.
C — third-party MCP Community/commercial bridge, usually stdio, usually driving ExtendScript underneath. Your Claude tokens + any licence (£9–$9.95/mo). Photoshop on any OS; InDesign if you pay. Free InDesign servers are macOS-only. Quality varies enormously.
D — generated script Claude writes .jsx/.psjs/.idjs; you run it. Your Claude tokens only. Repeatable batch work. Version control. Auditability. Every app. No feedback loop unless you build one. Claude cannot see the result.
E — cloud REST Firefly Services. No desktop app runs anywhere. Adobe enterprise contract, reported ~$1,000/mo floor. Server-side rendering at volume. Data merge. PDF→INDD. Cost. Enterprise sales cycle. Async job plumbing.
The rule of thumb that survives contact with reality

Use Route A when a human is watching and iterating on vector art. Use Route D for anything that has to run twice. Use Route C only for Photoshop, where the free option is genuinely excellent. Treat Route B as a feature for designers, not an automation surface. Only reach for Route E when you have volume that justifies an enterprise contract.

Route B is the trap

The most common expensive mistake in this space is routing production work through a conversational AI surface that was designed for exploration. A measured example from this research: a 9:16 reframe that a designer does by hand in about 30 seconds took over three minutes through a chat-mediated connector, and produced a result that still needed checking. The connector is a doorway, not a worker. Use it to reach the app, not to do the job.

Section 02

Illustrator's built-in MCP server

In plain terms

This is the headline, and it is genuinely new. The beta version of Adobe Illustrator now runs a tiny web server on your own computer while the app is open. Claude Code connects to that server and gets a menu of forty things it is allowed to do: make a document, add an artboard, create a layer, draw a shape, move it, recolour it, read back what is currently on the canvas, take a preview picture, export a PNG or an SVG. Claude is not guessing at Illustrator from the outside; it is pressing Illustrator's own controls from the inside, and it can look at the result and correct itself. Everything runs on your machine — nothing about your artwork is sent to Adobe for this to work.

Setup takes about a minute and is mostly copy-and-paste. Illustrator gives you a ready-made command in a panel; you paste it into a terminal, restart Claude Code, and say something like “create a document.” The important caveats: it only exists in the Beta build of Illustrator, Adobe's supported list of AI tools names Claude Code but does not name Claude Desktop, and the AI usage is billed by whoever provides the AI — Adobe charges nothing for the connection itself. It also handles one open document at a time, and you should not touch objects while it is working on them.

For the implementer

Architecture

Claude Code MCP client your terminal HTTP + Bearer JSON result Illustrator (Beta) localhost:18412/v1/mcp MCP server · 40 tools live document model Your canvas real layers, real objects full undo history Nothing leaves the machine. Adobe bills nothing; your AI provider bills the tokens.
Transport. Streamable HTTP on a fixed loopback port, authenticated with a per-installation bearer token.

Prerequisites

  • Illustrator (Beta) — install from the Creative Cloud desktop app under Beta apps. The shipping release does not have this.
  • An AI tool on the same computer. Adobe's documentation names Cursor, Claude Code, and Codex. NOTE Claude Desktop is not on that list — it may work, it is not supported.
  • The AI tool must be able to reach localhost. Anything running in a container or on a remote host cannot see port 18412.

Setup, exactly

  1. Launch Illustrator (Beta).
  2. In the Application Bar, open MCP & Tools.
  3. Click Copy Claude Code command to clipboard. Illustrator writes a complete claude mcp add command containing your token.
  4. Paste it into a terminal and run it.
  5. Restart Claude Code (claude).
  6. Smoke test with a single instruction: Create a document. A new document should appear in Illustrator.

Adobe's sample command has this shape — do not copy this key, it is per-installation and yours will differ:

# ADOBE'S SAMPLE — the key is per-installation. Copy YOURS from the MCP & Tools panel.
claude mcp add --transport http \
  --header "Authorization: Bearer ilst_da9d6ccd0a1e39ecea17c19e3a5042325856532f8f8df1185b76f0ba5b6fa054" \
  --scope user illustrator http://localhost:18412/v1/mcp

On Windows PowerShell, the backslash line-continuations do not work. Use one line, or backticks:

claude mcp add --transport http --header "Authorization: Bearer <YOUR_KEY>" --scope user illustrator http://localhost:18412/v1/mcp

Verify registration independently of Illustrator:

claude mcp list
# expect: illustrator  http  http://localhost:18412/v1/mcp   ✓ connected
Security model — read this before you paste the key anywhere

The bearer token is per-installation and remains valid until you regenerate it. Anything that can reach localhost:18412 with that header can drive your Illustrator. Do not commit it, do not paste it into a shared config, and regenerate it from the panel if it leaks. --scope user writes it to your user-level Claude config — prefer --scope local if you share that file. Adobe's own wording: “Usage is billed through your AI tool, not through Adobe.”

The 40 tools, by category

CategoryWhat it coversSample prompt (Adobe's own)
Documents & artboardsCreate, open, save documents; add, resize, reorder artboards.“Create a document with three artboards at 1080×1080.”
Structure & inspectionRead the object tree, query properties, take a preview image of the canvas.“Take a preview image and tell me what's misaligned.”
Layers & groupsCreate and rename real layers, create groups, reorder, lock, hide.“Put the background art on its own layer named Background.”
Selection & transformsSelect by name/type/ID; move, scale, rotate, align, distribute.“Align all the icons to the horizontal centre and distribute evenly.”
Art & textDraw primitives and paths, set fill/stroke, place and edit simple text.“Change the headline to Autumn Collection and make it 48pt.”
ExportPNG, JPEG, SVG, PDF — of the whole canvas, an artboard, the selection, or an object by ID.“Export each artboard as a PNG at 2×.”
Why this route beats hand-written SVG for layered output

The Layers & groups category creates genuine Illustrator layers — the thing SVG physically cannot express (see §11). And export by object ID means you can ask for one component out of a composition without manual isolation. Together those two make Route A the correct answer to “generate a layered Illustrator file from a prompt,” which was the original question that started this research.

Known limits

  • Single document. Multi-document orchestration is explicitly not supported.
  • No cross-app reach. It cannot touch Photoshop or InDesign.
  • No automatic brand-guideline enforcement. Adobe calls this out explicitly as not supported.
  • Latency grows with document size. Large documents mean slow round-trips.
  • Do not edit objects it is currently modifying. Background work plus a human hand on the same object is the documented failure case.
  • Beta build. Port, token format, and tool list can change between beta drops.

Prompting patterns that hold up

  • Ask for a plan first. Adobe's own recommended phrasing: “Show me a plan before making changes.” This turns a destructive multi-tool run into a reviewable one.
  • Name things explicitly. Tools select by name and ID — “the blue rectangle” is a guess, Layer "Background" is not.
  • Ask for a preview image after structural changes. The model can then self-correct instead of asserting success.
  • Work in small commits. Illustrator's undo stack is your rollback; keep each instruction to one reversible unit.

Driving it from a script rather than a chat

Claude Code can be run non-interactively, which turns Route A into a real pipeline stage. The MCP server is registered at user scope, so it is available to headless invocations too:

# one-shot, non-interactive, allowed to use the illustrator tools
claude -p "Open ./brand.ai, put every text object on a layer named Type, export the Type layer as SVG to ./out/type.svg, then report the object count." \
  --allowedTools "mcp__illustrator" \
  --output-format json

Wrap that in your job runner and you have a repeatable Illustrator stage whose output you can assert on — check the SVG exists, check its byte size is non-trivial, check the reported object count matches expectation. Never trust the transcript alone; assert on the artifact.

Section 03

The three AI Assistants (and why they are not an API)

In plain terms

Separately from the MCP work, Adobe has been putting its own chat assistant inside each app. Illustrator has one, InDesign has one in the beta build, and Photoshop's is in public beta. You open a panel, type what you want in ordinary language, and the assistant does it to the open document. It is genuinely useful for a designer sitting at the machine — in InDesign, for example, every change it makes shows up in the normal undo history, so nothing it does is a black box you cannot back out of.

The critical thing to understand is what these assistants are not. They are not something your code can call. There is no endpoint, no token, no command line. Claude cannot talk to them. They run on Adobe's models and consume Adobe credits — and Adobe has not published the daily limit for InDesign's, only that one exists. If you are building a pipeline, the AI Assistant is a feature you tell your designers about, not a component you can wire into anything.

For the implementer
IllustratorInDesignPhotoshop
StatusShipping in Beta; capability docs updated 19 Jun 2026Beta only, from 21.4; docs updated 3 Aug 2026 (Beta now 21.9)Public beta since 10 Mar 2026 — web/mobile first, then desktop beta
Undo integrationNative historyAdobe: “inspectable and reversible through native InDesign history”Native history
Language limitsNot separately documentedEnglish (NA), English (International), Latin script onlyNot separately documented
CostAdobe creditsComplimentary daily credit limit — number not publishedAdobe credits
Programmatic accessNONE — no endpoint, no CLI, no MCP tool for any of the three
Do not confuse the AI Assistant with the MCP server

Illustrator has both, and they are unrelated systems. The MCP server is a transport that lets your model drive the app. The AI Assistant is Adobe's model behind a panel. Adobe's marketing pages describe them in adjacent paragraphs and they are frequently conflated in secondary coverage — including in the source material that prompted this research.

Illustrator AI Assistant — the explicit NOT-supported list

Adobe documents these as out of scope, which is unusually candid and worth quoting in any internal proposal:

  • Working across multiple documents.
  • Reaching into other Adobe applications.
  • Automatic brand-guideline application — it will not enforce your brand book.

Documented limitations: response latency, degraded behaviour on large documents, and the background-work conflict — do not manipulate objects the assistant is mid-edit on.

Photoshop AI Assistant — a caveat on this section's confidence

At verification time there was no ai-assistant-capabilities.html page for Photoshop (404). The public-beta announcement of 10 March 2026 is solid; the detailed capability surface is not documented to the same standard as Illustrator's or InDesign's. Treat specific Photoshop AI Assistant claims you read elsewhere as unverified until Adobe publishes the page.

Section 04

InDesign: no MCP, and three imperfect workarounds

In plain terms

InDesign is the app most people want to automate — it does catalogues, price lists, reports, the genuinely repetitive layout work — and it is the app with the least direct AI access. There is no built-in connection like Illustrator's; that was checked directly and the page Adobe would have published simply does not exist. What InDesign got instead was the in-app AI Assistant, which as explained above your code cannot call.

So to have Claude drive InDesign you need a third-party bridge, and here the news is worse for Windows users than for Mac users. There are two paid products that work well — Duet at about £9 a month and Sidekick at $9.95 a month with a 30-day trial — and a handful of free open-source projects, almost all of which run only on macOS. On Windows, the free options are effectively not there. The honest recommendation for a Windows shop is to pay for Duet, or skip the bridge entirely and have Claude write scripts you run yourself.

For the implementer
Verified negative: InDesign has no built-in MCP server

Two independent checks. First, the URL that would mirror Illustrator's — helpx.adobe.com/indesign/desktop/connect-with-other-apps-and-tools/connect-indesign-to-ai-tools.html — returns 404. Second, the InDesign Beta feature overview contains zero occurrences of the string “MCP”. Claims to the contrary in blog posts are conflating the AI Assistant with Illustrator's MCP server.

The two commercial bridges

DuetSidekick
Price£9 / month$9.95 / month, 30-day trial
PlatformmacOS 12+ and Windows 10/11 64-bitmacOS and Windows
InDesign version2024 (v18.5) or newer2024 or newer
RAM8 GB minimumnot published
AI clientsClaude Desktop and Claude CodeClaude Desktop
Tool surface“12 tool categories”Aggregator; the widely-quoted “~130 tools” figure comes from here
TechUXPUXP

Duet is the Windows answer — it is the one that explicitly supports Claude Code, which matters if you want a scriptable, non-interactive pipeline rather than a chat window. The “~130 tools” number that circulates for InDesign MCP is Sidekick's aggregate figure, not a property of InDesign or of MCP generally; Duet publishes categories, not a tool count.

The open-source landscape — and why it fails on Windows

ProjectToolsPlatformVerdict
lucdesign InDesign MCP35+macOS onlyMost complete free option — unusable on Windows
bejaminjones InDesign MCP26macOS onlySame story
chris-enea InDesign MCPmacOS onlySame story
mikechambers/adb-mcp60+ (Photoshop-weighted)cross-platformInDesign support is “basic document creation” only

The macOS-only pattern is not accidental: those projects drive InDesign through AppleScript, which has no Windows equivalent. The Windows path is COM automation, which almost nobody has built an MCP server around for InDesign.

The Windows-native escape hatch nobody uses

InDesign registers a COM automation server on Windows. That means Python can drive it directly, right now, with no MCP and no licence fee — see lohriialo/indesign-scripting-python. Claude writes the Python; the Python drives InDesign over COM. If you want a Windows InDesign MCP server, this is the substrate you would build it on, and it is roughly a weekend of work to wrap a dozen useful operations.

⚠️ Note carefully what this is not: you cannot run Python inside InDesign. The Python process is outside, talking in.

# Windows-only. InDesign must already be running.
import win32com.client as win32

app = win32.Dispatch("InDesign.Application")          # latest installed version
doc = app.Documents.Add()
page = doc.Pages.Item(1)

frame = page.TextFrames.Add()
frame.GeometricBounds = [12, 12, 60, 190]        # [top, left, bottom, right] — mm by default
frame.Contents = "Hello from Python"

doc.Export(win32.constants.idExportFormat.idPDFType, r"D:\out\hello.pdf")

DoScript — the bridge between languages

InDesign's doScript() lets one language hand a payload to another engine. This is how you get from COM/Python into ExtendScript where the API surface is best documented:

jsx = '''
var d = app.documents.length ? app.activeDocument : app.documents.add();
var f = d.pages[0].textFrames.add();
f.geometricBounds = [12, 12, 60, 190];
f.contents = "Written by ExtendScript, called from Python";
'''
app.DoScript(jsx, win32.constants.idScriptLanguage.idJavascript)
Section 05

Photoshop: no built-in MCP, one excellent free server

In plain terms

Photoshop is the inversion nobody predicts. It has the most mature and best-documented plugin technology of the three apps — and no built-in AI connection at all. The page Adobe would have published for it does not exist. What Photoshop has instead is the best free community bridge found anywhere in this research: an open-source project offering eighty-nine separate operations, running on both Windows and macOS, installable with a single command, MIT licensed and actively maintained.

That project works by generating Photoshop's own script code and feeding it to the app through whatever automation channel the operating system provides — COM on Windows, AppleScript on Mac. Practically, that means it works with Photoshop versions going back more than a decade, and its compound operations behave sensibly with undo: a multi-step “recipe” collapses into one undo step rather than fifteen. For a Windows shop wanting AI-driven Photoshop today, this is the answer, and it costs nothing.

For the implementer
Verified negative: Photoshop has no built-in MCP server

helpx.adobe.com/photoshop/.../connect-photoshop-to-ai-tools.html returns 404. Only Illustrator has the built-in server.

The third-party servers, ranked for Windows

ProjectToolsMechanismWindowsNotes
alisaitteke/photoshop-mcp PICK 89 — 74 atomic + 15 recipe ExtendScript, delivered via COM (Win) / AppleScript (Mac) YES MIT · ~276★ · ~135 commits · Photoshop 2012 → 2025+ · recipes run inside a single undo step
mikechambers/adb-mcp 60+ UXP plugin + local proxy YES Modern stack; more moving parts to install; also touches Illustrator and (barely) InDesign
loonghao/photoshop-python-api-mcp-server Python over COM Windows only Good if you already live in Python

Install and register — the whole thing

# 1. Photoshop must be running and must have a document open for most tools.
# 2. Register the server with Claude Code (stdio transport):
claude mcp add --scope user photoshop -- npx -y @alisaitteke/photoshop-mcp

# 3. Verify
claude mcp list

# 4. Smoke test, from inside claude:
#    "List the layers in the open Photoshop document."

Equivalent raw MCP config, if you are wiring it into something other than Claude Code:

{
  "mcpServers": {
    "photoshop": {
      "command": "npx",
      "args": ["-y", "@alisaitteke/photoshop-mcp"]
    }
  }
}
Why the recipe tools matter more than the tool count

74 atomic tools means the model can compose anything — and will happily leave you with a 74-deep undo stack after one instruction. The 15 recipe tools wrap common multi-step jobs so they execute as a single undoable action. When you write prompts for this server, prefer the recipe that matches your intent over asking the model to assemble the steps. Fewer round-trips, cleaner history, far fewer half-applied states when something errors mid-sequence.

The five-rung Photoshop automation ladder

Independently of MCP, Photoshop has a well-defined escalation path. Climb only as far as you must:

RungToolUse whenCeiling
1ActionsA fixed sequence a designer recorded onceNo logic, no branching, no variables
2Batch / Image ProcessorApply an Action across a folderStill no logic; file-in/file-out only
3Scripts (.jsx / .psjs)Anything conditional. Start here for real work.Runs and exits; no persistent state; no UI beyond dialogs
4UXP pluginsA panel a human uses repeatedly; persistent settingsReal project; needs manifest, bundling, signing to distribute
5C++ SDKNew file formats, filters, core behaviourEnormous effort; per-version rebuilds

UXP script vs UXP plugin — Adobe's own distinction

UXP script (.psjs)UXP plugin
LifetimeEnds when it finishesPersists while loaded
UIDialogs onlyFull panels
Persistent storageNOYES
Module accessLimited setFull
IdentityNO — Adobe: “not supported in our distribution channels yet”Yes; distributable

When the typed UXP API does not expose something, batchPlay is the escape hatch — it speaks Photoshop's internal action descriptor language directly, which is the same thing Actions record. Anything the UI can do, batchPlay can do:

const { batchPlay } = require("photoshop").action;

await batchPlay(
  [{ _obj: "make", _target: [{ _ref: "layer" }], using: { _obj: "layer", name: "Type" } }],
  { synchronousExecution: true }
);
Section 06

The four extensibility platforms, decoded

In plain terms

Underneath every AI bridge is one of four much older technologies, and knowing which is which saves a lot of wasted effort. ExtendScript is Adobe's ancient JavaScript — the dialect is from 1999, it has no modern language features, and it still works in every app and is still the best-documented. UXP is the modern replacement, with real modern JavaScript, and it comes in two flavours: a single script file you run, or a full plugin with a panel. CEP is the previous generation of panels, built like little web pages; it is on the way out. The C++ SDK is for building things that behave like parts of Photoshop itself.

The trap is assuming every app supports every platform. They do not, and the gaps are severe: Illustrator has no public UXP at all in 2026 — it is Adobe-internal — so ExtendScript is the only scripting language Illustrator will take. Photoshop and InDesign both take UXP happily. Guess wrong and you will write a plugin the app will not load.

For the implementer
ExtendScript UXP script UXP plugin CEP C++ Illustrator YES — only option no internal only contested yes InDesign yes (.jsx) yes (.idjs) yes legacy yes Photoshop yes (.jsx) yes (.psjs) most mature legacy yes
The support matrix. The two cells that surprise people: Illustrator has no public UXP, and Photoshop's UXP is the most mature in the suite.

1 · ExtendScript

  • Language: ES3 (1999). No let, no const, no arrow functions, no JSON object, no template literals, no Array.prototype.forEach in older hosts. Write like it is 1999, because it is.
  • Extension: .jsx (also .jsxbin compiled).
  • Status: Still fully supported in all three apps. The ExtendScript Toolkit editor was deprecated in 2020 — the language was not. Use VS Code with the Adobe ExtendScript Debugger extension.
  • Where to run it: File → Scripts → Browse…, or drop it in the app's Scripts folder for it to appear in the menu.
  • Reference: the community-maintained docsforadobe.dev sites are better than Adobe's own PDFs.

2 · UXP scripts

  • Modern JavaScript (ES2018+), async/await, real Promise.
  • The file extension picks the engine. .idjs → InDesign UXP; .psjs → Photoshop UXP; .jsx → ExtendScript. Same menu, different runtime, entirely different API. This is the single most confusing thing about Adobe scripting today.
  • No persistent storage, no identity, limited module set — see the table in §5.

3 · UXP plugins

  • Real panels. manifest.json + HTML/JS. Developed via the UXP Developer Tool.
  • Photoshop's implementation is the reference one. InDesign's is solid. Illustrator's is Adobe-internal and not available to you.

4 · CEP — legacy

  • Chromium-embedded panels, packaged as .zxp. CEP 12 is the last major version.
  • Still functional in Photoshop and InDesign; being displaced by UXP.
  • CONTESTED For Illustrator, an Adobe support response asserts CEP has been unsupported since 2022, while third-party CEP panels for Illustrator continue to be sold and to work. Both things appear to be true. If you need an Illustrator panel today, this ambiguity is your problem: the only unambiguous options are the C++ SDK or shipping .jsx files with no panel at all.

5 · C++ SDK

  • Full native plugins — new tools, new file formats, new filters.
  • Available for all three apps. Requires per-version rebuilds and matching compilers. Reach for it only when nothing above can express what you need.
Decision rule

Automating Illustrator → write .jsx, or use the built-in MCP. Automating Photoshop or InDesign → write UXP scripts (.psjs / .idjs) unless you need to talk to a third-party server that speaks ExtendScript, in which case match its dialect. Never start a new CEP project.

Section 07

Adobe's cloud REST APIs (Firefly Services)

In plain terms

Separately from anything on your desktop, Adobe runs the actual applications on its own servers and lets you call them over the internet. You send a template and some data, Adobe renders it, and you get a finished PDF or image back. Nobody has to have Photoshop installed. This is how you build something that generates ten thousand personalised brochures overnight, and it is the only route in this whole report that scales that way.

Two things to know before you get excited. First, it is enterprise-gated: there is no self-service sign-up with a credit card, and the reported floor is around a thousand dollars a month — reported, not confirmed by Adobe. Second, the plumbing is more involved than a normal API: you do not upload files, you hand Adobe pre-signed download and upload URLs pointing at your own cloud storage, and the calls are asynchronous — you get a job ID back and poll until it finishes. Budget real engineering time for the storage and polling layer, not just the Adobe call.

For the implementer
Your service Adobe IMS indesign.adobe.io Your S3 / Azure 1 · POST /ims/token/v3 (client_credentials) 2 · access_token, valid 24 h 3 · POST /v3/merge-data { assets[…presigned URLs…], params, outputs } 4 · 202 { jobId, statusUrl } 5 · GET /v3/status/{jobId} ← poll with backoff 6 · PUT result 7 · you fetch the finished PDF from your own bucket
The async shape. Adobe never stores your files — it reads from and writes to pre-signed URLs you supply (AWS S3, Azure SAS, or Dropbox).

Authentication — OAuth Server-to-Server

curl -sS -X POST "https://ims-na1.adobelogin.com/ims/token/v3" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=$ADOBE_CLIENT_ID" \
  -d "client_secret=$ADOBE_CLIENT_SECRET" \
  -d "scope=openid,AdobeID,read_organizations,firefly_api,ff_apis"

# -> { "access_token": "...", "token_type": "bearer", "expires_in": 86399 }

Tokens last 24 hours. Cache them; do not mint one per request. Every subsequent call carries:

Authorization: Bearer <access_token>
x-api-key:     <client_id>
Content-Type:  application/json
x-gw-ims-org-id: <org id>        # optional but required in some tenancies

InDesign API v3 — https://indesign.adobe.io/v3/

EndpointDoesLanded
POST /v3/create-renditionRender INDD → PDF / JPEG / PNG
POST /v3/merge-dataData merge from CSV/JSON into a template
POST /v3/merge-data-tagsTag-based merge variant
POST /v3/convert-pdf-to-indesign NEWPDF → editable INDD / IDML. The single most interesting endpoint Adobe ships.24 Feb 2026
POST /v3/document-infoInspect a document without rendering it13 Nov 2025
POST /v3/remap-linksRepoint broken asset links4 Aug 2025
POST / GET / DELETE /v3/scriptsUpload, list, delete custom script bundles
PUT /v3/scripts/{name}/app-versionPin a script to an InDesign version
GET /v3/app-versionsList available InDesign versions20 Nov 2025
POST /v3/{SCRIPT_ID}/{SCRIPT_NAME}Execute your uploaded script
GET /v3/status/{jobId}Poll job state

Request body shape

{
  "assets": [
    { "source": { "url": "<PRESIGNED GET>", "storageType": "Azure" },
      "destination": "template.indd" },
    { "source": { "url": "<PRESIGNED GET>", "storageType": "Azure" },
      "destination": "data.csv" }
  ],
  "params": {
    "targetDocument": "template.indd",
    "outputMediaType": "application/pdf",
    "dataSource": "data.csv",
    "outputFileBaseString": "brochure",
    "hyphenationSettings": { "hyphenation": false },
    "dictionarySettings": { "language": "English: USA" }
  },
  "outputs": [
    { "destination": { "url": "<PRESIGNED PUT>" }, "source": "brochure.pdf" }
  ]
}
  • Max asset size: 2 GB (raised from 1 GB on 2 Jun 2026).
  • Storage types: AWS S3 pre-signed, Azure SAS, Dropbox.
  • Response: {"jobId": "...", "statusUrl": "..."}. Poll with exponential backoff; do not hammer.

Custom script bundles

Upload a ZIP containing manifest.json and your script file:

{
  "manifestVersion": "1.0",
  "id": "my-org/layout-fixups",
  "name": "layout-fixups",
  "version": "1.0.0",
  "host": { "app": "indesign", "minVersion": "18.0" },
  "appVersionStrategy": "latest",
  "apiEntryPoints": [
    { "type": "script", "path": "script.js", "language": "extendscript" }
  ]
}
  • apiEntryPoints[].language accepts extendscript, uxpscript, or javascript — maximum 3 entry points.
  • Name rules, tightened 18 Mar 2026: 3–255 characters; only a-z A-Z 0-9 - _ . and / as a segment separator. No spaces, no @, no #, no accents. Existing scripts with illegal names must be re-uploaded.

Data-merge variable file naming — the rules that silently bite

  • A column prefixed & is used to name output files. Only one such column is allowed.
  • Unsupported filename characters are replaced with _.
  • Reserved Windows device names are escaped: CON_CON_.
  • Names are truncated at 255 characters.
  • SILENT The & naming does not apply for certain combinations of outputMediaType, pagesPerDocument, and allowMultipleRecordsPerPage — it is ignored without error. Verify your output filenames on the first run rather than assuming.

Photoshop API v2 — https://image.adobe.io/v2/

v1 reached end of life on 31 July 2026 — that date has passed

Any integration still pointing at image.adobe.io/pie/psdService/… or other v1 paths is running on borrowed time or already broken. Migrate to /v2/.

What v2 adds over v1:

  • Linked smart objects — v1 could not handle them.
  • 5 GB file ceiling, up from 2 GB.
  • UXP scripting in the cloud — run your own .psjs server-side. This is the big one: it makes the cloud API arbitrarily programmable rather than a fixed menu.
  • Generative Fill and Generative Expand as API operations.
  • Artboards as first-class objects.
  • ICC profile handling.

Named services include POST /v2/remove-background, ActionJSON execution, Product Crop, Autocrop, and GET /v2/status/{jobId}.

Illustrator API v1 — https://illustrator-api.adobe.io/v1/

  • Rendition, preview, data merge, document operations — the same async shape as InDesign.
  • Image Trace — raster to vector. Presets include enhanced_general and high_fidelity_photo. NOTE This traces an existing raster; it does not generate vectors from a text prompt.
  • Recolor — programmatic recolouring of vector artwork.
  • Custom scripts are ExtendScript-only — unlike InDesign, which accepts UXP script too. If you are writing script bundles for both, they cannot share a dialect.
Firefly text-to-vector is not in the API

Adobe's text-to-vector generation exists in the Firefly web experience. It is not exposed as a Firefly Services API operation. Do not plan a pipeline around generating .ai vector art from a prompt server-side — that capability is not purchasable today.

Cost

Reported minimum for Firefly Services enterprise access is around $1,000/month. This figure comes from third-party reporting, not from an Adobe price list — Adobe does not publish pricing. Treat it as an order of magnitude for a build/buy decision, and get a real quote before committing.

Section 08

IDML, Data Merge, and InDesign Server

In plain terms

There is a completely different way to automate InDesign that involves no AI, no API and no running application: InDesign's IDML format is just a zip file full of readable XML. You can unzip a layout, edit the text and the numbers with an ordinary script, zip it back up, and InDesign opens it as a normal document. For anything that amounts to “same layout, different content,” this is faster, cheaper and more reliable than every AI route in this report, and it runs on a server with nothing Adobe installed.

Two related tools sit alongside it. Data Merge is InDesign's own built-in mail-merge: put placeholders in a layout, point it at a spreadsheet, get one page per row. InDesign Server is a headless licensed build of InDesign that runs on a server and executes the exact same scripts your desktop copy runs — around $2,100 a year through resellers, which is a fraction of the cloud API's floor. If your job is “render a lot of documents,” look here before you look at Firefly Services.

For the implementer

IDML

  • A zip archive. designmap.xml is the index; Spreads/, Stories/, Resources/ hold the content. Text lives in Stories/.
  • Python: SimpleIDML — open, inspect, substitute, and splice IDML files without InDesign.
  • Curated tooling list: paged-media/awesome-idml.
  • Round-trips cleanly: InDesign exports IDML, InDesign opens IDML. .indd is binary and undocumented; IDML is the documented interchange path.
from simple_idml import idml

with idml.IDMLPackage("template.idml") as pkg:
    # list the story files and the XML structure
    print(pkg.stories)
    # prefix every style name to avoid collisions when combining documents
    pkg.prefix("q1").export("out.idml")
The template-substitution pattern

Have a designer build the layout once in InDesign with obvious placeholder strings ({{HEADLINE}}, {{PRICE_1}}). Export IDML. Your pipeline unzips it, does string substitution inside Stories/*.xml, rezips, and either ships the IDML directly or renders it. No Adobe software runs in your pipeline at all. This is the single cheapest production route in this entire report.

Two cautions: substitute inside the XML text nodes, not blindly across the file, and beware that InDesign splits a single visual paragraph across multiple <Content> elements whenever formatting changes mid-run. Placeholders must be styled uniformly or they will be fragmented and your replace will miss.

Data Merge

  • Built into desktop InDesign; also exposed as POST /v3/merge-data in the cloud API.
  • Source is CSV or TXT. Column headers become field names. A column prefixed @ holds image paths.
  • Handles one-record-per-page and multiple-records-per-page layouts.
  • Fully scriptable from ExtendScript via the dataMergeProperties / mergeRecords() API, so Claude can generate the whole merge as a .jsx.

InDesign Server

Current versionv21.x (the 2026 line), tracking the desktop release
InterfaceSOAP; a Java client library ships with it
ScriptsDesktop scripts run unmodified — the same .jsx, no porting
UINone. Headless. No dialogs — a script that calls alert() hangs the server
Licence~$2,100/year through resellers
Infrastructure claimsOne vendor quotes ~$50k for surrounding infrastructure. Discount this — it reflects that vendor's architecture, not a requirement of the product
Build-vs-buy, stated plainly

For document rendering at volume, the ladder is: IDML substitution (free, no Adobe software, limited to content swaps) → InDesign Server (~$2,100/yr, full InDesign semantics, you run the box) → Firefly Services (~$1,000/mo reported, Adobe runs everything, PDF→INDD conversion available nowhere else). Most teams that jump straight to the third rung did not need to.

Section 09

Reading an InDesign job without InDesign

In plain terms

§8 treats IDML as something you write — a template you fill in. The other half is more immediately useful and gets almost no attention: IDML is something you can read. Point a script at an InDesign package and it will tell you which fonts are missing, which placed images have gone astray, what the page actually measures, whether there is any bleed, and every word of copy in the layout — with no InDesign, no licence, and no Adobe software of any kind installed.

This matters because of the gap in §4. Driving InDesign from an AI on Windows is paid-only; the free bridges are macOS-only by architecture. But that limit applies to controlling the application. Inspecting the work is free, cross-platform, needs nothing running, and is the part most worth automating anyway — a preflight pass catches the errors that cost money at the printer, and it costs a few hundred milliseconds. Everything below was measured against a real production ad package: a 10 × 20 in print ad, 11 placed assets, delivered as a standard InDesign Package folder.

For the implementer

An IDML is a zip. Six files inside it answer six different preflight questions. Nothing here needs a third-party library beyond the standard library — zipfile and a regex are enough, though SimpleIDML is friendlier if you are also writing.

QuestionWhere the answer lives
Which fonts are missing or substituted?Resources/Fonts.xmlStatus
Which placed images are missing?Spreads/*.xmlLinkResourceURI
Does a missing item actually print?ItemTransform + page GeometricBounds
Page size, bleed, slugResources/Preferences.xml and the spread
Every word of copyStories/*.xml<Content>
Is a font actually used, or just referenced?Resources/Styles.xml

Font status — the highest-value probe

Every font carries a Status: Installed, Substituted, or NotAvailable. This is the single most useful thing in the file, because a missing display weight is invisible in a PDF proof until someone notices the headline looks wrong.

import zipfile, re

z = zipfile.ZipFile("job.idml")
res = z.read("Resources/Fonts.xml").decode("utf8", "ignore")
for m in re.finditer(r'<Font\b[^>]*>', res):
    ps = re.search(r'PostScriptName="([^"]+)"', m.group(0))
    st = re.search(r'Status="([^"]+)"', m.group(0))
    if st and st.group(1) != "Installed":
        print(ps.group(1), st.group(1))    # BigShouldersDisplay-Black NotAvailable
Status describes the machine that wrote the file, not yours

NotAvailable means the font was missing on the workstation that exported the IDML. That is exactly what you want for incoming-package QA — it tells you the supplier was working without the font — but it is not a statement about your own system. Treat it as provenance, not as a local check.

Missing links — and the decoding bug that fakes them

Placed assets appear as LinkResourceURI. Compare the basenames against the Links/ folder. One trap costs an hour if you miss it:

URL-decode the URI or you will invent missing files

LinkResourceURI is percent-encoded. Decoding only %20 is the obvious half-fix and it is wrong — a file named PS Resorts Logo (1) white.psd arrives as PS%20Resorts%20Logo%20%281%29%20white.psd, and the parentheses stay encoded. It sits right there in Links/ and your report calls it missing. Use urllib.parse.unquote, not a .replace() chain.

from urllib.parse import unquote
import os

have = {f.lower() for f in os.listdir("Links")}
spreads = "".join(z.read(n).decode("utf8", "ignore")
                  for n in z.namelist() if n.startswith("Spreads/"))

for uri in set(re.findall(r'LinkResourceURI="([^"]+)"', spreads)):
    name = unquote(uri.split("/")[-1])          # NOT .replace("%20", " ")
    if name.lower() not in have:
        print("MISSING", name)

On-page or pasteboard? The triage that makes the report usable

A raw missing-link count is close to useless. In the measured package, eight links were missing — and seven of them were dead material parked on the pasteboard, left over from earlier rounds. Exactly one overlapped the live page. “Eight missing links” would have sent someone hunting for eight files; “one missing link touches the trim, seven are abandoned” is an actionable sentence.

Resolve it geometrically. A page's GeometricBounds is "y1 x1 y2 x2" in points. Each item's ItemTransform is a six-number affine matrix whose last two values are the translation; add them to the item's path anchors to get absolute page coordinates, then test for overlap.

# ItemTransform = "a b c d tx ty"; anchors are relative to that origin
tx, ty = float(t[4]), float(t[5])
x0, x1 = tx + min(xs), tx + max(xs)
y0, y1 = ty + min(ys), ty + max(ys)
on_page = x1 > page_x0 and x0 < page_x1 and y1 > page_y0 and y0 < page_y1
Do not trust DocumentPreference for the page size

Resources/Preferences.xml reported PageWidth="720" PageHeight="1512" — 10 × 21 in. The actual page, from the spread's GeometricBounds, was 720 × 1440 pt: 10 × 20 in, which is what the exported PDF measured. The document preference had gone stale against a resized page. Measure the spread; treat the preference as a hint. Bleed and slug offsets in that same file are reliable — all four bleed offsets being 0 is a genuine finding worth surfacing.

Copy extraction, and what it turns up

Every visible string is in Stories/*.xml inside <Content> elements. Concatenating them gives you the full text of the layout, which is worth diffing against whatever the client last approved. In the measured package this immediately surfaced a live text frame still carrying the client's revision instructions (“REMOVE everything saying must be purchased in advance”) along with a superseded ticket price, plus three mutually inconsistent vendor lists and one vendor name spelled two ways.

Remember the §8 caveat in reverse: InDesign splits a paragraph across multiple <Content> elements wherever formatting changes mid-run, so join them before matching, or a phrase that straddles a style change will not be found.

Referenced ≠ used

The phantom font dependency

Fonts.xml listed MinionPro-Semibold as Substituted, which reads like a licensing problem — Minion Pro ships with Creative Cloud and cannot be packaged. It was a false alarm. Searching Stories/ found zero text using it; the only reference was in Resources/Styles.xml, on $ID/[No paragraph style] — InDesign's built-in default, whose factory font is Minion Pro. It is present in essentially every InDesign document ever made, used or not.

So: before you chase a font, confirm a story applies it. Check <AppliedFont> in Stories/, not just the font table.

Cross-check the exported PDF

The IDML tells you what the layout wants; the PDF tells you what actually got out. Reading the font descriptors of the export is a direct test of whether a substitution reached the proof. In the measured package, three Big Shoulders Display weights were NotAvailable — and the PDF embedded exactly one weight of that family, Thin. No Bold, no ExtraBold, no Black anywhere in the file. A /FontFile, /FontFile2 or /FontFile3 key on the descriptor means embedded; its absence means the glyphs are not in the document.

Recovering the fonts — a 2026 trap

Google Fonts no longer ships static instances

Both missing families were free OFL fonts, so this should have been a download. It is not any more. ofl/bigshouldersdisplay/ upstream contains exactly one font file — BigShouldersDisplay[wght].ttf — and no static/ folder. The old static/Family-Weight.ttf URLs 404.

That matters because IDML resolves fonts by per-weight PostScript name (BigShouldersDisplay-Black), and a variable font does not satisfy those names. Pin the axis and rewrite the name table from STAT:

from fontTools.ttLib import TTFont
from fontTools.varLib import instancer

vf = TTFont("BigShouldersDisplay[wght].ttf")
# updateFontNames is what makes the PostScript name come out as
# BigShouldersDisplay-Black instead of staying -Regular
st = instancer.instantiateVariableFont(vf, {"wght": 900},
                                       inplace=True, updateFontNames=True)
st.save("BigShouldersDisplay-Black.ttf")

Then verify rather than assume: read name ID 6 back out of each generated file and compare it to the string the IDML asked for. That is the value InDesign matches on, and it is the only proof the instancing worked. Drop the statics into the package's Document fonts/ folder and the document self-activates them on open — but do not put the variable font in there alongside them, or InDesign has two sources for one family to disambiguate.

Where this sits among the five routes

This is Route D (generated script) pointed at the file rather than at the application, and it inherits Route D's best property: it runs anywhere, twice, in CI, with no licence and no Adobe process. It cannot change the document — for that you are back to §4's paid bridges or §8's template substitution. But as a gate in front of either, it is free, and it is the only InDesign automation in this report that costs nothing on Windows.

Assert on the artifact

Per §13: a preflight script that prints findings and exits 0 will be ignored within a week. Exit non-zero on any finding you actually care about — missing font, missing link that overlaps the trim, zero bleed on a document with edge-bleeding art — and put it in the build.

Section 10

Claude Design: what it actually exports

In plain terms

Claude Design is real. It launched on 17 April 2026 as an Anthropic Labs product and it genuinely produces designed output from a conversation. But its export formats matter enormously for anyone planning an Adobe pipeline, and they are narrower than people assume: it exports .zip, PDF, PPTX and HTML. That is the list. There is no SVG export, no Illustrator .ai file, and no InDesign IDML.

This means Claude Design is not the front end of a layered-Adobe-file pipeline, and any plan that assumes it hands editable vector artwork to Illustrator is built on a format that does not exist. Where it does connect to Adobe, that bridge lands in Adobe Express — the lightweight consumer-facing app — not in Illustrator or InDesign. If you want layered Illustrator output from a prompt, the route is Illustrator's built-in MCP server (§2), not Claude Design.

For the implementer
ClaimVerdictDetail
Claude Design existsTRUEAnthropic Labs, launched 17 Apr 2026
Exports .zip / PDF / PPTX / HTMLTRUEThe complete documented list
Exports SVGNOT DOCUMENTEDNo SVG export appears in the documentation
Exports .ai or IDMLFALSENeither format is offered
Has an Adobe bridgePARTLYYes — into Adobe Express, not Illustrator/InDesign
“Adobe for Creativity” connector existsTRUEAnnounced 28 Apr 2026, 50+ tools
…is “native multi-app access”MISLEADINGIt is the Express/Firefly tier, not desktop Illustrator/InDesign/Photoshop

Practical consequence for a pipeline

The useful export for downstream Adobe work is the HTML bundle inside the .zip, because HTML carries structure (elements, classes, a DOM) that a script can walk. From there you have two honest options:

  1. HTML → your own SVG generator → Illustrator. You control the SVG shape and can enforce the structural rules in §11. More work; predictable output.
  2. Prompt → Illustrator MCP directly (§2). Skip Claude Design entirely for anything that must end up as a layered .ai. This is the shorter path and produces real layers.

Route 2 is correct for almost every case where the deliverable is an Illustrator file. Route 1 is only better when Claude Design's compositional judgement is what you actually wanted and the Adobe file is a downstream artifact.

Section 11

The layered-SVG myth — the correction that matters most

In plain terms

There is a widely repeated claim that if you generate an SVG file with named groups — <g id="Background">, <g id="Type"> — Illustrator will open it with those as named layers. It will not. Illustrator opens it with a single layer called “Layer 1” containing named groups. The reason is simple and unfixable: the SVG format has no concept of a layer. There is no element for it. Nothing in the file can express the idea.

This is the single most consequential error circulating on this topic, because it is the exact promise that makes AI-generated Adobe files sound like a solved problem, and it is repeated in confident-sounding documentation that does not exist. There are three real fixes — accept groups instead of layers, use Illustrator's Release to Layers command and lose the names, or run a short conversion script that turns groups into layers and keeps the names. The fourth and best option is not to use SVG at all: Illustrator's built-in MCP server creates genuine named layers directly.

For the implementer
The SVG you generate <svg viewBox="0 0 800 600"> <g id="01_Background"> … </g> <g id="02_Shapes"> … </g> <g id="03_Icons"> … </g> <g id="04_Type"> … </g> </svg> open in Ai What the Layers panel shows ▾ Layer 1 ← the ONLY layer ▸ <Group> 01_Background ▸ <Group> 02_Shapes ▸ <Group> 03_Icons ▸ <Group> 04_Type names survive · layer status does not
The actual behaviour. The id attributes do carry through as group names — that part of the folklore is true. What does not happen is promotion to layers.

The three fixes, ranked

FixKeeps namesEffortWhen
Work in groups, not layersYESNoneGroups are selectable, nameable, hideable and lockable. For most downstream work they are sufficient, and “I need layers” is often untested habit.
Object → Release to Layers (Sequence)NOTwo clicksYou get real layers and lose every name. Only useful when order matters and names do not.
Group→layer .jsxYESRun one scriptThe correct fix. Creates a layer per top-level group, named from the group, and moves the contents across. A well-known gist by edygar does exactly this.
Use the MCP server instead BESTYES§2 setupReal layers created natively. No conversion step exists to go wrong.
// Illustrator .jsx — promote each top-level group to its own named layer.
// ES3 only: no let/const, no arrow functions, no forEach.
(function () {
  if (app.documents.length === 0) { alert("Open a document first."); return; }
  var doc = app.activeDocument;

  // The imported art lands on the bottom-most layer. Do NOT assume it is called "Layer 1".
  var src = doc.layers[doc.layers.length - 1];

  // Iterate backwards — moving items mutates the collection.
  for (var i = src.groupItems.length - 1; i >= 0; i--) {
    var g = src.groupItems[i];
    if (g.parent !== src) { continue; }        // top-level groups only

    var layer = doc.layers.add();
    layer.name = g.name || ("Group " + i);

    while (g.pageItems.length > 0) {
      g.pageItems[0].move(layer, ElementPlacement.PLACEATEND);
    }
    g.remove();
  }
  if (src.pageItems.length === 0) { src.remove(); }
})();

The SVG prompt that actually holds up

If you are generating SVG for Illustrator anyway, most of the failures are not about layers at all — they are unsupported features. This is the constraint set that survives contact with Illustrator's importer:

Produce a single SVG file. Obey ALL of the following:

STRUCTURE
- Exactly one <svg> root with a viewBox and NO width/height attributes.
- Direct children of <svg> are ONLY top-level <g> elements with an id.
- Order them back-to-front, numbered:
    01_Background, 02_Shapes, 03_Icons, 04_Type
- Every drawable element lives inside one of those groups. Nothing at the root.

FORBIDDEN — Illustrator handles these badly or not at all
- No <style> blocks and no class attributes. Style with presentation attributes only.
- No CSS variables, no @media, no @font-face.
- No filters, no masks, no clipPath unless explicitly requested.
- No <foreignObject>. No embedded raster unless explicitly requested.
- No transform on the top-level groups.

REQUIRED
- Fills and strokes as literal hex, e.g. fill="#1C1B19". No named colours, no rgb().
- Text as live <text> elements — never converted to paths.
- font-family naming a font the target machine actually has.
- Absolute coordinates. No percentage units.
Two fabricated sources to watch for

The source material for this research cited an Adobe help page describing SVG-id-to-layer mapping. No such page exists. It also cited github.com/indesign-extendscript-plugins as a repository of InDesign scripts. That URL is a 404 and the repository does not exist. The real offline InDesign route is IDML (§8). If you see either citation repeated, the document you are reading was not checked.

Section 12

Five pipelines you can ship this week

In plain terms

Everything above is inventory. This section is what to actually build. Each of these five is a complete working shape — what goes in, what comes out, which route it uses, and what can go wrong — ordered from “an afternoon” to “a real project.” None of them requires an enterprise contract except the last.

If you only do one thing: set up the Illustrator MCP server and run recipe 1. It takes about ten minutes and it will tell you more about what this technology can and cannot do than any amount of further reading.

For the implementer

Recipe 1 — Prompt to layered Illustrator file START HERE

  • Route: A (built-in MCP).
  • In: a text description. Out: an .ai file with correctly named layers and per-object SVG/PNG exports.
  • Shape: Set up per §2. Prompt in this order — (1) create the document and artboards, (2) create the named layers first, empty, (3) add art to a named layer at a time, (4) take a preview image and correct, (5) export.
  • Why layers first: creating the layer before the art means every object is born in the right place. Retrofitting layers onto existing art is where the model burns tokens and makes mistakes.
  • Check: assert the exported files exist and are non-trivial in size; open the .ai and confirm the Layers panel matches your list.

Recipe 2 — Batch Photoshop operation across a folder

  • Route: D (generated script), not C.
  • In: a folder of images plus a rule. Out: processed files plus a log.
  • Shape: Have Claude write one .psjs that takes a folder, iterates, applies the operation, saves to an output folder, and writes a CSV log of every file with its outcome. Run it from Photoshop's Scripts menu.
  • Why not MCP: a 500-file batch through a conversational bridge is 500 round-trips and 500 chances to drift. A script is one deterministic pass you can re-run and diff.
  • Check: input count equals output count; the log has zero error rows.

Recipe 3 — Interactive Photoshop editing session

  • Route: C (alisaitteke/photoshop-mcp).
  • In: an open document plus conversation. Out: edits, live.
  • Shape: Install per §5. Prefer recipe tools over composing atomic ones — one undo step instead of fifteen.
  • Failure mode: the model narrates success it did not verify. Ask it to list the layers back after any structural change.

Recipe 4 — Template-driven document generation, no Adobe software

  • Route: IDML substitution (§8).
  • In: an IDML template plus a data table. Out: one IDML (or rendered PDF) per row.
  • Shape: Designer builds the layout once with uniformly-styled {{PLACEHOLDER}} strings and exports IDML. Pipeline unzips, substitutes inside Stories/*.xml, rezips. Render either by opening in InDesign, or on InDesign Server, or via POST /v3/merge-data.
  • The one gotcha: a placeholder whose formatting changes mid-string is split across multiple <Content> nodes and your replace silently misses it. Enforce uniform styling on placeholders and assert that zero {{ sequences survive in the output.
  • Cost: zero, for the substitution step.

Recipe 5 — Server-side rendering at volume

  • Route: E (Firefly Services) or InDesign Server.
  • In: template plus data at scale. Out: thousands of PDFs.
  • Shape: Per §7 — mint a token (cache it, 24 h), stage assets to S3/Azure, generate pre-signed GET URLs for inputs and PUT URLs for outputs, POST /v3/merge-data, poll statusUrl with exponential backoff, collect from your own bucket.
  • Build this first: the storage/pre-signing/polling layer, with a fake Adobe call. It is most of the work and all of the operational risk. Swap in the real endpoint last.
  • Decide honestly: InDesign Server at ~$2,100/yr does the same rendering. Firefly Services earns its ~$1,000/mo only if you need managed scale or convert-pdf-to-indesign.
The check that applies to all five

Every one of these routes will happily report success while producing nothing. A transcript saying “I've exported the layers” is not evidence. Write the assertion against the artifact — the file exists, its size is plausible, its layer count matches, its text contains no surviving placeholder tokens — and make it exit non-zero when it fails. That assertion is the deliverable, not the prompt.

Section 13

The gotchas ledger

In plain terms

Every item below cost somebody real time. They are the small, unglamorous facts that are not in the marketing material and are hard to guess: an old file extension that silently selects a completely different programming language, a coordinate order that is not the one you expect, a date that has already passed. Skim it once now and it will save you an afternoon later.

For the implementer

Language and API

  • The file extension chooses the engine. .jsx = ExtendScript (ES3), .psjs = Photoshop UXP, .idjs = InDesign UXP. Same menu item, three different runtimes, incompatible APIs.
  • ExtendScript is ES3. No let/const, no arrow functions, no template literals, no JSON. Modern JavaScript pasted into a .jsx fails at parse time with an unhelpful error.
  • geometricBounds is [top, left, bottom, right] — not [x, y, w, h], and not [left, top, …]. Getting this wrong produces frames that are silently mirrored or off-canvas.
  • Font names are "Family\tStyle" with a literal tab. "Minion Pro\tRegular". A space does not work.
  • place() links, it does not embed. Moving the output file breaks the link. Embed explicitly if the file will travel.
  • Make scripts idempotent. Guard every lookup with .isValid before use; a re-run that assumes a clean document is a re-run that throws.
  • Do not assume the default layer is named “Layer 1”. Localised installs and imported files differ. Use doc.layers[doc.layers.length - 1] for the bottom layer.
  • InDesign Server has no UI. Any alert() left in a script hangs the process.

Dates and versions that have already passed

  • 🔴 Photoshop API v1 reached end of life 31 July 2026. Check every integration you own.
  • Firefly Services asset limit rose to 2 GB on 2 June 2026 (InDesign) and 5 GB for Photoshop v2. Older documentation says 1 GB / 2 GB.
  • Script name rules tightened 18 March 2026. Scripts uploaded before that with spaces or @ in the name need re-uploading.
  • The ExtendScript Toolkit editor was deprecated in 2020 — the language was not. These are constantly confused. Use VS Code with the ExtendScript Debugger extension.
  • CEP 12 is the last major CEP version. Do not start new CEP work.

Infrastructure

  • MCP is loopback-only. Illustrator's server binds localhost:18412. An AI tool in a container or on a remote host cannot reach it.
  • The Illustrator bearer token does not expire on its own — it lives until you regenerate it. Treat it as a long-lived credential.
  • Adobe help pages can be slow or unreachable over IPv6 from some networks. If curl against helpx.adobe.com returns zero bytes, force IPv4 and HTTP/1.1: curl -sS -4 --http1.1 <url>. This wasted hours during this research and is not an Adobe outage.
  • Firefly Services never stores your files. Pre-signed URL expiry is your problem — if a job queues longer than your URL's lifetime, it fails at the fetch step with a permissions error that looks like an auth bug.
  • Free InDesign MCP servers are macOS-only because they drive the app through AppleScript. This is architectural, not an oversight, and will not be fixed by waiting.

Model behaviour

  • Ask for a plan before destructive multi-tool runs. Adobe's own suggested phrasing: “Show me a plan before making changes.”
  • Ask for a preview image after structural changes. Without it, the model asserts success from its own intent rather than from the document.
  • Prefer recipe/compound tools over composing atomic ones where a server offers both — fewer round-trips, one undo step, far fewer half-applied states.
  • Do not touch objects the assistant is mid-edit on. Documented conflict, in Illustrator specifically.
Section 14

Every link, checked

In plain terms

Every source behind this report, grouped by topic. Links marked 404 are included deliberately — they are cited in circulating material about this subject and they do not exist. Knowing which sources are fictional is as useful as knowing which are real.

Section 15

Method, and what remains unverified

In plain terms

This report was built by checking claims rather than collecting them. Where a source said something specific, the underlying page was fetched and read; where a page was supposed to exist and did not, that absence is recorded as a finding rather than quietly dropped. Several widely-repeated claims did not survive, including one about a documentation page that was invented outright.

Some things could not be settled from documentation alone and are marked as such throughout — pricing that Adobe does not publish, a beta whose capability page has not been written yet, and one genuine contradiction where Adobe's own support statements and the working software disagree. Those are flagged inline rather than smoothed over. Everything else is dated 5 August 2026 and beta surfaces move fast.

For the implementer

How each class of claim was handled

Claim typeTreatment
Feature exists / does not existFetched the primary Adobe page. A 404 is recorded as a verified negative, not as “unknown.”
Version numbers, datesTaken from Adobe release notes and what's-new pages only.
Tool countsTaken from the vendor's own count. Aggregate figures are attributed to the aggregator (e.g. the “~130 tools” figure is Sidekick's).
PricingPublished prices stated as fact; the Firefly Services figure is labelled reported throughout because Adobe does not publish it.
Behaviour claimsWhere documentation and folklore disagree (the SVG-layers case), the format specification decides.

Open items — the honest list

  • InDesign AI Assistant daily credit limit. Adobe states a complimentary limit exists and does not publish the number.
  • Firefly Services pricing. ~$1,000/month is third-party reporting. Get a quote.
  • Photoshop AI Assistant capabilities. No capability page published as of verification; only the 10 Mar 2026 beta announcement is solid.
  • Illustrator CEP support. An Adobe support response says unsupported since 2022; commercial CEP panels for Illustrator continue to ship and work. Unresolved.
  • Illustrator MCP tool list stability. Forty tools across six categories at verification time, in a beta. Expect drift.
  • Claude Design SVG export. Absent from the documentation. Absence of documentation is weaker evidence than a 404 — treat as “not documented,” not “proven impossible.”
Re-check triggers

Re-verify this report when any of these happen: Illustrator's MCP server leaves Beta; InDesign or Photoshop publishes a connect-…-to-ai-tools page; Photoshop's AI Assistant capability page appears; Firefly Services publishes pricing. Each of those changes a recommendation here, not just a detail.