Illustrator Figure MCP
by ymo6
README.md
<div align="center">
# Illustrator Figure MCP
**Rebuild scientific figures as editable Adobe Illustrator artwork — and prove the result is structurally correct.**
[](https://github.com/ymo6/illustrator-figure-mcp/actions/workflows/ci.yml)
[](LICENSE)



</div>

<div align="center">
<sub>Rebuilt from a reference image as <b>124 editable objects</b> — every band, box, label and arrow a live object. No tracing, no rasters.</sub>
</div>
---
## Why this exists
Plenty of MCP servers can draw in Illustrator. They give a model hands but no eyes: nothing checks whether the thing it just drew is *right*. So the model draws, reports success, and the figure has a label overflowing its box, an arrow ending in the middle of an unrelated rectangle, and three "aligned" panels that are 3pt out.
The valuable part isn't the drawing. It's the **validate-and-repair loop**, on two channels that check different things:
| Channel | Mechanism | What it proves |
|---|---|---|
| **Geometry** | `audit_figure` — deterministic, read-only | Internal correctness: containment, degenerate sizes, duplicate names, overset text, raster declarations, connector routing and bindings, series alignment, trace signatures |
| **Appearance** | `export` to PNG, compared against the reference | Resemblance |
Geometry is *proved*. Similarity is *judged*. Neither alone is enough — a traced figure passes every geometric check while being completely non-editable, and a good-looking render says nothing about structure.
> `audit_figure` returning `passed: true` means **no hard geometric failure**. It does not mean the figure is correct.
## Quick start
Requires **macOS**, Adobe Illustrator (running), Node 20+, and Claude Code.
```bash
npm install && npm run build
claude mcp add illustrator-figure -- node "$PWD/dist/index.js"
cp -R skills/* ~/.claude/skills/
```
Grant Automation permission at the first prompt, or via **System Settings → Privacy & Security → Automation**. Then ask Claude to *"recreate this figure in Illustrator"* with a reference image attached.
**[→ Full usage guide](docs/USAGE.md)** — every tool, two worked examples, and how to read an audit report.
## It works on real figures
The schematic above was rebuilt from a reference image: 124 objects, 17 connectors bound to their boxes, 0 rasters. The audit flagged 11 arrows crossing panel titles — *which were in the original figure too*, so it found a legibility bug in the source.
**[→ See it rebuilt pass by pass](docs/WALKTHROUGH.md)**, with the audit output at every step — including the pass where the deterministic audit was silent and only the rendered image caught the problem.
Charts work the same way, except the geometry is computed from data rather than traced:

<div align="center">
<sub><b>40 objects.</b> Histogram bars, both density curves, the shaded tail, the axis and the legend are all live objects. Bars named <code>bar-1…bar-17</code> audit clean even though their heights differ, because the series check accepts any shared edge — columns share a baseline, not their tops.</sub>
</div>
## Reconstruct, never trace
Tracing preserves appearance and destroys semantics, which is the whole point of rebuilding a figure. Three defences make the shortcut hard to take:
- **Semantic tagging at creation.** Every object gets a UUID and a semantic type as it is made, so the auditor can tell constructed objects from foreign geometry.
- **`trace-signature`.** Image Trace's `expandTracing()` drops one untagged group holding a pile of untagged paths. That, dense untagged paths, and bulk geometry exceeding the declared draw log are all hard failures.
- **The raster gate.** `place_image` refuses any placement that isn't provably irreducible.
<details>
<summary><b>The raster gate — five declarations, all validated</b></summary>
<br>
| Declaration | Requirement |
|---|---|
| `raster_reason` | Specific description of the irreducible pixel content. "image", "PNG", "screenshot" are rejected as vacuous |
| `source_is_tightly_cropped` | `true` — every border, label, arrow, legend, axis, and neighbouring panel cropped away |
| `atomic_raster_unit` | `true` — one indivisible datum, not a grid or montage |
| `contains_reconstructable_content` | `false` — nothing left inside that should be an editable object |
| `decomposition_note` | ≥ 8 chars: what was split out and rebuilt |
A missing boolean is a failure, not a `false` — silence is not a declaration. Enforcement is on the creation path, not in the auditor: an auditor-only check is bypassed by simply not auditing.
</details>
## Connectors don't follow their objects
Illustrator has no connector primitive. An arrow is a `PathItem` with no relationship to the box it points at — move the box and the arrow stays put, silently wrong.
`add_connector` records the binding (source, target, attachment sites) on the path. `reflow_connectors` re-solves the geometry from the objects' current bounds. `audit_figure` reports `connector-detached` when the drawn path no longer agrees with its binding.
**Any operation that moves or resizes a connected object must be followed by `reflow_connectors`.**
Routing is `straight`, `orthogonal`, or `curved` — a bezier that leaves and arrives perpendicular to the attachment edges, the standard pathway-diagram look. The auditor samples the actual curve rather than the chord between anchors, so it checks where the ink is. Arrowheads are drawn as filled triangles, since Illustrator exposes no arrowhead property to scripting.
## Tools added by this fork
| Tool | Purpose |
|---|---|
| `audit_figure` | Deterministic structure audit; every finding carries evidence, a correction, and an acceptance criterion |
| `draw_sequence` | Build a whole region in one round trip, optionally auditing in the same call |
| `add_connector` | Create a connector bound to two objects by name |
| `reflow_connectors` | Re-solve connector geometry after objects move |
| `fit_text` | Resolve overset area text — resizing the frame with `modify_object` does **not** reflow it |
Plus the raster gate on `place_image` and semantic tagging on every `create_*` tool. The remaining 66 tools are upstream's.
`draw_sequence` is the one to reach for: nine objects — boxes, area-text labels, two bound connectors — build and audit in roughly 750 ms, where one call per object would be nine round trips.
## The four roles
Ask for a figure and `recreate-scientific-figure` coordinates the loop:
| Skill | Role |
|---|---|
| `design-scientific-figure` | **Designer** — the reconstruction spec, before anything is drawn |
| `recreate-scientific-figure` | **Drawer + orchestrator** — a region per round trip, runs the gates |
| `audit-scientific-figure` | **Reviewer** — reads both channels, issues findings |
| `correct-scientific-figure` | **Corrector** — findings into ordered, object-level operations |
Each region must pass before the next begins; then the whole figure runs the same loop.
## Documentation
| | |
|---|---|
| [docs/USAGE.md](docs/USAGE.md) | Install, rules, every tool, worked examples, all audit findings, troubleshooting |
| [docs/WALKTHROUGH.md](docs/WALKTHROUGH.md) | One real figure rebuilt pass by pass, with the audit output at each step |
| [CLAUDE.md](CLAUDE.md) | Internals and the constraints that are easy to break, for anyone editing this repo |
| [skills/](skills) | The four role skills |
## Development
```bash
npm test # 260 tests, any platform
```
The ported geometry is pure ES3, so the `.jsx` modules are loaded into a VM and the Liang–Barsky and segment-crossing maths is tested without Illustrator. Anything touching Illustrator must be tested on macOS with it running — see [CLAUDE.md](CLAUDE.md) for the constraints that bite (ES3, UUID-before-metadata ordering, `pageItems` snapshotting).
## Credits
- Tool layer forked from **[ie3jp/illustrator-mcp-server](https://github.com/ie3jp/illustrator-mcp-server)** (MIT) — transport, JSX runner, UUID identity, `note` metadata, and 66 Illustrator tools. See [LICENSE](LICENSE).
- The two-channel validation loop, the audit taxonomy, and the four-role protocol are ported from **[icebird1998/scientific-illustrator](https://github.com/icebird1998/scientific-illustrator)**, which implements them for draw.io, PowerPoint, and WPS. The maths is backend-neutral; the object model is not.
Not affiliated with Adobe.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues