____ _ ____ ____ _ _ _____ __ __ ____ ____
/ ___| / \ | _ \ / ___| | | |_ _| | \/ |/ ___| _ \
| | / _ \ | |_) | | | | | | | | | |\/| | | | |_) |
| |___ / ___ \| __/| |___| |_| | | | | | | | |___| __/
\____/_/ \_\_| \____|\___/ |_| |_| |_|\____|_| 一 MCP(模型上下文协议) CapCut的服务器,用Elixir编写。让Claude直接阅读和编辑CapCut项目——不需要CapCut API。通过读写CapCut的本地JSON项目文件来工作。
用“疯狂”的语言为乐趣而建。Elixir/OTP,带有GenServers、监督树、模式匹配和无处不在的管道。
它的作用
Claude获得了15个工具来处理您的CapCut项目:
读取并检查
| 工具 | 克劳德能做什么 |
|---|---|
list_projects | 显示所有CapCut草稿 |
get_project | 检查画布大小、FPS、持续时间、曲目计数 |
get_timeline | 查看所有曲目、剪辑及其时间码 |
read_draft_json | 返回完整的原始项目JSON进行调试 |
创建和添加
| 工具 | 克劳德能做什么 |
|---|---|
create_project | 创建新的空草稿(自定义大小/FPS) |
add_text | 在特定时间添加文本覆盖 |
add_clip | 将视频或音频文件添加到时间线(验证文件是否存在) |
修改剪辑
| 工具 | 克劳德能做什么 |
|---|---|
set_clip_transform | 定位、缩放和旋转剪辑 |
set_clip_opacity | 设置剪辑透明度(0.0--1.0) |
set_clip_volume | 静音、标准化或增强剪辑音频 |
set_clip_loop | 启用/禁用剪辑循环 |
set_clip_blend_mode | 从本地CapCut安装中应用混合模式(屏幕、柔光、倍增等) |
move_clip | 在时间线上重新定位剪辑 |
trim_clip | 设置源输入/输出点和时间线持续时间 |
remove_clip | 按片段ID删除片段 |
连接后的示例提示:
- “列出我的CapCut项目”
- “在0ms时将文本'Intro'添加到项目X中3秒”
- “显示我最新项目的时间表”
- “创建一个名为'Reel'的1080x1920垂直项目”
- “将屏幕录制剪辑设置为屏幕混合模式”
- “将剪辑X移动到5秒,并将其不透明度设置为0.8”
- “将轨道2上的视频静音并循环播放吉祥物片段”
需求
- Windows(CapCut将项目存储在
%LOCALAPPDATA%\CapCut\) - Erlang/OTP 28 安装
- 灵丹妙药1.19+(见 安装)
- 已安装CapCut桌面应用程序
安装
1.安装Erlang OTP (如果尚未安装):
winget install Erlang.ErlangOTP2.安装Elixir (没有winget包——下载zip):
(New-Object Net.WebClient).DownloadFile(
'https://github.com/elixir-lang/elixir/releases/download/v1.19.5/elixir-otp-28.zip',
"$env:USERPROFILE\elixir.zip"
)
Expand-Archive "$env:USERPROFILE\elixir.zip" -DestinationPath "$env:USERPROFILE\elixir"
[Environment]::SetEnvironmentVariable(
'PATH',
[Environment]::GetEnvironmentVariable('PATH','User') + ";$env:USERPROFILE\elixir\bin",
'User'
)3.克隆和构建:
git clone https://github.com/burnshall-ui/capcut-mcp.git
cd capcut-mcp
mix deps.get
mix compile4.烟雾测试:
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | mix run --no-halt预期:JSON响应 "name":"capcut-mcp".
连接到克劳德
克劳德代码
创建(或编辑) .claude/settings.json 在项目根目录中:
{
"mcpServers": {
"capcut": {
"command": "mix",
"args": ["run", "--no-halt"],
"cwd": "C:/Users//Desktop/kram/capcut-mcp",
"env": {
"PATH": "C:\\Program Files\\Erlang OTP\\bin;C:\\Users\\\\elixir\\bin"
}
}
}
}重新启动Claude代码 capcut 工具会自动出现。
克劳德桌面版
Claude Desktop忽略了 cwd Windows上的config字段,因此 mix run 找不到 mix.exs。该修复程序是一个小型包装器脚本,它首先更改为项目目录。
该回购交易 start-mcp.bat 这正是如此。如果它与默认值不同,请编辑它以指向您的Elixir安装:
@echo off
cd /d "C:\Users\\Desktop\kram\capcut-mcp"
"C:\Users\\elixir\bin\mix.bat" run --no-halt然后将其添加到 %APPDATA%\Claude\claude_desktop_config.json:
{
"mcpServers": {
"capcut": {
"command": "C:\\Users\\\\Desktop\\kram\\capcut-mcp\\start-mcp.bat"
}
}
}重新启动克劳德桌面。
配置
CapcutMcp.CapCut.PathDiscovery 自动在启动时发现CapCut项目文件夹。它按顺序检查:
- 这
CAPCUT_PATH环境变量 %LOCALAPPDATA%\CapCut\User Data\Projects\com.lveditor.draft--标准Windows安装路径
如果两者都不解析到现有目录,服务器仍将启动。需要磁盘访问的第一个工具调用返回一个描述性错误,列出了所尝试的操作,因此Claude可以逐字地将其转发给您。
用以下命令覆盖发现的路径(例如,对于便携式安装) CAPCUT_PATH:
CAPCUT_PATH="D:\CapCut\Projects\com.lveditor.draft" mix run --no-halt混合模式发现从以下位置读取CapCut的本地应用资源:
C:\Users\\AppData\Local\CapCut\Apps通常,您不需要在Windows上手动配置它,因为它来自 %LOCALAPPDATA%. 如果您的CapCut安装位于其他地方,请用以下命令覆盖它 CAPCUT_APPS_PATH:
CAPCUT_APPS_PATH="D:\PortableApps\CapCut\Apps" mix run --no-halt建筑
Claude (stdin/stdout JSON-RPC 2.0)
└── MCP.Server GenServer -- stdin loop, dispatches messages
└── MCP.Dispatcher Pure -- routes tool calls by name
└── Tools.* Pure -- one module per tool (15 tools)
├── TimelineHelper Shared -- segment lookup, validation, UUID
├── BlendModes ETS-cached -- discovers CapCut MixMode resources
└── ProjectStore GenServer -- project cache + disk I/O
├── PathDiscovery Pure -- resolves projects root (env / LOCALAPPDATA)
├── Reader Pure -- reads JSON files
└── Writer Pure -- writes JSON files (atomic + backup)OTP监督树:
CapcutMcp.Application
├── CapCut.ProjectStore (permanent)
└── MCP.Server (permanent)如果任一进程崩溃,主管会自动重新启动它。这 ProjectStore 将解析后的项目JSON缓存在内存中,并通过读取加载——读取和写入都会在未命中时自动填充缓存,因此GenServer重启是透明的。 BlendModes 缓存 MixMode.json 在第一次读取后,在ETS表中。
每次写信给 draft_content.json 创建a .bak 备份并使用原子重命名(写入 .tmp ->重命名)以防止在写入过程中进程被终止时发生损坏。
可观测性
每 tools/call 经历 :telemetry.span/3 在 CapcutMcp.MCP.Dispatcher,因此持续时间和结果作为结构化事件公开——单个工具中没有自定义日志管道。两个核心子系统(ProjectStore 缓存和 BlendModes 加载器)也会发出自己的事件,边界硬化过程(读取器路径信任检查)也会产生自己的拒绝事件,因此单个遥测处理程序可以回答“哪个工具运行缓慢,是缓存绑定还是磁盘绑定,以及在进入过程中是否过滤了任何损坏的元数据?”。
发射事件:
| 事件 | 测量 | 元数据 | ||
|---|---|---|---|---|
[:capcut_mcp, :tool, :execute, :start] | :system_time, :monotonic_time | :tool, :request_id | ||
[:capcut_mcp, :tool, :execute, :stop] | :duration, :monotonic_time | :tool, :request_id, :result, :reason? | ||
[:capcut_mcp, :tool, :execute, :exception] | :duration, :monotonic_time | :tool, :request_id, :kind, :reason, :stacktrace | ||
[:capcut_mcp, :cache, :hit] | :count (总是 1) | :id | ||
[:capcut_mcp, :cache, :miss] | :count (总是 1) | :id | ||
[:capcut_mcp, :cache, :write] | :count (总是 1) | :id, :reason (:load | :update | :create) |
[:capcut_mcp, :blend_modes, :load] | :duration | :result (:ok | :error), :count?, :path?, :reason? | |
[:capcut_mcp, :draft, :schema_version] | :count (总是 1) | :version (String.t() | nil), :supported (boolean) | |
[:capcut_mcp, :meta, :rejected] | :count (总是 1) | :reason (:path_outside_root), :path (String.t()) |
中的默认日志处理程序 CapcutMcp.Telemetry 附在后备箱上,每次工具调用打印一行,例如:
12:34:56.789 [info] tool=add_text request_id=42 result=ok duration=8.24msLogger.metadata 在管道早期填充(mcp_request_id, mcp_method, tool, request_id),因此堆栈下游的每一条日志行(包括单个工具内部)都可以根据请求进行过滤。
[:capcut_mcp, :draft, :schema_version] 向每一个成功者致敬 read_draft 并且另外触发 Logger.warning 当草案 new_version 字段缺失或不在 CapcutMcp.CapCut.Reader.supported_versions/0 --服务器仍然读取草稿,它只是标记磁盘上的模式未经测试。
[:capcut_mcp, :meta, :rejected] 火灾发生时 list_projects 遭遇a root_meta_info.json 条目谁 draft_fold_path 在配置之外解析 CAPCUT_PATH。该条目将从响应中删除(因此工具调用者不会被欺骗通过损坏/恶意的元文件读取或写入任意文件),以及 Logger.warning 与遥测事件一起发射。
缓存和混合模式事件被触发,但 *不* 默认情况下会记录(它们在点击路径上很健谈)。如果您想要运行命中率或磁盘负载审计跟踪,请附加自己的处理程序:
:telemetry.attach_many(
"my-cache-counter",
[
[:capcut_mcp, :cache, :hit],
[:capcut_mcp, :cache, :miss]
],
fn [_, _, kind], _measurements, _metadata, _cfg ->
:counters.add(my_counter_ref, kind_to_idx(kind), 1)
end,
nil
)要将事件传输到Prometheus、OpenTetry、Datadog等,请附加自己的处理程序;应用程序代码不需要更改。
发展
# Run tests
mix test
# Code style (strict)
mix credo --strict
# Static analysis (first run builds PLT, ~1-2 min)
mix dialyzer
# Coverage (HTML report at cover/excoveralls.html)
mix coveralls # console summary
mix coveralls.html # full HTML report
# Format check
mix format --check-formatted
# Run with a custom CapCut path
CAPCUT_PATH="C:/path/to/projects" mix run --no-halt
# Interactive Elixir shell with the app running
iex -S mix run --no-halt已知限制
- 导出/渲染 --无法通过此服务器进行导出(CapCut没有用于导出的CLI;只有UI自动化可以做到这一点)
- 云项目 --只能访问本地草稿
- 效果和模板 --可以引用CapCut的内置效果ID,但不能创建新的效果ID;确切的ID因CapCut版本而异
- CapCut格式更改 --CapCut更新可能会更改JSON模式;针对v8.3.0进行测试
技术栈
- Elixir 1.19/OTP 28 --因为为什么不
- 杰森 --JSON编码/解码
- :遥测 --每个工具调用的结构化事件
- 信条 (
--strict)--零问题 - 透析器 (
:underspecs,:error_handling,:unknown)--零警告 - ExUnit --164次测试+12次
stream_data属性测试+6个文档测试(包括JSON-RPC集成测试,对工具进行遥测断言+缓存+混合模式+模式版本+元拒绝事件、路径发现回退、边界模糊测试,对每个注册的工具进行随机锤击StreamData.term()参数和时间线变异不变量,如update_segment往返,ensure_timerange幂等性和insert_segment计数保存) - 流数据 --基于属性的测试
TimelineHelper(UUID格式、段往返、轨道插入不变量,validate_timing域)和tools/call请求边界(没有随机有效载荷可能会使调度器崩溃) - ExCoveralls --应用程序代码的行覆盖率约为88%(剩下的空白是stdin循环I/O层和一些懒惰的磁盘助手)
