Skip to main content
Glama
Bieuulls

Illustrator AI & MCP Control

by Bieuulls

illustrator_execute_script

Destructive

Run raw JavaScript/ExtendScript in Adobe Illustrator to perform custom operations, access the full DOM, and read document state when higher-level tools fall short.

Instructions

Execute raw JavaScript/ExtendScript code in Adobe Illustrator.

CONTRACT: readOnly=False, destructive=True, idempotent=False, openWorld=True

WHEN TO USE:

  • Single one-off items, quick prototypes, or operations not covered by higher-level tools

  • Full DOM access when structured tools are insufficient

  • Reading document state with custom logic

  • To SEE the artwork, use illustrator_observe instead: it returns the image inline with a numbered map of items, their handles and bounds, so there is no file to export, locate and open

EXECUTION CONTRACT: Your script is evaluated at the top level, not inside a function. - The value of the LAST EXPRESSION is the result. End with the value you want back, usually a JSON.stringify(...) call. - A bare return is a syntax error: "Illegal return outside of a function body". Wrap the code in a function and call it immediately when you need an early exit. - Returning an object is fine; it is serialised for you. Returning nothing is a valid outcome and is reported as data: null. Injected helper libraries are declared at the same top level, so they are in scope either way. See EXAMPLES for both forms. Top-level {ok:false}, {success:false}, or a string error field produces a warning, not an execution failure. Nested values remain opaque. Use throw or mcpFail(message, details) for an explicit failure: try { doWork(); } catch (e) { mcpFail("Label failed", {cause:String(e)}); } mcpFail throws an ordinary catchable Error; details are bounded to 2048 characters. Neither throwing nor returning an error rolls back edits. Host line numbers, when available, refer to injected host code, not necessarily to the caller's source lines. Verification is separate.

ABSTRACTION LADDER — prefer higher levels before using raw script: Level 5 — illustrator_path_boolean: boolean sculpt (unite/subtract/intersect/xor) Level 4 — illustrator_execute_task + element_create_batch: batch-create identical shapes Level 3 — illustrator_path_import_svg: import SVG d-string paths Level 2 — illustrator_execute_task + element_create: smooth curves, handles, mirror Level 1 — illustrator_execute_script (THIS tool): raw ExtendScript

DECISION RULES:

  • Subtract/unite shapes — MUST use illustrator_path_boolean

  • Creating >=3 identical shapes — MUST use illustrator_execute_task + element_create_batch

  • setEntirePath with >12 coord pairs — STOP and use smooth:true or illustrator_path_import_svg

COORDINATE SYSTEM:

  • Geometry helpers use artboard-relative coordinates: origin at the active artboard's top-left, with y increasing downward (screen space)

  • Raw Illustrator DOM positions use document-space coordinates, with y increasing upward; do not assume that the active artboard starts at (0, 0)

  • Units: points (1 pt = 1/72 inch)

HELPERS — ARTBOARD-RELATIVE, Y-DOWN (includes: ['geometry']): Use these to avoid manual conversion to raw document coordinates: rectXY(x, y, w, h) — rectangle at screen-space (x,y) ellipseXY(x, y, w, h) — ellipse at screen-space (x,y) lineXY(x1, y1, x2, y2) — line between screen-space points polygonXY([[x,y],...], closed)— polygon from screen-space points pointXY(x, y) — returns {left, top} for position assignments drawPathPoints(spec) — full path with handles, UUID, heap registration Example: var rect = rectXY(100, 200, 50, 30); // no -y needed

RAW DOM — DOCUMENT-SPACE, Y-UP (only when helpers are insufficient): These are API snippets to put inside a script, not tool calls. Convert an artboard-relative point before passing it to the DOM: var ab = doc.artboards[doc.artboards.getActiveArtboardIndex()].artboardRect; var position = [ab[0] + x, ab[1] - y]; // Nonzero-origin example: ab top-left (72, 720), (x, y) = (100, 200) // gives the raw DOM position [172, 520]. Rectangle: doc.pathItems.rectangle(position[1], position[0], width, height) ⚠ width & height must be POSITIVE. Negative height → shape above artboard (invisible). Ellipse: doc.pathItems.ellipse(position[1], position[0], width, height) Line: convert each artboard-relative point with the same ab-offset formula Color: var c = new RGBColor(); c.red=255; c.green=0; c.blue=0; shape.fillColor = c; Text: var tf = doc.textFrames.add(); tf.contents = "text"; tf.position = position; Grid helpers: artboardGrid(cols, rows), itemsInCell(cell, mode)

EXAMPLES: Read with a native-coordinate crop: { "params": { "script": "app.activeDocument.name;", "return_preview": true, "clip_box": [ 0, 125, 125, 0 ], "clip_space": "illustrator_native_y_up" } } Draw in artboard-relative Y-down coordinates with geometry helpers: { "params": { "script": "var r = rectXY(50, 80, 200, 100); r.fillColor = makeRGBColor(255, 0, 0); r.name;", "includes": [ "geometry" ], "description": "red banner" } } Position text from an offset artboard using raw DOM coordinates: { "params": { "script": "var doc = app.activeDocument; var ab = doc.artboards[doc.artboards.getActiveArtboardIndex()].artboardRect; var x = 100; var y = 200; var tf = doc.textFrames.add(); tf.contents = 'Offset'; tf.position = [ab[0] + x, ab[1] - y]; tf.position;", "description": "raw DOM offset-artboard placement" } } Read state back; the last expression is the result: {"params": {"script": "JSON.stringify({items: app.activeDocument.pageItems.length});"}} Return early, which needs a function wrapper: { "params": { "script": "(function () { var d = app.activeDocument; if (d.pageItems.length === 0) return 'empty'; return d.pageItems[0].name; })()" } } A readback, declared so it is not treated as an edit: { "params": { "script": "JSON.stringify({name: app.activeDocument.name});", "read_only": true } }

ELEMENT DISCOVERY:

  • Use artboardGrid(cols, rows) to partition the artboard into a labeled grid

  • Use itemsInCell(cell, mode) to find items in a specific grid cell

  • Modes: 'containsCenter' (default) or 'intersects'

  • Cell labels follow A1 scheme (letter row + number col, e.g. A1, B3)

MUTATION SAFETY:

  • Each call increments a per-document mutation counter

  • Failed executions decrement it again, so failures do not accumulate

  • A raw script is opaque to this server, so it cannot tell which kind of change you made. Evidence is therefore requested on a backlog rule rather than on the operations performed, unlike illustrator_execute_task

  • Use final_step=true on the last mutation to require final evidence

NOTES:

  • When evidence is required the result carries a VERIFICATION REQUIRED block naming what to confirm, and diagnostics.evidence says whether an image was actually supplied

  • return_preview=false suppresses capture but not the requirement, which is then reported unmet rather than dropped

  • setEntirePath() creates corner points only; set handles after creation

  • ExtendScript can access File/Folder and OS — treat as open-world

SAFETY:

  • __mcp_check() watchdog: call as FIRST line inside every for/while body

  • Never iterate live Illustrator collections if adding/removing items

  • Use __mcp_forEachSnapshot(collection, fn) or __mcp_snapshot(collection) instead

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
paramsYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses extensive behavior beyond annotations: the execution contract (last-expression value, illegal return), error handling via mcpFail, mutation counter and evidence requirements, safety watchdog, open-world access, coordinate system differences, and helper libraries. It explains that raw scripts are opaque to the server and how read_only parameter affects evidence. This far exceeds what annotations alone convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well-structured with clear headings (CONTRACT, WHEN TO USE, EXECUTION CONTRACT, etc.). It front-loads the purpose and usage, and uses examples effectively. Some redundancy exists (coordinate system repeated across sections), but given the tool's complexity, the length is justified. It is not over-verbose to the point of harming readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers every aspect an agent needs to call the tool correctly: execution semantics, coordinate conversions, helper functions, error handling, safety, mutation evidence, and decision rules. It also references sibling tools for routing. The output schema is absent, but the description clearly explains the result format (last expression serialized, data:null for nothing). Nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already contains rich descriptions for every parameter (script, includes, clip_box, read_only, etc.), so the baseline is 3. The description adds context about coordinate systems for clip_box and clip_space, and mentions helper functions that relate to includes, but does not redefine parameter meanings. It does not materially improve upon the schema's own documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first line states the verb and resource clearly: 'Execute raw JavaScript/ExtendScript code in Adobe Illustrator.' It distinguishes itself from siblings by explicitly naming alternatives like illustrator_observe for seeing artwork and listing higher-level tools in the abstraction ladder. An agent can immediately know this is the low-level script runner.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'WHEN TO USE' section lists explicit use cases (one-off items, quick prototypes, operations not covered by higher-level tools) and points to illustrator_observe as the alternative for visual inspection. The 'DECISION RULES' section states MUST-use requirements for other tools (e.g., path_boolean for boolean ops, task+batch for identical shapes), leaving no ambiguity about when to choose this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.