ae-channel MCP Server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ae-channel MCP Server用 ae_system_report 看一下当前工程里有哪些 comp"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ae-channel
让 AI 客户端直接读写你的 After Effects 工程。 一个 CEP 面板(装在 AE 里)+ 一个 MCP 服务器(跑在 Python 里),合起来把 AE 变成一个可被脚本调用的编辑器:建合成、加层、打关键帧、 套预设、渲染、QC、检查点回滚,都能用一条工具调用完成。
中文就是本文件;English:
README.en.md。 108 个工具的完整清单在docs/tool-reference.md, 2026-11-05 之前的工程记录(实测数据、判据、踩坑史)在docs/README-engineering.md。
30 秒判断要不要用
适合你,如果:你在 DSH(或别的 MCP 客户端)里用自然语言驱动 AE ——「把这个 comp 的所有文字层 字号加 4,再导出三帧给我看」。
不适合你,如果:你只想要一个能对话的 AE 面板、或者想在没有 AE 的机器上渲染(面板需要本机 AE;
序列渲染走 aerender,也要求 .aep 已保存到磁盘)。
当前形态:模型通过 108 个 MCP 工具(32 读 + 76 写,命名前缀 mcp__ae__)操作当前 AE 项目。
Related MCP server: ae-mcp
你需要什么
需要 | 说明 |
Windows + Adobe After Effects 2025(25.x) | 面板是 CEP 扩展;工具面按 AE 25.2x131 实测校准 |
Python 3.11+ | 依赖见 |
一个 MCP 客户端 | DSH 最省事;其它客户端只要能配 stdio MCP 就行 |
一个已保存的 | 面板要挂在工程窗口上;序列渲染要求先存盘 |
装依赖(如果不用 DSH 一键装):
python -m pip install -r server\requirements.txt第一部分:用 AE 的人(三步上手)
1. 装面板
powershell -NoProfile -ExecutionPolicy Bypass -File cep\update.ps1脚本把扩展复制到 %APPDATA%\Adobe\CEP\extensions\com.dsh.aechannel,并打开 CEP 的调试签名。
装完必须重启 AE,然后 窗口 > 扩展 > ae-channel。
面板只在有工程打开时出现在工作区里。停在 AE 首页时找不到它,先新建/打开一个工程。 打开面板后正常退出 AE(文件 > 退出,或
app.quit())——用taskkill关掉会让 AE 跳过工作区保存,下次面板可能被藏进锁定的标签页。
2. 让客户端连上
MCP 服务器是本项目里的一个 Python 子进程,DSH 里加一段配置(其它客户端同理):
{
"mcpServers": {
"ae": {
"command": "<python>\\python.exe",
"args": ["C:\\path\\to\\ae-channel\\server\\ae_channel\\__main__.py", "mcp"],
"env": { "DSH_AE_ENABLE_WRITE": "1", "DSH_AE_TOOL_PROFILE": "read" }
}
}
}上面
args的路径换成你这份仓库里server\ae_channel\__main__.py的绝对路径,command换成你的 Python 3.11+。DSH_AE_ENABLE_WRITE=1是写闸:不设它,所有写工具都回writes_disabled。先只读跑通,再开写。DSH_AE_TOOL_PROFILE=read只是建议初学者从这里起步(见下面的「档位」)。
3. 第一次成功
在客户端里依次说:
自检:「跑一下
ae_system_check」→ 应回build …-cep、engineVersion、engineTools。只读一次:「用
ae_system_report看看我现在打开的项目里有哪些 comp」。写一次(确认写闸已开):「用
ae_comp_add建一个 1920×1080 的 comp,名字叫测试」,再 「用ae_layer_add在里面加一个文本层,写上 hello」。
三条都通了,说明面板、桥、MCP、AE 四段链路都是活的。
⚠️ 默认档是
idle,只有 2 个工具(ae_system_profile_set+ae_system_tool_search)。 这是刻意的:一个刚起的会话不该背 108 个工具的声明。第一句话通常是 「ae_system_profile_set(profile="read")」,要写字幕/批次时再放宽到authoring或full。
第二部分:接 MCP 的人
传输与并发
stdio:每个客户端拉一个自己的
python … server\ae_channel\__main__.py mcp进程;面板通过 WebSocket 拨到127.0.0.1:38941(DSH_AE_PORT可改)。一次只能有一路连 AE:第二个进程会发现端口已被占用并拒绝启动,而不是把面板抢走。 要多路并用就换
DSH_AE_PORT,并在 AE 侧用对应端口的面板。
档位(工具暴露面)
档位 | 工具数 | 用途 |
| 2 | 刚开会话,只有两个元工具 |
| 33 | 只读探查:看结构、属性、关键帧 |
| 25 / 6 | 质检与审计场景 |
| 44 | 起步批次 |
| 83 | 日常编辑(不含少数重工具) |
| 108 | 全部:宏、渲染、预览、检查点 |
会话内切换:ae_system_profile_set(profile="read")(默认只影响本会话)。进程级默认:环境变量
DSH_AE_TOOL_PROFILE。
状态与产物(~/.dsh/ae-state,可用 DSH_AE_STATE_ROOT 改)
jobs/ 长任务的作业记录(ae_job_get 读它)
checkpoints/ 检查点(ae_checkpoint_save / restore)
captures/ 预览对比用的 PNG
renders/ aerender 的产物与日志
recovery/ 失败信封的恢复记录(ae_checkpoint_recover 读它)三件常见的工程事
批量:
ae_keyframe_add/ae_layer_set/ae_text_style_set等 22 个工具接受targets=[{layer, …}, …]:一次调用、一个 Undo 组,顶层参数是默认值,坏条目进results[]。渲染:
ae_render_start走外部aerender(要求.aep已保存且工程不脏);单帧预览用ae_render_frame_run(回一张 PNG)。找工具:
ae_system_tool_search(query="keyframe")按名字/描述查;ae_system_tool_report还能 告诉你哪些工具常被连着调用。
工具一览(按任务,不是全表)
我想… | 先看这些 |
看工程 / 找项 / 看层 |
|
建与改结构 |
|
关键帧与缓动 |
|
文字与文本动画 |
|
效果 / 预设 / 图层样式 |
|
渲染与对比 |
|
质检 |
|
批量与复用 | 任一写工具的 |
安全网 |
|
完整签名(参数表 + 每个工具的一行说明)在 docs/tool-reference.md。
五条安全须知
写闸默认关:没有
DSH_AE_ENABLE_WRITE=1,写工具一律writes_disabled(连 dry-run 也一样)。破坏性工具要
confirm=true:删层、删项、修剪合成、覆盖保存、恢复检查点。不给就拒, 并在拒绝里列出会发生什么。回包说三态:
outcome=succeeded/failed/unknown。unknown不是失败——先看recoveryId和ae_job_get,别盲目重试。有命名的陷阱:套缺效果的预设还传
allowMissing=true、回滚一个已经脏了的工程,会先被trap_refused挡下,要你明确acknowledge_trap=true才继续。一次调用 = 一个 Undo 组(批量也一样),但删整个文件夹会带走子树、回滚会清空 Undo 历史—— 这两条的后果写在工具说明里,别靠记忆。
常见问题
「AE bridge is not connected」 AE 没开,或面板没开。检查:AE 里有工程;窗口 > 扩展 > ae-channel 已打开;面板没有显示「断开」。
面板在「窗口 > 扩展」里点了没反应 / 找不到
确认用 cep\update.ps1 -Force 重装过并重启了 AE;面板只在有工程时进入工作区。
「bridge port 127.0.0.1:38941 is already owned」
已经有一路连着 AE(DSH 或别的会话)。关掉那一侧,或给新的一侧换 DSH_AE_PORT。
「我只看到 2 个工具」
默认档是 idle。说「ae_system_profile_set(profile="read")」,或把 DSH_AE_TOOL_PROFILE 设成
read / authoring / full。
「写到一半超时了」
默认等待 35 s(面板轮询窗口 31.5 s 之上)。长任务用 wait_seconds 变成作业,再用 ae_job_get 收结果。
「ae_render_start 说工程是脏的」
aerender 渲的是磁盘上的 .aep。先 ae_system_save(覆盖已有文件要 confirm=true),再渲染。
「ae_layer_style_set(action="apply") 拒绝了」
应用图层样式走的是 AE 菜单命令,且有宿主前提:在「刚启动、从未交互打开过工程」的 AE 上会失败
(实测),先手动打开一次工程、建一个 comp 再试。
「文字/中文乱码」
多半是终端编码,不是数据:回包是 UTF-8 JSON(\u8f89\u5149 = 辉光)。看原始 JSON,不看控制台渲染。
自检与回归
python server\ae_channel\__main__.py client doctor # 不需要 AE:协议 / 工具面 / 写闸 / 端口
python scripts\run_regression.py # 全量离线回归(当前 67 项)doctor 结尾应是 TOOL SURFACE OK, LIVE CHAIN BLOCKED (AE handshake …) 且退出码 0——
它需要 AE 的那一项是 [BLOCKED],不是 FAIL。
给测试者用的冻结包说明在 docs/TEST-KIT.md。
想再深入
文件 | 内容 |
更细的安装 / 首次运行走查 | |
108 个工具的参数与逐条说明 | |
旧版 README:实测数据、判据、踩坑史 | |
交接状态:最近每批改了什么、为什么、还剩什么 | |
已完成 / 未完成的批次与裁定 | |
人拍板过的决定(含出处) | |
架构审查与工具面收口的账 |
许可
本项目的代码是 MIT,见 LICENSE。一个例外写在 THIRD-PARTY.md:cep/extension/js/CSInterface.js 是 Adobe 随 CEP 框架分发的桥接文件(文件头为 All Rights Reserved),按 CEP 扩展的惯例随包携带、头部原样不动,不受本项目 MIT 覆盖;若你需要零第三方文件,删掉它并让使用者从 Adobe 的 CEP 资源自行放回同一路径即可。
Available Tools
2 toolsae_system_profile_setTool profile / phased exposureAIdempotent
Inspect or CHANGE the MCP tool profile (which tools the model is shown).
This is the ONE tool that is visible in EVERY profile, because it is how a
narrow profile is widened again: without it, a session started on idle
could never reach a write tool without a human editing the phase file.
YOU START ON idle (2026-10-29): the default face is exactly this tool plus
ae_system_tool_search - two tools, ~4.8 KB of prompt instead of ~195 KB. That
is deliberate, and one call changes it: profile="read" for the 33 read-only
tools, profile="authoring" for the 83 authoring tools, profile="full" for all
108. Use ae_system_tool_search first if you do not know which profile carries
the tool you want - it searches the ACTIVE face, so widening is what makes its
answers useful.
WHERE THE COST IS. The tool list is re-sent to the model on every request, so it is paid for continuously - which is why the profiles are not cosmetic. The numbers live in docs/tool-description-rationale.md.
THE SWITCH IS NOT INSTANT, AND THAT IS A CONTRACT, NOT A WARNING. The host
only re-reads tools/list after a notifications/tools/list_changed
notification; the measured window is about 75 ms, but the honest instruction
is coarser: the new tool set is usable on your NEXT model turn, never in
this one. Calling a just-exposed tool in the same turn can therefore fail
with unknown_tool -- that refusal text says so, and it is NOT a failed edit.
Likewise a tool that has just been REMOVED can still be offered for one turn
(stale registration) and will be refused the same way.
Switching is a META operation: it is journaled (event tool_profile, with the
exposed names and whether the host was told) but it never dispatches to After
Effects and never needs the write gate.
WHOSE TOOL LIST MOVES: scope="session" (the default) changes THIS
conversation only - the other conversations served by the same process keep
the face they had, and the notification is sent to this session alone.
scope="process" is the old, deliberate meaning: every conversation the server
serves re-syncs on its next request, EXCEPT the ones that set their own
profile, which keep it (a session choice always wins over the process default).
request_id is accepted and NOT forwarded (the tool has no args envelope); the
async wrapper's finish is what makes the key guard it.
| Name | Required | Description | Default |
|---|---|---|---|
| list | No | ||
| scope | No | session | |
| profile | No | ||
| request_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare write/idempotent/non-destructive; the description adds far more that annotations cannot carry — the ~one-turn latency window before a newly exposed tool is callable, that `unknown_tool` on a just-added tool is not a failed edit, that removed tools may linger one turn as stale registrations, and that the switch is journaled but bypasses the write gate and After Effects. Scope blast radius is spelled out per value, including that a session choice wins over the process default.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Sectioned with caps headers and front-loaded with the core switch semantics, which helps scanning. But it is roughly 300 words for a four-param meta tool and carries rhetorical ballast that does not aid invocation ("THAT IS A CONTRACT, NOT A WARNING", "the honest instruction is coarser", the docs pointer for cost numbers), so signal is diluted by emphasis.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, yet the description never says what an inspect/`list` call returns or what the profile-change response looks like, and the `list` param is undocumented. Everything an agent needs to safely perform the switch — timing contract, scope, values, gating — is otherwise complete and unusually thorough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate, and it largely does: `profile` values are enumerated with tool counts, `scope` is given default and full semantics, and `request_id` is explained as accepted-but-not-forwarded. The `list` parameter, however, is never mentioned, leaving one of four params with no meaning anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb pair and resource: "Inspect or CHANGE the MCP tool profile (which tools the model is shown)." It goes further and distinguishes itself from the only sibling by explaining the asymmetry ("This is the ONE tool that is visible in EVERY profile") and its role relative to `ae_system_tool_search`.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit about the starting state (`idle`), the exact values to pass (`read` = 33 tools, `authoring` = 83, `full` = 108), and when to reach for the sibling first ("Use `ae_system_tool_search` first if you do not know which profile carries the tool you want"). It also names the condition that selects `scope="process"` versus the default `session`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ae_system_tool_searchSearch the tool catalogueARead-onlyIdempotent
List or search the tools the ACTIVE profile exposes, at three detail levels.
This is the discovery half of layered exposure (design-layered-tool-exposure
section 3.4 / P3). Narrowing a profile lowers what every model request pays,
but it also means the model cannot see what it is missing - this tool is how
it looks BEFORE widening, instead of guessing a name and getting
unknown_tool.
DETAIL LEVELS, and why the default is the cheapest:
"name"- names only. A profile's names cost a fraction of its definitions, and the definitions are whattools/listpays."summary"- name + the FIRST SENTENCE of the existing description. Derived from the live docstring, never a second hand-written blurb, so it cannot disagree withtools/list."full"- name + the complete definition, the same fieldstools/listreturns, so this is a real substitute inside a narrow profile rather than a paraphrase of one.
IT CANNOT SEARCH PAST THE ACTIVE PROFILE. The candidate set is exactly
profiles.select() for the active profile - the SAME single judgement
tools/list uses, not a second one - so searching under read cannot reveal
a write tool. Switch with ae_system_profile_set first to reach anything else; a
search that could leak a narrower profile's tools would make the profile
meaningless.
query matches a case-insensitive substring of the name OR the description;
family filters on the classification family (profiles.family_of), and the
special value "offline" on the tools that need no After Effects.
limit defaults to 20 and limit=0 means NO limit (the whole catalogue);
the reply always carries matched/returned/truncated, so a caller can tell
a full answer from a cut-off one either way.
Read-only, needs no After Effects, never dispatches to the engine and never needs the write gate - it filters an in-process registry.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | No | ||
| family | No | ||
| detail_level | No | name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnly/idempotent/non-destructive annotations, it discloses that the tool never dispatches to the engine, never needs the write gate, needs no After Effects, and filters an in-process registry. It also describes the reply envelope (`matched`/`returned`/`truncated`) so a caller can detect truncation, and warns that `"full"` is a genuine substitute for `tools/list` rather than a paraphrase.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose and the core constraint, then uses a clear per-detail-level breakdown. However, some material is rationale rather than operational — the internal reference 'design-layered-tool-exposure section 3.4 / P3' and the defensive restatements ('it cannot disagree with tools/list', 'would make the profile meaningless') cost space without changing agent behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter search tool with no output schema and no annotation coverage of parameters, the description covers selection semantics, parameter meaning, the hard scope limit, side-effect profile, and the shape of the return metadata. An agent has everything needed to call it correctly and interpret a truncated result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must carry all parameter meaning — and it does: `query` is a case-insensitive substring of name OR description, `family` filters on classification family with the special value `"offline"`, `limit` defaults to 20 with `limit=0` meaning no limit, and `detail_level` has all three values explained with their cost tradeoffs. This is exactly the compensation the low schema coverage requires, including an implicit enum the schema does not declare.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List or search the tools the ACTIVE profile exposes') plus the scope qualifier 'ACTIVE profile' and the three detail levels. It explicitly distinguishes itself from the sibling by naming `ae_system_profile_set` as the way to reach tools outside the current profile.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit when-to-use ('this tool is how it looks BEFORE widening, instead of guessing a name and getting `unknown_tool`') and an explicit alternative for the excluded case ('Switch with ae_system_profile_set first to reach anything else'). It also articulates the when-not boundary: 'IT CANNOT SEARCH PAST THE ACTIVE PROFILE'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v1.23.0- First observed
ae_system_profile_set - First observed
ae_system_tool_search
TDQS
Scored across 2 tools
One tool changes the exposure profile, the other searches the currently exposed catalogue, so purposes are distinct in principle. There is mild overlap in that `ae_system_profile_set` also 'inspects' the profile while `ae_system_tool_search` lists the active profile's tools, which could cause a model to pick either when it just wants to know what is available.
Both names follow the identical `ae_system_<noun>_<verb>` pattern (`ae_system_profile_set`, `ae_system_tool_search`), with consistent snake_case and shared namespace prefix. No deviations.
Two tools is below the typical 3-15 range, but the thinness is deliberate and justified: this server is a minimal meta control plane whose whole point is to avoid paying for a large prompt. Each tool earns its place, though there is no dedicated read-only 'current profile' introspection tool.
The pair covers the full widen-inspect-switch loop: search at three detail levels, switch profile with session/process scope, and switch back. Minor gaps exist — no explicit tool to enumerate all available profile names or to read the current profile state without invoking the setter.
Maintenance
Related MCP Connectors
LLM chat, text tools, image generation, editing, batch image jobs, and asynchronous video generation
214 tools for AI agents over one MCP endpoint: image, video, audio, 3D, data, storage, mail, GPUs.
AI video editor for agents and humans: timeline, captions, color, audio and generation as MCP tools.
AI editor to build, animate & export layered short-form video projects via one tool catalog.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceEnables AI agents to control Adobe After Effects to create videos programmatically, with commands for comps, layers, effects, and rendering.6 npm26MIT
- AlicenseAqualityBmaintenanceEnables AI assistants to operate Adobe After Effects with the dexterity of an editor: reading projects, creating and rigging layers, setting real velocity curves, animating text, building native SVG-based shapes, applying effects, expressions, masks, and viewing render snapshots to verify results.176 npm1MIT
- AlicenseAqualityAmaintenanceEnables AI agents to inspect and control a live Adobe After Effects session, including reading active composition and layer data and evaluating arbitrary ExtendScript.4MIT
- AlicenseAqualityBmaintenanceLets AI agents drive a running Adobe After Effects (~270 undo-safe operations). Works with every UI language Adobe ships and sees the frame: draws Object Matte on what it sees (lassos, ⊕/⊖ points, a preview of gaps and people) and syncs AI-generated layers with the plate frame by frame. A large skills library, built for AI and generative features: Roto Brush, Object Matte, Content-Aware Fill.413269 npm3Apache 2.0