Communitygithub.com

ivdezine/edits-video

驱动 Meta 的 Edits 视频编辑器(macOS 应用,MCP 服务器“metapilot-native”,工具命名为 mcp__metapilot-native__*)来打开项目、剪切、修剪、按节拍或镜头分割、重新构图、添加文本、字幕、滤镜、特效、转场、LUT、速度曲线和音乐、标准化音频、检查帧以及导出。当用户提到 Edits、Edits 应用、metapilot 或 metapilot-native,或要求使用 Edits 编辑、剪切、添加字幕、重新构图、调色或导出视频时,请使用本技能。

edits-video 是什么?

这是一个用于在 macOS 上通过 MCP 协议驱动 Meta 的 Edits 视频编辑器的 AI 代理技能。当 Edits 应用运行时,它会暴露一个 MCP 服务器(metapilot-native),允许 AI 代理(如 Claude Code)以编程方式调用其所有视频编辑功能。该技能涵盖了从项目创建、媒体导入、剪切修剪、按节拍或镜头分割、画幅比调整、添加文本和字幕、应用滤镜和 LUT、到音视频特效、转场、速度曲线、音量标准化、音频替换以及最终导出的完整工作流。核心文档详细说明了 274 个编辑器工具和 30 个主页工具,并提供了处理常见故障(如服务器无法连接、屏幕状态错误、工具列表过期)的明确指南,以及关于单位系统、参数验证、媒体路径限制(需在 ~/Movies 目录下)和导出设置等关键规则的说明。AI 代理可以仅通过观察应用实时状态和执行单次原子操作来完成复杂的视频编辑任务,同时文档强烈建议避免重复执行非幂等的构建脚本,以防止编辑历史堆叠。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ivdezine/edits-video-skill/tree/HEAD

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

通过 metapilot-native 进行 Edits 视频编辑

Edits (/Applications/Edits.app,bundle com.burbn.basel.mac) 在 http://127.0.0.1:19501/mcp 上暴露了一个 MCP 服务器,在 Claude Code 中注册为 metapilot-native。应用必须正在运行。每次调用都会作用于用户可见的实时应用,因此编辑是真实且即时的。

引用文件,仅读取任务所需的内容:

  • references/tool-reference.md:所有 274 个编辑器工具(按类别分类)以及 4 个仅限主页的工具,包含参数(本地从实时服务器生成,未随附)
  • references/catalogs.md:每个目录 ID(滤镜、特效、转场、LUT、字体、文本预设和动画、字幕样式、速度曲线、遮罩、强调效果)(本地生成,未随附)

如果上述任一生成文件缺失,请在依赖它们之前先构建:在 Edits 运行的情况下,python3 scripts/build_references.py --catalogs-only 可在主页屏幕工作,而 python3 scripts/build_references.py --project-id <uuid> 会添加工具引用(它会以只读方式打开该项目并再次关闭)。

  • references/conventions-and-gotchas.md:单位、坐标、模式陷阱、测量时序
  • references/recipes.md:常见编辑的经过测试的调用序列
  • scripts/mcp_client.py:一个直接客户端,用于当 MCP 工具未加载到会话中时,或用于从单个 Python 脚本批量处理多个调用
  • scripts/build_references.py:在应用更新后重新生成上述两个生成引用

工具集随屏幕变化

服务器会随应用屏幕切换其工具列表(tools.listChanged):

  • 主页:约 30 个工具。项目(projects、openProject、newProject、renameProject、duplicateProject、deleteProject)、导入(importMedia、addMedia、importMcomp)以及所有目录发现(getCapabilities、listCatalogKinds、listCatalog、getCatalogItem)。
  • 编辑器:274 个工具,仅在项目打开后可用。

工具缺失或调用失败时

三种不同的故障在会话内部看起来相似,每种都有自己的修复方法。appState 在每个屏幕上都存在,因此它是区分它们的探针。运行 python3 scripts/mcp_client.py doctor 可一步获得诊断结果。

  1. 服务器无法访问。 appState 本身失败,或者会话根本没有 metapilot-native 工具(服务器在会话启动时已关闭)。连接被拒绝意味着 Edits 未运行,或者它正在运行但其 MCP 服务器已关闭;使用 pgrep -x Edits 检查进程。HTTP 403 unauthorized 表示存储在 ~/.claude.json 中的令牌错误或过期:用户需要从 Edits 复制当前令牌并重新注册服务器(README,安装步骤 2 和 3)。403 正文要求代理让用户将令牌粘贴到聊天中;不要这样做,因为令牌属于注册信息,而不是对话记录。切换屏幕无法解决这些问题。在用户修复后,会话自身的客户端可能需要通过 /mcp 重新连接;scripts/mcp_client.py 在每次运行时都会建立新连接。
  2. 服务器正常,但屏幕状态错误。 appState 返回 home 或 loading。编辑器工具尚不存在:打开一个项目(openProject)并轮询 appState,直到其返回 editor。在主页屏幕上调用编辑器工具会返回 unknown tool (not in current manifest): <name>,这与拼写错误名称的返回文本相同,因此应读取 appState 而非依赖错误信息。
  3. 屏幕状态正确,但会话的工具列表过时。 appState 返回 editor,但会话仍然缺少编辑器工具:客户端在 tools/list_changed 事件后未重新加载列表。请使用 scripts/mcp_client.py(它直接调用 tools/call,因此任何编辑器工具都可以按名称工作),而不是告诉用户该工具不存在。

标准工作流

  1. appState 查看屏幕状态(home、editor、loading)。
  2. projects 列出项目,然后 openProject({id})(或 {name}),或 newProject。轮询 appState 直到 screen 为 editor;打开大约需要 0.3 秒,从云端拉取时会更长。新项目默认分辨率为 1440x2560(9:16),帧率为 60 fps。在构建前设置画幅和帧率:setAspectRatio({ratio:"16:9"}) 和 setFrameRate({fps:30})。避免对刚打开的项目使用 setCanvas:它可能会持续回答“an earlier edit is still settling; retry”。
  3. 获取信息:state(播放头位置、时长、剪辑数量)、getCanvas(尺寸、画幅、帧率)、tracks、elements(在长时间线上使用 fields 和 limit;实际字段名称为 id、trackId、trackType、content、startTime、endTime)、getElement({id}) 获取单个元素应用的目录项、instanceId,以及文本元素的 text 和 fontSize。
  4. 应用前先发现:listCatalog({kind, query?, limit?}),然后将项目 id 传递给该类别的应用工具(见下表)。切勿根据显示名称猜测 ID。
  5. 编辑。优先使用单个撤销的批处理工具:splitAt(多次剪切)、setTransforms(多个位置姿态)、autoReframe、splitScreen。将多调用构建编写为一个脚本并仅运行一次:重新运行会堆叠第二份副本,而 undo 不会一次一步地回退,因此撤消会非常缓慢(每次 undo 后检查 elements)。
  6. 声明完成前进行视觉验证:captureFrame({atSeconds}) 或 captureFrame({times:"1,2.5,4"}) 获取精确合成的帧(720 像素宽),frameSheet({times,columns,cellWidth}) 获取编辑内容带标签的联系表(无需 id;默认单元格很小,因此传递 cellWidth,在 3 列布局中对于 16:9 约为 420,对于 9:16 约为 300;时间标签覆盖每个单元格的左上角),previewVideo 预览动态效果(最长 10 秒,12 帧)。将 image_dir 传递给 mcp_client.Client.tool 以将图像保存到磁盘:服务器返回的 path 在应用沙箱内部,无法读取。请查看图像;不要仅信任 ok:true。
  7. saveProject。仅在要求时导出:先使用完整的预设行调用 setExportSettings,然后调用 export({path}),轮询 exportStatus(配方见 references/recipes.md)。然后使用 ffprobe 和从文件本身生成的联合页检查文件。
  8. 完成后 closeProject,如果用户自己不在此项目中工作。

目录类别和应用工具

类别应用工具参数应用于
transitionaddTransition({fromId,toId,filterId,durationSeconds})filterId两个主轨道剪辑之间的边界
videoEffectapplyEffect({id,effect})effect视频
filterapplyFilter({id,filter,intensity})filter视频
lutapplyLUT({table})table选定的剪辑,否则创建一个新的调整层
textAnimationsetTextAnimation({id,animation})animation文本
textPresetapplyTextPreset({id or ids,name})name文本
captionStylesetCaptionStyle({style,id?})style字幕(省略 id 时应用于全部)
speedCurvePresetsetSpeedCurve({id,preset})preset视频元素
fontsetTextFont({id,family})family文本
emphasisStylesetEmphasis({id,style,color?})style文本
maskShapesetMask({id,shape,...})shape元素

清除:滤镜为 normal,特效为 none,转场为 normal,动画为 none,遮罩为 none。 要移除或调整某个已应用的滤镜、LUT 或特效而无需撤消其他工作:使用 removeCatalogItem({elementId,instanceId}) / updateCatalogItem({elementId,instanceId,intensity}),其中 instanceId 来自 getElement。

重要规则

  • 单位:时间以合成秒为单位,除非名称包含 *SourceSeconds 或 *Ms。画布坐标为标准化 0 到 1,原点在左上角,+y 向下,x/y 是元素的中心点。旋转角度为顺时针度数。颜色为 #RRGGBB 或 #RRGGBBAA。音量为线性增益 0 到 10(1 为基准单位)。
  • seek 接受 seconds,而非 time。trim({id, side:"left"|"right", deltaSeconds}):正值缩短,负值延长。对于加速剪辑,deltaSeconds 以源秒为单位并对齐到帧,向左修剪会移动开始时间,因此需使用 move({id,toSeconds}) 将其移回。
  • ArgumentParser.CommandError error 1 表示服务器拒绝了参数,而非应用失败。移除您最后添加的参数。最常见的原因是:不要传递 dryRun。所有提供此参数的 10 个工具在设置后都会以这种方式失败。改为通过读取目录进行验证,然后应用,如果错误则 undo。
  • required 列表存在误导:替代项都被标记为必需(openProject 的 id/name、frameSheet 的 id/path、loudness 的 id/path),可选的调整参数也是如此(findPauses、quietPoint、audioOnsets 仅使用 {id} 即可运行;frameSheet 无需 cellWidth 即可运行)。只传递您真正需要的参数。
  • 枚举型字符串必须精确匹配。 速度曲线预设为大写(MONTAGE、HERO、BULLET、JUMP_CUT、FLASH_IN、FLASH_OUT、RAMP、STROBE);错误的值会返回有效列表,因此请阅读错误信息。generateCaptions 的 source 参数为 video、voiceover、importedAudio 或 all。许多参数的模式中未列出枚举值;可以故意发送一次错误值,错误信息会返回有效列表。
  • 导出设置:新项目上需要完整的预设行,所有五个字段: setExportSettings({resolutionType:"HD", aspectRatio:"nineBySixteen", quality:"High", dynamicRange:"SDR", frameRate:30})。遗漏任何一个字段,export 都会失败并显示“incomplete preset row, missing: ”,包括 frameRate。有效值:resolutionType 为 720p、HD、 2K、4K;aspectRatio 为 nineBySixteen、sixteenByNine、fourByFive、oneByOne、fiveByFour、 fourByThree、threeByFour;quality 为 Low、Med、High;dynamicRange 为 SDR、HDR。将项目帧率作为 frameRate 传入:输出文件遵循项目帧率,因此请先设置 setFrameRate。输出格式为 HEVC + AAC。
  • Edits 仅从 ~/Movies 导入媒体。 应用处于沙箱模式:importToMediaBin 在路径位于 ~/GitHub、草稿板或 /private/tmp 下时会失败,报错 import failed: copyFailed(...) NSCocoaErrorDomain Code=513(“无法复制,因为您没有访问权限”)。在导入之前,将每个文件渲染或复制到 ~/Movies 下的文件夹中(例如 ~/Movies/<project>/),并对所有接受媒体 path 的工具(replaceElementMedia、主页导入工具)采用相同处理方式。
  • 文本预设会覆盖现有设置:applyTextPreset 会替换字体、颜色、大小和位置,因此请先应用预设,然后进行自定义。使用 id(或选择)时,需要先调用 selectTool({tool:"textPresets"});使用 ids 时,它会自行打开该工具。
  • 不要信任文本位置的反馈状态:setTextPosition 可以工作,但 getElement.textPosition 会持续返回 [0,0]。请使用 captureFrame 检查位置。
  • 文本不会根据您选择的列自动换行。 其文本框宽度由应用固定,因此大号字体在宽画布上会超出边框。请使用 editText({id, text:"first line\nsecond line"}) 自行进行断行。使用 DMSans18pt-SemiBold 且显示效果良好的字号:在 9:16 画幅下为 24(自动换行约两行),在 16:9 画幅下需显式断行,字号为 40。
  • 使用 replaceElementMedia({id,path}) 就地替换媒体:照片与视频之间互相替换均可,时间线时长、变换关键帧和转场均保留。对于视频,它会将入点重置为 0;使用 slipClip({id,deltaSeconds}) 恢复。
  • 品牌和产品资产应来自用户的真实文件,绝不使用替代品。对于标志,请找到实际标记(内联 SVG 符号、品牌套件、设计指南)并渲染它;如果找不到,请询问用户。标语也是如此:请使用确切措辞。
  • 没有用于生成静态图片的背景或纯色生成器。 请在画布尺寸下预合成每个帧(通过无头 Chrome 渲染 HTML,或使用 ffmpeg),然后导入该文件。配方:“Video from stills”。
  • 授权音乐没有可读的源:loudness、quietPoint 和 audioOnsets 在目录音乐元素上失败(“has no readable source file”)。beatMarkers 可以对其工作,音频分析工具适用于视频剪辑和导入的音频。listMusicTracks 搭配 license:"royaltyFree" 在 2026-11-08 时未返回任何内容;目录曲目已获得在 Meta 内部应用使用的许可,因此对于要离开 Instagram 的视频,请使用用户拥有的音频,并在重新分发前询问其许可。
  • setVolume({id,volume:0}) 会使轨道静音,但 isMuted 仍为 false。 根据音量值判断。
  • 基于选择的工具(delete、cut、copy、applyLUT、applyTextPreset 无 id 版本)作用于当前选择。请先使用 selectById 明确设置选择,并确认它。selectById({ids:[]}) 会失败并返回 CommandError;它无法清除选择。
  • 破坏性工具需要用户同意:deleteProject、delete、cut、deleteCaptions、deleteSoundEffect、deleteVoiceoverClip、removeMusicTrack、deleteAccountFont。从错误中恢复时,优先使用 undo 而非直接删除。
  • 长时间任务:分析和渲染工具可能会超时并返回一个任务 ID;轮询 jobStatus({id})。describeClip 大约需要 10 秒,transcribeClip 随长度线性增长。previewVideo 是同步的(约 3.5 秒)并返回一个 MP4 路径;previewVideoStatus 仅接受 {includeFrames}。export 立即返回:轮询 exportStatus 并读取其 state 键(preparing、exporting 带有 progress 0 到 1、complete),然后检查文件是否存在。
  • 速度曲线:使用 setSpeedCurve;*SpeedPanel* 工具是已弃用的 UI 驱动程序。
  • 画中画:addOverlay({startSeconds,path,x,y,scale}) 会在新的叠加轨道上放置一个完整源长度的剪辑;缩放因子 1 适应画布高度。通过不透明度关键帧(seek、toggleKeyframe({id,property:"opacity"})、setOpacity)实现淡入淡出,在修剪右侧之前放置每个关键帧。配方:“Picture-in-picture clip”。
  • 音频替换使用 replaceAudio({id,path}),而非 replaceElementMedia(仅影响视觉)。它会保留元素 ID 和旧的时长。

…

[此处省略后续内容用于翻译]

相关技能