Skip to main content
Glama
README.md
# ae-mcp

An advanced MCP server for Adobe After Effects. It gives an assistant an editor's toolkit:
read a project, create and rig layers, set keyframes with real speed curves, animate text,
build vector shapes, apply effects and expressions, drive native menus — and **see the
result** through snapshots returned right into the conversation.

## Architecture

```
Assistant (MCP)
      │  stdio
┌─────▼──────────────────────────────┐
│  ae-mcp server (Node/TypeScript)   │   easing, SVG, presets, schemas
└─────┬──────────────────────────────┘
      │  1. HTTP 127.0.0.1:9782  (CEP transport, primary)
      │  2. watched JSON files    (ScriptUI transport, fallback)
┌─────▼──────────────────────────────┐
│  bridge inside After Effects       │   CEP panel or ScriptUI panel
└─────┬──────────────────────────────┘
      │  $.evalFile + AEMCP.runFile()
┌─────▼──────────────────────────────┐
│  ExtendScript kernel (AEMCP)       │   ~4,000 lines, 60+ commands
└────────────────────────────────────┘
```

Three principles:

- **Heavy lifting stays in Node.** SVG conversion, easing math, animation presets — all
  prepared server-side; the ExtendScript kernel just executes.
- **Exchanges go through files.** Requests and responses travel as JSON on disk, avoiding
  `evalScript`'s escaping and size limits. HTTP only triggers the run.
- **Everything is atomic.** Each request — even a batch of 50 operations — runs inside a
  single undo group: one `Ctrl+Z` reverts it all.

### Bridge auth token

The CEP panel's HTTP server listens on `127.0.0.1` and triggers commands in After Effects
(including `ae_eval`, which runs arbitrary ExtendScript). To stop a web page open in the
browser while AE is running from driving the bridge via a plain `fetch()`, the panel
generates a random token on first launch, stored in `Documents/ae-mcp/bridge/token.txt` and
republished in `bridge.json` (`token` field). Every `POST /run` or `POST /reload` must carry
the `X-AE-MCP-Token` header; without it the server returns `401`. The MCP client
(`src/bridge/client.ts`) reads the token from `bridge.json` and sends it automatically — no
manual setup needed. The token persists as long as `token.txt` exists; delete it to force
regeneration on the next panel launch.

The fallback file transport (`req/`/`res/`) has no token: it relies on the OS permissions of
the user's `Documents` folder, which already block access from another account.

## Install

```bash
npm install
npm run build
npm run install-bridge      # installs the CEP extension + ScriptUI panel + kernel
```

Then, in After Effects:

- **CEP transport (recommended)** — restart After Effects. The bridge starts on its own, no
  window. `Window > Extensions > AE MCP Bridge` shows status, port, and log.
- **ScriptUI transport (no restart)** — `File > Scripts > Run Script File…`, then pick
  `Documents/ae-mcp/AE MCP Bridge.jsx`. The panel starts polling immediately.

Register the server with your MCP client:

```bash
claude mcp add ae-mcp -- node "/path/to/ae-mcp/build/index.js"
```

> `npm run install-bridge` also copies the panel into `Scripts/ScriptUI Panels` of any
> detected After Effects install, making it dockable. That copy lives under `Program Files`
> and needs admin rights; if it fails, nothing else is affected.

## Tools

| Tool | Role |
|---|---|
| `ae_status` | Bridge state, AE version, project, comps |
| `ae_help` | Docs: property paths, matchNames, easings, shapes, animators |
| `ae_project` | Inventory, import (images, video, PSD/AI as comp), folders, save |
| `ae_comp` | Create, read, adjust, duplicate, precompose, markers |
| `ae_layer` | Every layer type, every attribute, deep read |
| `ae_property` | Read/write any property by path; expressions |
| `ae_keyframes` | Keyframes with named curves, relative values, hold, offset |
| `ae_text` | Text content and formatting, text animators, fonts |
| `ae_shape` | Native vector trees, Bézier paths, **SVG conversion** |
| `ae_effect` | Find, apply, adjust, and animate effects |
| `ae_mask` | Rect/ellipse/Bézier masks, modes, feather |
| `ae_animate` | Ready-made animation presets, staggered sequencing |
| `ae_rig` | Controls, expression links, alignment, parenting, Essential Graphics |
| `ae_render` | **Snapshot returned into the conversation**, render queue |
| `ae_ui` | Native menu commands, playhead, selection |
| `ae_run` | Raw access to every kernel command, batched with references |
| `ae_eval` | Arbitrary ExtendScript (last resort) |

## What sets this apart

**Real speed curves.** `ease: "expo.out"` doesn't just apply *Easy Ease* — the Bézier curve
is converted into per-dimension influence and speed, computed from the segment's average
velocity, exactly like hand-tuning the Graph Editor.

**Relative values.** A `slideIn` uses `mode: "offset"`: the animation builds on the layer's
existing position instead of overwriting it. Same idea for scale with `mode: "multiply"`.

**SVG becomes real shapes.** `ae_shape action=svg` converts `path`, `rect`, `circle`,
`ellipse`, `line`, `polyline`, `polygon`, groups and their transforms into native, editable
shape layers, with fills, strokes, dashes, and arcs approximated in Bézier.

**A visual feedback loop.** `ae_render action=snapshot` renders the comp and returns the
image directly: the assistant compares its output to the reference and corrects, instead of
working blind.

**Atomic batches with references.** A whole scene builds in one round trip, each step able
to reuse the previous one's result via `{{0.index}}` or `{{prev.id}}`.

## Development

```bash
npm run build          # kernel + TypeScript
npm run build:kernel   # kernel only (also checks its syntax)
node scripts/ae.mjs status                       # bridge status
node scripts/ae.mjs layer.list '{"comp":"My Comp"}'
node scripts/selftest.mjs                        # full validation against AE
node scripts/selftest.mjs --keep --only=shape    # subset, keeps the comp
```

The kernel is split into modules under `host/kernel/` and concatenated into
`host/aemcp-kernel.jsx` by `scripts/build-kernel.mjs`. **It must stay ES3-compatible**: no
`let`/`const`, no `Array.prototype.map`, no native `JSON` (a polyfill is provided in the
prelude).

| Folder | Contents |
|---|---|
| `src/` | MCP server: tools, transport, easing, SVG, presets |
| `host/kernel/` | ExtendScript kernel source |
| `cep/` | CEP extension (HTTP panel) |
| `scriptui/` | ScriptUI panel (fallback bridge) |
| `scripts/` | Build, install, diagnostic CLI, tests |

## Troubleshooting

| Symptom | Likely cause |
|---|---|
| `No After Effects bridge detected` | Panel isn't open, or AE is closed. |
| CEP panel missing from the menu | `PlayerDebugMode` not set (rerun `install-bridge`) or AE wasn't restarted. |
| `Kernel not found` | `npm run install-bridge` wasn't rerun after a kernel change. |
| File writes refused | Preferences > Scripts & Expressions > *Allow Scripts to Write Files*. |
| Effect name not found | AE's UI isn't in English: use `matchName` instead (`ae_effect action=list`). |

TDQS

A3.5/5.0

Scored across 17 tools

Disambiguation3/5

Most tools map to distinct After Effects domains (project, comp, layer, property, keyframes, text, shape, mask, effect, rig, render), so an agent can usually tell them apart. However, ae_run explicitly covers everything the other tools do, and ae_property overlaps with ae_effect, ae_shape, and ae_mask for property-level manipulation. The descriptions help by positioning ae_run as low-level kernel access and ae_eval/ae_ui as fallbacks, but the boundaries are not always crystal clear.

Naming Consistency4/5

All tool names share a consistent ae_ prefix and lowercase snake_case style, which gives the set a strong visual and structural identity. The pattern is not uniformly verb_noun—most names are resource nouns like ae_comp or ae_layer, while a few are action verbs like ae_run or ae_render—but this deviation is minor and the naming remains readable and predictable.

Tool Count4/5

At 17 tools, the server sits slightly above the ideal 3-15 range, but After Effects automation genuinely requires coverage across project, composition, layer, properties, keyframes, effects, rendering, and UI control. Each tool covers a substantial functional area, so the count feels justified rather than padded.

Completeness5/5

The tool surface is remarkably complete: it covers project/comp/layer lifecycle, property and expression editing, keyframes and animation presets, text/shape/mask/effect manipulation, rigging, rendering, and even arbitrary menu/script fallbacks. ae_run, ae_ui, and ae_eval seal any remaining gaps, leaving no obvious dead ends for AE automation workflows.

Maintenance

ActivityMaintained
ResponsivenessSyncing