{
  "markdown": "**English** · [Español](README.es.md)\n\n# mograph\n\n<!-- mcp-name: io.github.VicThor-wpp/mograph-mcp -->\n\n[![PyPI](https://img.shields.io/pypi/v/mograph-mcp)](https://pypi.org/project/mograph-mcp/)\n[![Python](https://img.shields.io/pypi/pyversions/mograph-mcp)](https://pypi.org/project/mograph-mcp/)\n[![Licence](https://img.shields.io/badge/licence-Apache--2.0-blue)](LICENSE)\n[![MCP](https://img.shields.io/badge/MCP-2026--07--28-6f42c1)](https://modelcontextprotocol.io)\n\n**An MCP server that drives Adobe Illustrator and After Effects, and moves\nartwork between them as editable shape layers.**\n\n![The artwork animating in After Effects: letters rising in sequence, bars wiping open, the badge blooming with overshoot](https://gitlab.com/vic-lab/mograph-mcp/-/raw/main/docs/animation.gif)\n\n*Nothing above was drawn by hand. The artwork was built in Illustrator, moved\ninto After Effects with `ai_to_ae_push`, animated with `ae_animate` — the\nletters rise in sequence, the bars wipe open from their left edge, the badge\novershoots and settles — and rendered with `ae_aerender`. Every step is a tool\ncall in this server.*\n\nPoint an AI agent at a storyboard and it can read the artwork, clean it up,\ntransfer a frame into After Effects as real shape layers — bezier curves,\nstrokes, gradients, the group hierarchy rebuilt as parented nulls — animate it,\nand then render both sides to tell you how far apart they are.\n\n> **Not affiliated with Adobe.** \"Adobe\", \"Illustrator\" and \"After Effects\" are\n> trademarks of Adobe Inc. This is an independent project that automates\n> applications you already own, through Adobe's own scripting interfaces.\n\n---\n\n## What it looks like in use\n\nYou talk to your agent; it calls the tools. A session usually goes:\n\n```text\nYou:   Look at the open Illustrator document and tell me what's in frame 3.\n       → ai_see_document returns the render inline, ai_frame_tree the structure\n\nYou:   That price list should be six groups, not 40 loose paths. Fix it.\n       → ai_cluster_items proposes, you approve, ai_apply_clusters applies\n\nYou:   Push frame 3 into After Effects, skip the subtitles.\n       → ai_to_ae_push rebuilds it as shape layers, roles labelled\n\nYou:   Animate the rows in, staggered from the bottom.\n       → ae_set_anchors, then ae_animate with anticipation and settle\n\nYou:   How close is it to the original?\n       → ai_to_ae_verify renders both and answers with a number\n```\n\nFour of those sequences ship as MCP **Prompts**, so a client can offer them as\na starting point rather than making you remember the order.\n\n## Status\n\n| | Windows | macOS |\n|---|---|---|\n| Illustrator (`ai_*`) | ✅ tested end to end (COM) | ⚠️ implemented, **never run** (osascript) |\n| After Effects (`ae_*`) | ✅ tested (CEP + WebSocket) | ⚠️ should work — CEP is cross-platform — but untested |\n| Illustrator → After Effects (`ai_to_ae_*`) | ✅ tested against real client files | ⚠️ untested |\n| Unit tests | ✅ | ✅ (no Adobe needed, run anywhere) |\n\nVerified against **Illustrator 2026 (30.x)** and **After Effects 2026** on\nWindows 11. Older releases are likely to work — the panel declares After Effects\n16.0 and up, and the Illustrator side uses long-standing ExtendScript — but they\nhave not been run, so treat that as unverified rather than supported.\n\n**macOS is written and has never been run.** That is not a soft \"should be\nfine\". The known risks are itemised in [`AGENTS.md`](AGENTS.md).\n\n**Protocol:** MCP revision **2026-07-28** on the official Python SDK 2.x\n(`mcp>=2,<3`). Transport is stdio only — this drives desktop applications, so it\nis bound to one machine by design.\n\n---\n\n## Install\n\nRequires Python 3.10+ and the Adobe applications you intend to drive.\n\n```bash\npip install mograph-mcp\nmograph-mcp register codex     # or: claude, zcode\nmograph-mcp doctor             # what this machine can and cannot do\n```\n\n`register --print` shows the config instead of writing it, for a client that is\nnot one of the three. For Claude Code, `claude mcp add mograph -- mograph-mcp`\nworks directly.\n\nWhatever route you take, the entry needs a **generous per-tool timeout**. After\nEffects takes 20–40 seconds to answer the first script of a cold session, and a\nclient that gives up at its own default aborts while the server is still\nworking — which reads as a hang rather than as a slow first call. `register`\nsets it where the client supports it.\n\nIllustrator needs nothing else. After Effects needs the panel below.\n\n## Update\n\n```bash\npip install -U mograph-mcp\n```\n\nThree things make an update look like it did not happen, and all three are\nquiet:\n\n1. **The running server still has the old code.** The process your client\n   started is alive with the previous version in memory, and `dev_reload` does\n   not help — the tool list is handed to the client once, at connect. Restart\n   the client, or kill `mograph-mcp` and let it relaunch. A new tool that does\n   not appear is almost always this.\n2. **Update the environment the CLIENT launches, which may not be the one on\n   your PATH.** Read the `command` in the MCP entry: if it points at a venv,\n   `pip` has to run from that venv's Python. Upgrading the wrong one leaves\n   everything looking correct and changes nothing.\n3. **`uvx` caches.** `uvx mograph-mcp` keeps serving the version it cached the\n   first time; `uvx mograph-mcp@latest` gets the new one.\n\n`mograph-mcp doctor` prints the version it is actually running, which is the\nfastest way to tell an update that landed from one that did not.\n\n**If a release changes the CEP panel, reinstall it and restart After Effects.**\nReinstalling is not enough on its own: AE holds the old JavaScript in memory,\nkeeps connecting with it, and the server refuses the stale panel — which from\nthe outside looks exactly like the panel never being open. `CHANGELOG.md` says\nwhen a release touches the panel.\n\n## After Effects: the panel\n\nAfter Effects has no COM interface, so this reaches it through a small CEP\nextension that runs inside the application and connects back to the server over\na local WebSocket. Two ways to install it, and the difference is worth a moment.\n\n### Signed package — recommended\n\nDownload `mograph-bridge.zxp` from\n[Releases](https://gitlab.com/vic-lab/mograph-mcp/-/releases):\n\n```bash\nmograph-mcp install-panel --zxp mograph-bridge.zxp\n```\n\nIt loads with `PlayerDebugMode` off, so nothing about your Adobe installation\nchanges. The command hands the package to Adobe's own installer\n(`UnifiedPluginInstallerAgent`, which ships with Creative Cloud, or `ExManCmd`).\nUseful flags: `--print` shows the command without running it, `--installer\n<path>` points at a tool in an unusual place, `--list` asks Adobe what it\nbelieves is installed.\n\nThe certificate is self-signed, so the installer reports an unverified\npublisher. That is accurate — a certificate from a public authority costs money\nand buys nothing here except an Adobe Exchange listing. Build your own with\n`python scripts/sign_panel.py` if you would rather not trust this one, or use\n[ZXPInstaller](https://zxpinstaller.com/) to install the same file by hand.\n\n### Folder copy — for development\n\n```bash\nmograph-mcp install-panel\n```\n\nFaster, and what you want while changing the panel itself. Adobe treats a copied\nfolder as unsigned, **so this enables `PlayerDebugMode`** — a setting that lets\nCEP load unsigned extensions, *all* of them and not just this one, and that\nstays on after the panel is removed. It lowers a defence in your Adobe\ninstallation, so it is worth doing on purpose rather than by default.\n\n### Either way\n\nRestart After Effects and open **Window → Extensions → mograph bridge**. It\nshould say *\"Connected and authenticated\"* once your MCP client has started the\nserver.\n\nSkipping the panel is fine — everything on the Illustrator side works without\nit. Details, the manual install and what each disconnect code means are in\n[`docs/panel.md`](docs/panel.md).\n\n---\n\n## What it can do\n\nThe authoritative list is whatever the server returns from `tools/list`. By\nfamily:\n\n**Illustrator (`ai_*`, 57 tools).** Documents, layers and items; export.\nInspection and triage of a delivered file (`ai_inspect_document`,\n`ai_audit_for_animation`, `ai_audit_structure`). **Grouping derived from\ngeometry**, for when a file's hierarchy does not match what the eye reads as one\nthing (`ai_cluster_items` + `ai_apply_clusters`). Naming that survives the trip\n(`ai_auto_name_items`, `ai_propagate_names`). Reading frames and comparing them\n(`ai_frame_tree`, `ai_diff_frames`, `ai_track_frames`). Layout and reframing.\n\n**After Effects (`ae_*`, 66 tools).** Projects, comps, layers; effects and\nexpressions; keyframes, easing and interpolation. **`ae_animate`** writes\nentrances and exits with anticipation, overshoot and settle — the parts that are\nnot in a storyboard and are what stop an interpolation looking dead.\n**`ae_stagger`** orders layers by where they *actually* are in the comp, walking\nthe parent chain. Anchors and parenting, render queue, and headless rendering\nwith `ae_aerender` (`wait=False` returns a handle instead of holding the call\nopen; `ae_render_status` polls it).\n\n**Between them (`ai_to_ae_*`, 2 tools).** `ai_to_ae_push` and `ai_to_ae_verify`.\n\n![The same artwork in Illustrator and in After Effects, side by side, measured at 0.05 percent divergence](https://gitlab.com/vic-lab/mograph-mcp/-/raw/main/docs/header.png)\n\n*The right-hand panel is what After Effects returned after the push; the 0.05%\nis what `ai_to_ae_verify` measured between the two renders. The layer names\ntravelled because the source had named groups — that is the whole difference.*\n\nThe coordinate maths — the Y flip, artboard-to-comp scaling, bezier handles to\ntangents, gradient endpoints — lives in `mapping.py` as pure functions with unit\ntests, so it is verifiable without either application.\n\n### Renders come back as images\n\n`ai_see_document`, `ae_see_frame` and `ai_contact_sheet` return the PNG inline,\nnot just a path on disk. A path only works if the client happens to have\nfilesystem access and happens to think of reading it, and the protocol promises\nneither — a poor foundation for the tools everything else is verified with.\n\nImages are downscaled to `max_dim=1024` on the long side by default; the file\npath is still in the reply, and `max_dim=0` returns the path alone.\n\n### Field notes are served on demand\n\nMany tools carry substantial notes — the traps, why each default is what it is,\nwhat breaks. Loading all of that into every session would cost thousands of\ntokens before the first question, so `tools/list` carries what a tool does and\nwhen to use it, and the rest is fetched only if you want it:\n\n- `docs://guia` — which tools have extended notes\n- `docs://tools/<name>` — the full notes for one\n\n### Three recipes to start from\n\nThe tool list says what each tool does. It cannot say which one comes next, and\nthe order is where the costly mistakes live — grouping before looking, pushing\nevery frame instead of the last, parenting before anchoring. Those sequences are\nMCP Prompts:\n\n- **Prepare a delivered Illustrator file** — inspect, clean and group before\n  animating anything\n- **Turn a storyboard into motion** — a run of frames to keyframes\n- **Push artwork to After Effects and verify it** — the transfer, and the part\n  people skip\n- **Review an animation you just built** — look at it, measure what you see,\n  and fix what a verify score cannot show\n\n---\n\n## Configuration\n\nThe full tool set is ~18,500 tokens of `tools/list`, paid at connect time. A\nsession that will only touch one application does not need the other half:\n\n```bash\nMOGRAPH_TOOLS=ai            # Illustrator only  -> 57 tools, ~9,000 tokens\nMOGRAPH_TOOLS=ae            # After Effects only\nMOGRAPH_TOOLS=ai,symbiosis  # Illustrator plus the transfer\nMOGRAPH_TOOLS=all           # everything (default)\n```\n\nAn invalid name is a startup error rather than an empty server: exposing zero\ntools looks exactly like a broken installation.\n\nEvery tool ships `annotations` and a readable title, so a client can\nauto-approve reads and ask only about mutations. Failures arrive as protocol\nerrors, not as successful calls with a failure buried in the body.\n\n| Variable | Default | What it does |\n|---|---|---|\n| `MOGRAPH_WORKSPACE` | `~/mograph` | Where files land. A root declared by the client wins over it |\n| `MOGRAPH_TOOLS` | `all` | Which tool families to expose |\n| `MOGRAPH_WS_PORT` | `9123` | Bridge port; must match the panel |\n| `MOGRAPH_ALLOW_RAW_SCRIPT` | `1` | `0` drops `ai_run_script` and `ae_run_script` |\n| `MOGRAPH_PORT_TAKEOVER` | `0` | `1` kills whatever holds the bridge port |\n| `MOGRAPH_BRIDGE_AUTH` | `1` | `0` accepts an unauthenticated panel — **unsafe** |\n| `MOGRAPH_AI_APPNAME` | `Adobe Illustrator` | macOS only, if the app name differs |\n\n## Security\n\n**Local only, the bridge is authenticated, and two tools can run arbitrary\ncode.** The server mints a token per run, writes it where only a local process\ncan read it, and refuses both a second panel connection and any browser-origin\nhandshake. The full threat model is in [`SECURITY.md`](SECURITY.md).\n\n---\n\n## Known limitations\n\n- **Gradients keep their geometry and lose their middle stops.** Measured: a\n  two-stop gradient, linear or radial, arrives with a mean channel error of\n  0.2/255 — angle, extent and centre exact. A three-stop one arrives at\n  19.8/255, because only the first and last colours survive. After Effects does\n  not expose a shape layer's multi-stop gradient to scripting at all, so this is\n  a limit of the host. The push reports every gradient it flattened and names\n  the colours it dropped. Patterns, brushes and mesh objects are skipped with a\n  warning.\n- **After Effects' first call of a session** takes 20–40s; the bridge waits 60s\n  (`MOGRAPH_EVAL_TIMEOUT`).\n- **One panel at a time**, by design — a second connection is refused rather\n  than silently displacing the first.\n- **No live feedback.** Nothing reacts to events in the applications; every\n  exchange starts from a tool call.\n- **macOS is untested.** See the table above.\n\n## Troubleshooting\n\n**The AE tools say no panel is connected.** Open After Effects and the `mograph\nbridge` panel. Code `4401` means After Effects is still running the old\n`main.js` from memory — restart it. `4409` means another server already holds a\npanel. `mograph-mcp doctor` names which panels are installed, which port each\ndials, and whether a session token is present.\n\n**The bridge port is busy.** The error names the PID holding it. Stop that\nprocess, or set `MOGRAPH_PORT_TAKEOVER=1`.\n\n**Illustrator does not connect.** On Windows, COM launches it. On macOS, if\nseveral versions are installed and it picks the wrong one, set\n`MOGRAPH_AI_APPNAME=\"Adobe Illustrator 2026\"`. Error `-1743` is the Automation\npermission prompt: approve it in System Settings → Privacy & Security →\nAutomation.\n\n**Shapes land in the wrong place after a push.** The mapping scales the artboard\nonto the comp; if their aspect ratios differ, it distorts. Use a comp the same\nsize as the artboard.\n\n**A gradient lost a colour.** See *Known limitations*. Check `degraded` in the\npush reply, which names each flattened layer and the colours it dropped.\n\n---\n\n## Development\n\n```bash\npython -m pip install -e \".[dev]\"\npython -m pytest tests/ -q        # no Adobe required\npython -m ruff check .\n```\n\nWith both applications open and the panel connected:\n\n```bash\npython scripts/smoke_fidelity_ai.py   # Illustrator only, does not touch the bridge port\npython scripts/smoke_fidelity_ae.py   # round trip, reads bezier + stroke back out of AE\npython scripts/smoke_gradient.py      # gradient round trip, axis included\npython scripts/smoke_stroke.py        # dashes, draw-on, and the shape of the ease\n```\n\n`dev_reload` swaps backend code in place without restarting the client, which\ncovers most of the debugging loop. It cannot add or rename a tool — the list is\nhanded to the client once, at connect time.\n\n[`CONTRIBUTING.md`](CONTRIBUTING.md) has the ground rules,\n[`AGENTS.md`](AGENTS.md) the accumulated field notes about how these two\napplications actually behave, [`CHANGELOG.md`](CHANGELOG.md) what changed in\neach version, and [`ROADMAP.md`](ROADMAP.md) what is known to be left.\n\n## Licence\n\n[Apache-2.0](LICENSE). \"Adobe\", \"Illustrator\" and \"After Effects\" are trademarks\nof Adobe Inc.; this project is not affiliated with them and ships no Adobe code.\nSee [`NOTICE`](NOTICE).",
  "bytes": 16445,
  "sha": "477f90c5639d3d11fe62f313fbb2620d4dca1b232339e996edeae3437e8420ab",
  "repo_slug": "",
  "fonte": "pypi",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_victhor_wpp_mograph_mcp_9a1e5117/readme"
}