After Effects MCP · Advanced
Learning loop — the MCP grows with your workflow
AE MCP ships with 220+ tools. As you use it, it journals which JSX snippets you re-run with the same shape — and you (or Claude) can promote those patterns into new MCP tools with proper schemas and parameters, with no rebuild and no After Effects restart. It's a Synthetic-exclusive system that no other Adobe MCP has.
Why it matters
- · Fewer tokens. Claude calls a tool with 2 args instead of generating 30 lines of JSX.
- · Fewer errors. Validated schema, not JSX generated from scratch each time.
- · Learns from real usage. The patterns that get promoted are the ones you actually repeat.
- · 100% reversible. It's a JSON file on your PC. Remove a line and the tool is gone.
How it works
run_jsx_json ─▶ journal.jsonl ─▶ analyze.mjs ─▶ (tú elegís) ─▶ promote.mjs ─▶ wrappers.json
JSX libre cada llamada detecta shapes template tool nuevo
repetidos + JSON vivo al reconectar
params candidatos el cliente MCPFour steps, fully local:
1. Automatic journaling
Every time an MCP client calls a tool, the server appends one line to ~/.synthetic-ae-mcp/journal.jsonl. Calls to run_jsx / run_jsx_json store the full code (these are the candidates); everything else stores just the tool name + arg keys (no payloads). Journaling is best-effort: if the write fails, the tool call still completes normally.
2. Analyze: find recurring patterns
# desde el repo del MCP (clonado o vía npx) node scripts/analyze.mjs # reporte human-readable node scripts/analyze.mjs --json # output JSON para scripting node scripts/analyze.mjs --min 3 # subir el umbral (default 2)
The analyzer normalizes JSX (strips comments, replaces strings and numbers with tokens), groups by signature, and for each shape that recurs ≥2 times reports: how many times it ran, which literal positions vary (those are your params), and a code sample.
3. Promote: create the new tool
Define a JSON spec with name + template + param types. Example: a tool that sets frameRate=X on all comps whose name contains a substring:
{
"name": "ae_set_framerate_batch",
"description": "Set frameRate on all comps whose name contains <pattern>.",
"code": "var n = 0; for (var i = 1; i <= app.project.numItems; i++) { var it = app.project.item(i); if (it instanceof CompItem && it.name.indexOf({{pattern}}) >= 0) { it.frameRate = {{fps}}; n++; } } __write({ ok: true, updated: n });",
"params": [
{ "name": "fps", "type": "number", "required": true, "description": "Target frame rate" },
{ "name": "pattern", "type": "string", "required": false, "default": "", "description": "Substring to match in comp name (empty = all)" }
]
}node scripts/promote.mjs spec.json # OK promoted 'ae_set_framerate_batch' (2 params) -> ~/.synthetic-ae-mcp/wrappers.json # Reconnect the MCP (or restart the client) to see the new tool.
4. Live: the tool shows up in your client
The server reads wrappers.json fresh on every tools/list. Reconnect Claude Desktop / Cursor / Codex and ae_set_framerate_batch(fps, pattern) is available like any native tool, with its full MCP schema. When Claude calls it, the server fills the template and dispatches through run_jsx_json — no architecture change, no rebuild.
Parameter types
| Type | Rendered into JSX as |
|---|---|
| string | JSON-escaped string: "hello" → "hello" |
| number | Numeric literal: 24 → 24 |
| boolean | true / false |
| array | JSON literal: [1,2,3] → [1,2,3] |
| object | JSON literal: {"a":1} → {"a":1} |
| raw | Inserted verbatim (advanced) |
Privacy and security
- · Everything is local:
~/.synthetic-ae-mcp/is a folder on your PC. Nothing is uploaded anywhere. - · The journal records run_jsx[_json] calls with the full code. Other tools log only name + arg keys (no values).
- · To change the folder: set
AE_MCP_DATA_DIRin your MCP config. - · To reset: delete
~/.synthetic-ae-mcp/.