Illustrator AI & MCP Control
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| TIMEOUT | No | Timeout in seconds for MCP operations | 30 |
| WS_HOST | No | Host address for the WebSocket bridge | 127.0.0.1 |
| WS_PORT | No | Port for the WebSocket bridge | 8081 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| illustrator_execute_scriptA | Execute raw JavaScript/ExtendScript code in Adobe Illustrator. CONTRACT: readOnly=False, destructive=True, idempotent=False, openWorld=True WHEN TO USE:
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 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:
COORDINATE SYSTEM:
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:
MUTATION SAFETY:
NOTES:
SAFETY:
|
| illustrator_execute_taskA | Execute structured SOC operations or a compatibility callback pipeline. CONTRACT: readOnly=False, destructive=True, idempotent=False, openWorld=True WHEN TO USE:
EXAMPLES: One structured operation (the preferred form): { "params": { "batch": { "operations": [ { "task": "element_create", "params": { "type": "rect", "x": 40, "y": 40, "width": 200, "height": 120, "fill": { "r": 0, "g": 150, "b": 136 } } } ] } } } Several operations, stopping at the first failure: { "params": { "batch": { "operations": [ { "task": "element_create", "params": { "type": "ellipse", "x": 0, "y": 0, "width": 60, "height": 60, "id": "dot" } }, { "task": "element_modify", "targets": { "type": "id", "ids": [ "dot" ] }, "params": { "x": 120 } } ], "stopOnError": true } } } Validate a batch without applying it: { "params": { "batch": { "operations": [ { "task": "element_create", "params": { "type": "star", "x": 100, "y": 100, "numPoints": 5, "outerRadius": 40, "innerRadius": 18 } } ], "mode": "validate" } } } Create a layer through the compatibility route: {"params": {"payload": {"task": "layer_create", "params": {"name": "Background"}}}} Create a layer, then a rectangle on it, in one batch: { "params": { "batch": { "operations": [ { "task": "layer_create", "params": { "name": "Background" } }, { "task": "element_create", "params": { "type": "rect", "x": 0, "y": 0, "width": 800, "height": 600, "layer": "Background" } } ], "stopOnError": true } } } TARGET SELECTORS: {type: "selection"} — current selection (default) {type: "layer", layer: "Layer 1"} — all items on layer {type: "query", itemType: "PathItem", pattern: "axis_*"} — pattern match {type: "all", recursive: true} — all items in document {type: "id", ids: ["A1", "A2"]} — stable MCP ID targeting OPTIONS: batch.stopOnError and payload.options.stopOnError stop after the first failed operation. They preserve earlier edits and do not provide transactional rollback. payload.options.mode and stopOnError are honored by the default structured SOC route. trace is honored by both structured and callback routes. payload.options.kind, skipCollect, minCreated, idPolicy, and the deprecated assignIds alias are callback-pipeline controls. The default SOC route forces kind="creation", resolves per-op targets, and has no apply callback. retry, idempotency, and timeout are compatibility fields that still validate but are currently ignored by this executor. It does not call the retry wrapper or use payload.options.timeout as its host deadline. dryRun — NOT SUPPORTED; rejected before execution. It could not prevent mutation (batch ops run during compute) and reported otherwise. To inspect without changing anything, use query_items, preflight_check, or get_document. rollback, snapshot, and recompute — NOT SUPPORTED; enabled requests are rejected before host dispatch. Explicit false/null disabled forms remain valid. Unknown task, payload, batch, operation, option, and nested retry fields are rejected. Use stopOnError instead of the internal strict spelling. RESULT: structuredContent carries the canonical result object: execution status, data, effects, verification, recovery, warnings and truncation. isError reflects the EXECUTION outcome only — a failed or unavailable visual check never turns a successful edit into a tool error. NOTES:
|
| illustrator_job_statusA | Inspect a retained Illustrator job; optionally finalize its export files. CONTRACT: readOnly=False, destructive=True, idempotent=True, openWorld=True WHEN TO USE:
RESULT: Returns the Python record immediately for queued/running jobs. For an unresolved terminal record, queries the bounded host ledger when the CEP panel is available and idle, then mirrors a completed outcome locally. EXAMPLES: Reconcile a job whose reply was lost: {"params": {"jobId": "job_7f3a91c2"}} NOTES:
|
| illustrator_path_booleanA | Perform boolean operations (subtract, unite, intersect, xor) on paths. CONTRACT: readOnly=False, destructive=True, idempotent=False, openWorld=False WHEN TO USE:
PIPELINE:
EXAMPLES: Unite: {"params": {"operation": "unite", "subject": "body_id", "clip": ["wing_id"]}} Subtract a hole: {"params": {"operation": "subtract", "subject": "plate_id", "clip": ["hole_id"]}} NOTES:
|
| illustrator_export_documentA | Export the active document to PNG or JPG. Native SVG and PDF are refused. CONTRACT: readOnly=False, destructive=True, idempotent=False, openWorld=True WHEN TO USE:
EXAMPLES: PNG at twice the size: {"params": {"file_path": "C:/out/fig.png", "format": "png", "scale": 2.0}} PDF refusal; use a separate working copy with Illustrator PDF save: {"params": {"file_path": "C:/out/fig.pdf", "format": "pdf"}} SVG refusal after source-association failure; use a separate working copy: {"params": {"file_path": "C:/out/fig.svg", "format": "svg"}} PNG of the artboard, returned inline as well: {"params": {"file_path": "C:/out/fig.png", "return_image": true, "artboard_only": true}} Refuse rather than overwrite an existing file: {"params": {"file_path": "C:/out/fig.png", "format": "png", "overwrite": "fail"}} Keep the old file and write beside it: {"params": {"file_path": "C:/out/fig.png", "overwrite": "version"}} NOTES:
|
| illustrator_historyA | Undo or redo actions in Illustrator. CONTRACT: readOnly=False, destructive=True, idempotent=False, openWorld=False WHEN TO USE:
EXAMPLES: Undo three steps: {"params": {"action": "undo", "count": 3}} Save a checkpoint before risky work: {"params": {"action": "checkpoint_save", "name": "before_boolean"}} Restore it: {"params": {"action": "checkpoint_restore", "name": "before_boolean"}} List checkpoints: {"params": {"action": "checkpoint_list"}} NOTES:
|
| illustrator_place_fileA | Place an external file (EPS, AI, PDF, image) into the document. CONTRACT: readOnly=False, destructive=True, idempotent=False, openWorld=True WHEN TO USE:
KEY CONCEPTS: linked=True (drafting) — file updates automatically when source changes linked=False (final) — file is embedded and fully editable embed_editable=True — opens PDF, copies content as editable vectors (slower) trace=True — place raster, then run Image Trace to vectorize EXAMPLES: Place a linked image: {"params": {"file_path": "C:/img/photo.png", "x": 100, "y": 50, "linked": true}} Place and auto-trace: {"params": {"file_path": "C:/img/photo.png", "trace": true, "trace_preset": "6 Colors"}} NOTES:
|
| illustrator_set_referenceA | Set or clear a reference image on a locked background layer for tracing. CONTRACT: readOnly=False, destructive=True, idempotent=True, openWorld=True WHEN TO USE:
KEY CONCEPTS: Places image on a dedicated 'reference' layer at the bottom of the stack. Layer is locked, dimmed, and non-printable to prevent accidental edits. Calling again with the same file replaces the previous reference (idempotent). EXAMPLES: Set a dimmed tracing reference: {"params": {"action": "set", "file_path": "C:/ref/sketch.png", "opacity": 50}} Legacy set (still accepted): {"params": {"file_path": "C:/ref/sketch.png"}} Clear the reference layer: {"params": {"action": "clear"}} NOTES:
|
| illustrator_documentA | Create, open, list, activate, save, or close an Illustrator document. CONTRACT: readOnly=False, destructive=True, idempotent=False, openWorld=True WHEN TO USE:
EXAMPLES: Create: {"params": {"action": "create", "width": 800, "height": 600, "color_mode": "RGB"}} Open: {"params": {"action": "open", "file_path": "C:/art/figure.ai"}} Save under a new name: {"params": {"action": "save", "file_path": "C:/art/figure_v2.ai"}} Close, saving first: {"params": {"action": "close", "save_before_close": true}} NOTES:
|
| illustrator_get_documentA | Get complete document information and structure as a JSON tree. CONTRACT: readOnly=True, destructive=False, idempotent=True, openWorld=False WHEN TO USE:
OPTIONS: scope: 'document' (default), 'app', or 'both' max_items: items per layer, 1-5000 (default 200) max_layers: layers to return, 1-200 (default 50) offset: skip first N items per layer (for paging) layer_name / layer_index: filter to single layer EXAMPLES: Document structure: {"params": {}} Application info, with no document open: {"params": {"scope": "app"}} One layer, paginated: {"params": {"layer_name": "Layer 1", "offset": 200, "max_items": 200}} Symbol definitions and instances, without placing anything: {"params": {"scope": "symbols"}} One symbol, names and counts only: {"params": {"scope": "symbols", "symbol_name": "icon-star", "symbol_contents": false}} NOTES:
|
| illustrator_query_itemsA | Query items using the Task Protocol with declarative target selection. CONTRACT: readOnly=True, destructive=False, idempotent=True, openWorld=False WHEN TO USE:
TARGET SELECTORS: {type: "selection"} — current selection (default) {type: "layer", layer: "Layer 1"} — all items on layer {type: "all", recursive: true} — all items in document {type: "query", itemType: "PathItem", pattern: "axis_*"} — filter by type/name EXAMPLES: Require exactly one matching text label: { "params": { "targets": { "type": "query", "contents": "alpha-helix", "expect": { "count": 1 } } } } Every path whose name starts with axis_: {"params": {"targets": {"type": "query", "itemType": "PathItem", "pattern": "axis_*"}}} Everything on a named layer: {"params": {"targets": {"type": "layer", "layer": "Layer 1"}}} NOTES:
|
| illustrator_preflight_checkA | Perform observational validation on the active document. CONTRACT: readOnly=True, destructive=False, idempotent=True, openWorld=False WHEN TO USE:
KEY CONCEPTS: Checks for: items outside artboard bounds, zero-size items, empty text frames, locked layers/items. Does NOT modify the document. EXAMPLES: Check supplied publication thresholds: { "params": { "publication": { "output_width_mm": 89, "min_font_pt": 5, "min_stroke_pt": 0.25, "min_image_ppi": 300 } } } Check the active artboard before exporting: {"params": {}} Check one artboard, counting any overlap as on-artboard: {"params": {"artboard_index": 0, "policy": "intersects"}} NOTES:
|
| illustrator_path_import_svgA | Import an SVG path d attribute into the active document. CONTRACT: readOnly=False, destructive=False, idempotent=False, openWorld=False WHEN TO USE:
EXAMPLES: A curve: {"params": {"d": "M 10 50 C 20 20, 80 20, 90 50 Z"}} Filled red: {"params": {"d": "M 0 0 L 100 0 L 100 100 Z", "fill": {"r": 255, "g": 0, "b": 0}}} Stroked with no fill: { "params": { "d": "M 0 0 L 50 50 L 100 0", "stroke": { "r": 0, "g": 0, "b": 0, "width": 2 }, "fill": false } } With an explicit id for later targeting: {"params": {"d": "M 0 0 L 100 0 L 100 100 Z", "id": "triangle"}} NOTES:
|
| illustrator_observeA | Capture coordinated visual evidence and precise follow-up handles. CONTRACT: readOnly=False, destructive=False, idempotent=True, openWorld=True WHEN TO USE:
OPTIONS: mode: raw, annotated, or both clip_box: optional targeted crop in artboard-relative screen coordinates max_items: annotation-map cap; omissions are reported explicitly RESULT: Returns image content plus context, timing, annotation map, handle expiry, managed runtime generation, omissions, and preservation verification. EXAMPLES: Compact annotated evidence and handles: {"params": {"mode": "annotated", "detail": "summary", "map_detail": "compact"}} Look at the page and get handles for what is on it: {"params": {"mode": "both"}} Crop to a region, in artboard-relative points: {"params": {"mode": "raw", "clip_box": [0, 0, 200, 120]}} Compare every artboard on one contact sheet: {"params": {"artboards": "all"}} Three specific boards, on a checkerboard: {"params": {"artboards": [0, 2, 5], "background": "checkerboard"}} NOTES:
|
| illustrator_connection_statusA | Report whether Illustrator is reachable, and what to fix if not. CONTRACT: readOnly=True, destructive=False, idempotent=True, openWorld=False WHEN TO USE:
KEY CONCEPTS: Four layers, outermost first: this server's WebSocket listener, the CEP panel's socket, Illustrator itself, and the active document. The first one that is not ok is reported as blockedAt, and the recovery steps address that link only. Layers behind a broken one read 'unknown' rather than being guessed at. OPTIONS: probe=false (default) — instant, reads process-local state only probe=true — also round-trips a tiny read-only script to Illustrator EXAMPLES: Instant report, no host call: {"params": {}} Also confirm Illustrator itself answers: {"params": {"probe": true}} RESULT: data.ready is true only when every layer is up. data.blockedAt names the first broken layer, or is null. data.recovery lists the steps for it. execution reports whether this report was produced, never whether the connection is healthy — a successful report of a dead panel is a success. NOTES:
|
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| operation_catalog_resource | Operation routes and purpose; read detailUri for parameters and examples. |
| extendscript_reference_resource | Static ExtendScript scripting reference (cached by client). |
| library_catalog_resource | Helper library catalog auto-generated from manifest.json. |
| update_linked_items_snippet | JSX snippet for updating all linked items from source files. |
| canonical_result_schema_resource | JSON Schema for the canonical result in ``structuredContent`` (T11). Published as a resource rather than as each tool's MCP ``outputSchema``: in mcp 1.25.0 a tool that returns ``CallToolResult`` — which is how it controls ``isError`` and attaches preview images — cannot also declare an output schema, because FastMCP derives that from the return annotation. Exposing it here keeps the contract discoverable and machine-readable, and every result carries a matching ``schemaVersion``. |
TDQS
Scored across 15 tools
Each tool has a distinct purpose and the descriptions repeatedly cross-reference to prevent misselection (e.g., execute_script vs execute_task, observe vs export). A few name pairs like document/get_document and job_status/connection_status could mislead, but the extensive WHEN TO USE guidance resolves ambiguity.
All tools share the illustrator_ prefix and most follow verb_noun, but there are notable exceptions: illustrator_document, illustrator_history, illustrator_observe (verb only), and the awkward illustrator_path_import_svg invert the expected verb-first order. The mixed patterns are still readable but not fully consistent.
15 tools is an appropriate breadth for an Illustrator control server, covering document lifecycle, shape creation/editing, import/export, observation, validation, and diagnostics. No tool feels redundant, and the count sits comfortably within the ideal range.
The tool set covers core workflows: document management, structured and raw editing, boolean geometry, SVG import, file placement, export, visual observation, querying, preflight checks, history, and connection/job status. Minor gaps exist (e.g., dedicated text editing or layer management tools depend on execute_task or raw script), but most operations are reachable through structured operations.