mcp-ae
# MCP After Effects
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that lets Claude (or any MCP client) control **Adobe After Effects** via natural language.
## How It Works
```
Claude ──MCP──► mcp-after-effects ──ExtendScript──► Adobe After Effects
```
The server bridges Claude to AE using one of three mechanisms (selected automatically based on your OS):
| Mode | OS | Mechanism |
|------|----|-----------|
| `applescript` | macOS | `osascript` → AE's `DoScript` |
| `com` | Windows | VBScript COM automation |
| `aerender` | Any | AE command-line renderer (`aerender`) |
---
## Prerequisites
- **Node.js** ≥ 18
- **Adobe After Effects** (any recent version — CC 2019+)
- After Effects must be **open** for `applescript`/`com` modes, or `aerender` must be on your PATH for `aerender` mode
---
## Installation
```bash
npm install
npm run build
```
---
## Configuration
### Claude Desktop (`claude_desktop_config.json`)
```json
{
"mcpServers": {
"after-effects": {
"command": "node",
"args": ["/absolute/path/to/mcp-ae/dist/index.js"],
"env": {
"AE_BRIDGE_MODE": "auto"
}
}
}
}
```
### Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `AE_BRIDGE_MODE` | `auto` | Bridge mode: `auto`, `applescript`, `com`, or `aerender` |
| `AE_RENDER_PATH` | (OS default) | Full path to `aerender` binary when using `aerender` mode |
### aerender Paths (defaults)
- **macOS**: `/Applications/Adobe After Effects 2024/aerender`
- **Windows**: `C:\Program Files\Adobe\Adobe After Effects 2024\Support Files\aerender.exe`
---
## Available MCP Tools
### Project & Composition
| Tool | Description |
|------|-------------|
| `ae_get_project_info` | Get info about the open project |
| `ae_list_compositions` | List all compositions |
| `ae_get_composition_layers` | List all layers in a composition |
| `ae_create_composition` | Create a new composition |
### Layers
| Tool | Description |
|------|-------------|
| `ae_add_text_layer` | Add a text layer |
| `ae_add_solid_layer` | Add a solid color layer |
| `ae_add_null_layer` | Add a null/control layer |
| `ae_import_file` | Import a file (video, image, audio, AEP) |
### Animation
| Tool | Description |
|------|-------------|
| `ae_set_layer_property` | Set a layer property value (with or without keyframe) |
| `ae_add_keyframe` | Add a keyframe to a layer property |
| `ae_apply_effect` | Apply an effect to a layer by match name |
### Render & Save
| Tool | Description |
|------|-------------|
| `ae_add_to_render_queue` | Add a composition to the render queue |
| `ae_start_render` | Start rendering all queued items |
| `ae_save_project` | Save the current project |
### Advanced
| Tool | Description |
|------|-------------|
| `ae_run_script` | Execute raw ExtendScript in After Effects |
---
## Example Prompts
Once connected to Claude, you can say things like:
- *"List all compositions in my After Effects project"*
- *"Create a 1920×1080 composition called 'Intro' at 24fps, 5 seconds long"*
- *"Add a white text layer saying 'Hello World' at 72px font size, centered"*
- *"Set the opacity of layer 'Title' to 0 at t=0 and 100 at t=1 second"*
- *"Apply a Gaussian Blur to the background layer"*
- *"Add the 'Main' composition to the render queue and save to /tmp/output.mp4"*
- *"Run this ExtendScript: `app.project.activeItem.name`"*
---
## Property Paths
Use dot notation for nested properties with `ae_set_layer_property` and `ae_add_keyframe`:
```
Transform.Position → [x, y]
Transform.Scale → [x, y] (percentage, e.g. [100, 100])
Transform.Rotation → degrees
Transform.Opacity → 0-100
Transform.Anchor Point → [x, y]
```
---
## Common Effect Match Names
| Effect | Match Name |
|--------|-----------|
| Gaussian Blur | `ADBE Gaussian Blur 2` |
| Drop Shadow | `ADBE Drop Shadow` |
| Glow | `ADBE Glo2` |
| Hue/Saturation | `ADBE HUE SATURATION` |
| Levels | `ADBE Levels2` |
| Fractal Noise | `ADBE Fractal Noise` |
| Linear Wipe | `ADBE Linear Wipe` |
| Fill | `ADBE Fill` |
Find all match names by running: `ae_run_script` with:
```javascript
var e = app.effects;
var r = [];
for (var i=0; i<e.length; i++) r.push(e[i].matchName);
return r.join("\n");
```
---
## Development
```bash
npm run dev # Run with tsx (no build step)
npm run build # Compile TypeScript → dist/
npm run watch # Watch mode
```
---
## Architecture
```
src/
├── index.ts # MCP server, tool definitions
├── ae-bridge.ts # OS-level AE communication
└── scripts/
└── common-effects.ts # Effect names & property path constants
```
TDQS
Scored across 72 tools
Most tools map cleanly to a distinct resource and action, and descriptions clarify cardinality such as single versus batch. However, the rendering/queue family has some overlapping paths—ae_add_to_render_queue, ae_batch_render, ae_export_frames, ae_start_render, and ae_render_headless—that could lead an agent to choose the wrong operation.
All tools share the ae_ prefix and follow a consistent snake_case verb_noun pattern. The get/list distinction is used predictably, and batch variants are uniformly marked with batch_, making the naming scheme highly predictable.
72 tools is an extreme count for an MCP server. Many are micro-tools such as individual layer toggles, keyframe helpers, and batch wrappers that could be consolidated into fewer parameterized actions without losing clarity.
The tool surface covers project, composition, layer, keyframe, effect application, import, and render-queue workflows with no major dead ends. Minor gaps remain, such as no effect parameter editing, no text content modification, and no mask or track-matte operations.