mcpField
S
SonicCraft

SonicCraft

本地服务
github.com媒体与设计21 周前更新

关于 SonicCraft

SonicCraft 是面向 AI Agent、命令行用户和 MCP 客户端的确定性音频引擎。它将 YAML 或 JSON 时间线编译为混音并完成响度母带处理的语音、音乐和音效,并生成与渲染音频对应的字幕。

主要功能

  1. 01编译 YAML 或 JSON 音频时间线
  2. 02组合 TTS、音乐与音效
  3. 03自动安排时间并进行侧链闪避
  4. 04响度归一化与峰值限制
  5. 05生成字幕和分轨文件
  6. 06渲染前验证并预览

适用场景

  1. 01制作带背景音乐的旁白
  2. 02制作带定时停顿的多人语音
  3. 03生成带匹配字幕的音频
  4. 04渲染前预览时间安排和合成字符量

MCP 相关

MCP 服务向 MCP 客户端提供 SonicCraft 音频工作流,也可通过 Agent 集成使用。它调用 SonicCraft CLI 执行验证、计划和渲染。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"user-github-me-soniccraft": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"ELEVENLABS_API_KEY",
"-e",
"OPENAI_API_KEY",
"-e",
"CARTESIA_API_KEY",
"ghcr.io/user-github-me/soniccraft:0.1.0"
],
"env": {
"ELEVENLABS_API_KEY": "<ELEVENLABS_API_KEY>",
"OPENAI_API_KEY": "<OPENAI_API_KEY>",
"CARTESIA_API_KEY": "<CARTESIA_API_KEY>"
}
}
}
}
启动命令docker run -i --rm -e ELEVENLABS_API_KEY -e OPENAI_API_KEY -e CARTESIA_API_KEY ghcr.io/user-github-me/soniccraft:0.1.0
需要配置的环境变量
ELEVENLABS_API_KEY密钥ElevenLabs API key for the elevenlabs TTS provider (optional)
OPENAI_API_KEY密钥OpenAI API key for the openai TTS provider (optional)
CARTESIA_API_KEY密钥Cartesia API key for the cartesia TTS provider (optional)

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
ocighcr.io/user-github-me/soniccraft:0.1.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

SonicCraft

SonicCraft

一款面向 AI Agent 的声明式、确定性音频引擎。 用 YAML(或 JSON)时间线描述制作内容:谁说什么、按什么顺序、配什么音乐、音量多大。SonicCraft 会将其编译为 TTS 语音、背景音乐和音效,通过侧链压低背景音进行混音,并按照 EBU R128 响度目标进行母带处理,还会生成与实际渲染音频相匹配的 WebVTT/SRT 字幕。它以 CLI、MCP 服务和 Agent Skill 的形式提供。

CI License: MIT OR Apache-2.0 crates.io SonicCraft MCP on mcprush

官方网站 · 快速入门 · 在 AI Agent 中使用 · MCP 服务 · Agent Skill

在 AI Agent 中使用

将此仓库链接提供给 Agent(Claude Code、Codex、Cursor、Gemini CLI 等),并请它制作音频,例如 “使用 https://github.com/user-github-me/soniccraft 为我的产品视频制作一段 30 秒的配背景音乐旁白。” 所需内容见下文和 AGENTS.md。

  1. 安装 CLI(预构建并已验证校验和,无需 Rust)。也支持 Homebrew、Scoop、Docker 和 Cargo:参见快速入门。

    curl -fsSL https://raw.githubusercontent.com/user-github-me/soniccraft/main/install.sh | sh   # macOS, Linux
    
    irm https://raw.githubusercontent.com/user-github-me/soniccraft/main/install.ps1 | iex        # Windows
    
  2. 编写时间线。 soniccraft init my-audio 会创建一个可离线渲染的时间线:在 Mac 上使用 macOS 语音,其他平台使用模拟测试语音(不是真实语音)。要在任何平台使用真实语音,可选 Kokoro 或 Piper(免费、本地运行),也可使用 ElevenLabs、OpenAI 或 Cartesia 密钥;参见提供方。soniccraft init --list 会显示模板,soniccraft providers 会显示此处可用的语音,soniccraft schema 会显示 JSON Schema;Agent Skill 介绍了格式。

  3. 检查、查看费用并进行渲染:

    soniccraft validate my-audio/timeline.yaml           # errors with a code, line, column and fix hint
    soniccraft plan my-audio/timeline.yaml               # free dry run: timing, ducking, characters to synthesize
    soniccraft render my-audio/timeline.yaml --preview   # mastered audio, subtitles, manifest, preview page
    

要让 Agent 持续使用 SonicCraft,请添加 Skill 和 MCP 服务。两者都使用步骤 1 中的 CLI;如果安装了 Node.js 20 或更高版本,MCP 服务也可以在无需安装任何内容的情况下运行:在下文中用 npx -y soniccraft-mcp 替代 soniccraft mcp。

AgentSkillMCP 服务
Claude Codeclaude plugin marketplace add user-github-me/soniccraft,然后运行 claude plugin install soniccraft@soniccraft插件中已包含,或运行 claude mcp add soniccraft -- soniccraft mcp
Codexnpx skills add user-github-me/soniccraft -g -a codexcodex mcp add soniccraft -- soniccraft mcp
Cursornpx skills add user-github-me/soniccraft -g -a cursor在 .cursor/mcp.json 中填写 {"mcpServers": {"soniccraft": {"command": "soniccraft", "args": ["mcp"]}}}
Gemini CLI 和其他工具npx skills add user-github-me/soniccraft -g(选择 Agent)使用相同的 mcpServers 条目(Gemini CLI:~/.gemini/settings.json)

此服务也已作为容器映像收录在官方 MCP Registry,名称为 io.github.user-github-me/soniccraft。详情见:MCP 服务和Agent Skill。

原因

让 Agent 制作带背景音乐的双人讲解,通常会得到它手写的 ffmpeg 滤镜图:adelay 的偏移量根据猜测的语音时长计算,再加上 amix,或许还有一个只记得一半的 sidechaincompress。这会以一些可预见的方式出错:

  • 时间漂移和重叠。 合成语音的时长永远不会和 Agent 猜测的完全一致,因此台词会相互冲突或留下空白,而且每次修改脚本都会改变后续所有偏移量。
  • 没有自动压低背景音乐。 很难在滤镜图中正确设置侧链压缩,因此背景音乐要么盖过人声,要么始终音量过低。
  • 响度差异。 不同提供商和语音的输出音量各不相同。没有任何机制会测量综合响度或真峰值,因此成品音量不均,还可能出现削波。
  • 字幕漂移。 字幕是根据估算时间编写的,而不是根据渲染完成的音频生成。
  • 迭代过程不透明且成本高。 出错的滤镜图只会返回难以理解的 ffmpeg 错误,而每次重试都会再次为所有 TTS 调用付费。

SonicCraft 的工作原理

HyperFrames 表明,当 Agent 编写声明式 HTML,再由确定性渲染器完成精确到帧的工作时,制作出的视频效果更好。SonicCraft 将同样的理念应用于音频。Agent 将意图写成数据;编译器会验证数据、测量实际时长、以整数采样帧解析所有时间,并使用 Rust 原生渲染。同一条时间线、TTS 缓存和二进制文件始终会生成字节完全一致的音频、字幕和清单。

version: "1.0"
output:
  format: "mp3"
  sample_rate: 48000
  bitrate: "320k"
  target_lufs: -16.0 # integrated loudness target, measured per EBU R128 / ITU-R BS.1770
  export_subtitles: true # Emits matching .vtt and .srt

tracks:
  - id: ambient_bed
    type: "music"
    source: "assets/audio/synthwave_loop.wav"
    loop: true
    volume: 0.65
    fade_in_ms: 1200
    fade_out_ms: 2500
    ducking:
      trigger_tracks: ["voice_primary", "voice_secondary"]
      reduction_db: -18.0
      attack_ms: 80
      release_ms: 350

  - id: voice_primary
    type: "speech"
    pan: -0.15 # Subtle left stereo placement
    sequence:
      - id: cue_01
        speaker: "narrator"
        provider: "elevenlabs"
        voice_id: "21m00Tcm4TlvDq8ikWAM"
        text: "Autonomous software development requires deterministic compilation targets."
      - pause_duration: 350ms
      - id: cue_03
        speaker: "narrator"
        provider: "elevenlabs"
        voice_id: "21m00Tcm4TlvDq8ikWAM"
        text: "By separating high-level planning from digital signal processing, systems eliminate runtime hallucinations."

  - id: voice_secondary
    type: "speech"
    pan: 0.15 # Subtle right stereo placement
    sequence:
      - id: cue_02
        start_relative:
          after_cue: "cue_01"
          offset_ms: 150
        speaker: "guest"
        provider: "local_kokoro"
        voice_id: "am_adam"
        text: "Exactly. SonicCraft treats audio composition the same way Hyperframes treated web-based video."

  - id: sfx_impact
    type: "sfx"
    source: "assets/sfx/whoosh.wav"
    volume: 0.8
    start_at_ms: 0

这是 examples/tech-briefing/timeline.yaml。以下是 soniccraft render 对它的处理:

  1. 一次性验证所有内容。 未知键、拼写错误的枚举值、无效锚点、缺失的声音、缺失的文件和缺失的 API 密钥都会一并报告,每条报告均包含稳定代码、路径、行号和列号,以及修复提示。
  2. 合成并缓存。 cue_01 和 cue_03 使用 ElevenLabs(带词级时间戳);cue_02 使用本地 Kokoro-FastAPI 服务(local_kokoro 是内置 kokoro 提供方的别名)。每个结果都按内容哈希缓存,因此之后渲染时只需为有更改的行付费。
  3. 平衡人声音量。 每段提示音都会裁掉开头和结尾的静音,并标准化至 -20 LUFS,因此云端声音和本地声音的音量相同。
  4. 以采样帧为单位排布时间线。 cue_01 从 0 开始。cue_02 在 cue_01 结束后 150 ms 开始。cue_03 按顺序播放,在 cue_01 结束后 350 ms 开始,但该位置与 cue_02 冲突,因此默认的重叠策略(push)会自动将 cue_03 移至 cue_02 结束后 350 ms,保留其暂停时长作为间隔,并报告一条 cue_pushed 信息。最终形成自然的三轮对话,无需 Agent 计算时间。
  5. 放置音乐。 背景音乐是没有长度限制的循环片段,因此会持续播放至时间线结束,并淡入 1.2 s;时间线在最后一个词之后 2.5 s 结束(即背景音乐的 fade_out_ms),背景音乐会在这段尾音期间精确淡出。呼啸音效在 0 时触发。
  6. 压低背景音乐音量,每当任一人声说话时降低 18 dB。检测基于人声自身信号,并使用 80 ms 前瞻时间(默认与起音时间相同),因此第一个音节响起时背景音乐已被压低;随后用 350 ms 恢复音量,默认的 250 ms 保持时间会跨越 150 ms 的轮次间隔。
  7. 调整声像,将两个人声分别设为 -0.15 和 +0.15(恒定功率)。
  8. 对混音进行母带处理,将综合响度设为 -16 LUFS,真峰值上限设为 -1.0 dBTP(采用默认的 podcast 预设),并迭代调整响度增益和 4× 过采样真峰值限制器,直至误差在 0.2 LU 以内(若没有任何一次处理达到目标,则保留最接近的一次,并由 loudness_target_missed 报告偏差;若目标无法达到,则无论目标为何,都会在平均限制量 6 dB 以内选取响度最大的母带)。
  9. 编码为原生 48 kHz、320 kbps 的 MP3,解码并测量交付文件(若编解码器导致峰值超过上限,则重新限幅),并根据放置后的词级时间戳生成 timeline.vtt 和 timeline.srt,并标注为 narrator 和 guest。

在花费任何费用之前,soniccraft plan(别名 dry-run)会显示根据估算时长生成的相同布局,但不会调用 TTS API(JSON 内容经过删减,数字为估算值):

{ "valid": true, "duration_ms": 20616.9, "estimated": true,
  "items": [
    { "id": "cue_01", "kind": "cue", "start_ms": 0.0,     "end_ms": 4838.7,  "duration_source": "estimate" },
    { "id": "cue_02", "kind": "cue", "start_ms": 4988.7,  "end_ms": 10863.7, "duration_source": "estimate" },
    { "id": "cue_03", "kind": "cue", "start_ms": 11213.7, "end_ms": 18116.9, "duration_source": "estimate",
      "pushed_from_ms": 5188.7 } ],
  "synthesis": { "cues": 3, "cached": 0, "characters_to_synthesize": 276 } }

功能

  • Timeline DSL v1.0:使用 YAML 或 JSON 编写,并提供已发布的 JSON Schema。严格校验:未知键会报错并提供“是否想输入”的提示;一次性报告所有问题,并附带稳定的代码、路径、行/列位置和可机械执行的修复方法。
  • **无需计算即可安排时间:**按顺序排列提示和停顿、设置绝对起始时间,以及通过相对锚点(after_cue、with_cue、before_cue,支持有符号偏移量)在提示、片段或整个轨道上定位。语音重叠会自动分开(或针对每条提示配置串音警告、拒绝或允许)。
  • **八种 TTS 提供商:**ElevenLabs、任意兼容 OpenAI /audio/speech 的服务、Cartesia、Kokoro(Kokoro-FastAPI)、Piper、macOS say、任意本地命令,以及确定性模拟语音。可在同一时间轴中自由混用。提供支持分层语音设置的说话人注册表。
  • **低成本迭代:**基于内容寻址的 TTS 缓存;不会调用付费 API 的试运行(提供预估时长和各提供商的字符数);支持并发数上限和带退避的重试。
  • **音乐和音效:**循环(无缝循环或带循环交叉淡化)、裁剪、三种曲线的淡入淡出、片段间交叉淡化,以及结束时自动添加淡出尾音的开放式背景音轨。
  • **侧链闪避:**由实际语音信号(或时间轴)驱动,并支持起音、释放、保持和预读。
  • **正确处理响度:**先对每个音源进行 BS.1770 标准化,再按预设进行母带标准化(播客 -16、流媒体 -14、EBU R128 广播 -23、ATSC A/85 -24 LUFS),并使用过采样真峰值限制器。对有损输出进行解码并测量最终交付音频,同时补偿编解码器真峰值和响度漂移。
  • **原生 DSP 和编码器:**无需 ffmpeg 即可处理 wav、mp3 和 flac;安装了 ffmpeg 时可处理 ogg、opus 和 m4a。支持 16/24 位整数或 32 位浮点,以及固定种子的 TPDF 抖动。
  • **根据渲染后的音频生成字幕:**WebVTT、SRT、带逐词时间戳的 JSON,以及兼容 HyperFrames 的转录文本;支持说话人标签和逐条提示的字幕覆盖。
  • **附属文件:**每条轨道的分轨文件、确定性清单,以及包含波形、闪避包络和字幕的独立 HTML 预览。
  • Agent 接口:validate、plan、render、providers 和 voices 提供机器可读的 --json 报告;兼容两个协议版本的 MCP 服务、Agent Skill,以及 Claude Code 插件。

快速开始

安装预构建二进制文件(已验证校验和;无需 Rust 或 C 工具链):

curl -fsSL https://raw.githubusercontent.com/user-github-me/soniccraft/main/install.sh | sh   # macOS, Linux: ~/.local/bin
brew install user-github-me/soniccraft/soniccraft                                            # Homebrew (macOS, Linux)
irm https://raw.githubusercontent.com/user-github-me/soniccraft/main/install.ps1 | iex        # Windows
scoop bucket add soniccraft https://github.com/user-github-me/scoop-soniccraft; scoop install soniccraft

使用 Rust:cargo binstall soniccraft 会下载相同的发行版二进制文件,而 cargo install --locked soniccraft 会从 crates.io 构建(要求见下文)。

从源代码构建。 要求:Rust 1.89 或更高版本(rustup),以及用于捆绑的 LAME MP3 编码器的 C 工具链(cc 和 make:macOS 上使用 Xcode 命令行工具,Linux 上使用 build-essential;Windows 上使用 Visual Studio Build Tools,除非已安装 NASM,否则还需在环境中设置 AWS_LC_SYS_PREBUILT_NASM=1)。 ffmpeg 是可选项(用于 ogg/opus/m4a 输出和更多输入格式)。预构建二进制文件无需这些依赖:见 下文。

git clone https://github.com/user-github-me/soniccraft
cd soniccraft
cargo install --locked --path crates/soniccraft-cli    # installs `soniccraft` and `soniccraft-mcp` into ~/.cargo/bin
soniccraft --version

--locked 会使用 Cargo.lock 中的依赖版本,也就是 CI 测试所用的版本。

预构建二进制文件。 每个 GitHub 发行版都提供适用于 Linux(x86_64-unknown-linux-gnu、aarch64-unknown-linux-gnu;glibc 2.35 或更高版本)、macOS (aarch64-apple-darwin、x86_64-apple-darwin;macOS 11 或更高版本)和 Windows(x86_64-pc-windows-msvc)的压缩包。 soniccraft-v<version>-<target>.tar.gz(Windows 上为 .zip)包含 soniccraft、soniccraft-mcp、 许可证文本和 THIRD-PARTY-LICENSES.txt。-no-mp3 压缩包不含 LGPL MP3 编码器;此时 MP3 输出需要 ffmpeg。使用 sha256sum --check --ignore-missing SHA256SUMS 检查下载文件(macOS 上: shasum -a 256 --check --ignore-missing SHA256SUMS)。这些二进制文件未经公证:在 macOS 上,浏览器 下载的文件会被隔离;使用 xattr -d com.apple.quarantine soniccraft soniccraft-mcp 清除隔离标记(curl 和 npm 启动器不会设置此属性)。

容器镜像。 每个发行版也会发布为 ghcr.io/user-github-me/soniccraft (linux/amd64 和 linux/arm64,包含用于 ogg、opus 和 m4a 输出的 ffmpeg):

docker run --rm -v "$PWD":/work ghcr.io/user-github-me/soniccraft render timeline.yaml
docker run -i --rm -v "$PWD":/work ghcr.io/user-github-me/soniccraft mcp --base-dir /work   # MCP on stdio

写入挂载目录的文件归 uid 1000 所有;添加 --user "$(id -u):$(id -g)",即可用自己的身份写入。 使用 -e ELEVENLABS_API_KEY 传入 API 密钥(绝不要放入时间线)。容器中无法使用 macOS 的 say:请使用 模拟语音、云服务提供商或本地服务。docker build -t soniccraft . 可从源代码构建相同的镜像。

无需任何 API 密钥即可渲染演示:

# macOS: Samantha and Daniel from macOS `say`, plus the built-in mock voice
soniccraft render examples/offline-demo/timeline.yaml --preview

# any OS: the same timeline with mock voices only
soniccraft render examples/offline-demo/timeline.mock.yaml

macOS 上的运行会生成 examples/offline-demo/offline-demo.wav,以及 .vtt、.srt、.words.json 和 .transcript.json 字幕文件、一个 .manifest.json,还有 offline-demo.preview.html(在浏览器中打开即可 查看波形、闪避包络和字幕)。Agent 遵循的完整流程:

soniccraft validate examples/offline-demo/timeline.mock.yaml          # errors, warnings, fix hints
soniccraft plan     examples/offline-demo/timeline.mock.yaml          # dry run: layout, ducking, cost
soniccraft render   examples/offline-demo/timeline.mock.yaml --json   # one JSON report on stdout

使用 API 密钥和本地 Kokoro 服务,渲染 README 时间线:

export ELEVENLABS_API_KEY=...                                          # never put keys in timelines
docker run -d -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-cpu:latest
soniccraft render examples/tech-briefing/timeline.yaml

从模板开始创建自己的项目(会写入时间线,并为其音频资源生成替代文件):

soniccraft init my-episode --template two-person-podcast

CLI

soniccraft validate <TIMELINE> [--json] [--check-credentials]
soniccraft plan <TIMELINE> [--json]                      (alias: dry-run)
soniccraft render <TIMELINE> [-o PATH] [--format F] [--subtitles] [--stems] [--manifest] [--preview]
                  [--no-cache] [--cache-dir DIR] [--jobs N] [--json]
soniccraft schema [-o FILE]
soniccraft init [DIR] [--template NAME] [--list] [--no-assets] [--force]
soniccraft providers [--json]
soniccraft voices <PROVIDER> [--json]
soniccraft cache <info|clear> [--cache-dir DIR] [TIMELINE]
soniccraft mcp [--base-dir DIR] [--allow-command]
命令功能
validate解析并检查时间线及其环境(资源是否存在且可解码、凭据是否齐全且允许发送到对应主机、本地 TTS 服务是否有响应、macOS 语音和 piper 模型是否已安装、是否需要 ffmpeg、渲染是否符合内存预算、缓存状态)。--check-credentials 还会通过一次低成本的身份验证请求验证 API 密钥。
plan / dry-run验证后,使用缓存或估算的时长(模拟语音使用精确时长)布局时间线:条目时间、重叠调整、闪避区段、各提供方需要合成的角色,以及 ASCII 示意图。绝不会调用付费 API。
render完整的处理流程。-o 设置输出路径(仅当未设置 output.format 时,才根据扩展名选择格式:对于 format: wav 的时间线,使用 -o out.mp3 --format mp3);--format 可设为 wav、mp3、flac、ogg、opus、m4a,并会覆盖两者。--subtitles、--stems 和 --manifest 会启用对应导出(类似于 output.export_* 字段);--preview 会写入 <stem>.preview.html。--no-cache 会忽略缓存的 TTS 音频(新结果仍会缓存);--cache-dir 选择缓存目录;--jobs N 限制并发合成请求数(默认值为 4)。只有渲染成功后才会写入输出文件,且绝不会覆盖现有的非 SonicCraft 输出文件。
schema打印时间线 JSON Schema,或使用 -o 将其写入文件。
init根据模板写入 DIR/timeline.yaml(默认 DIR 为当前目录),并生成它引用的音频资源(以程序化方式生成无缝合成器循环和三个 SFX,结果确定且免版税)。模板(--list):offline-demo(macOS 默认:系统语音 + 模拟)、offline-demo-mock(其他平台默认:可在任何地方渲染)、tech-briefing、two-person-podcast、voiceover-with-music、dialogue-crosstalk。--no-assets 只写入时间线;未指定 --force 时绝不会覆盖现有文件。
providers列出内置提供方及其可用状态、凭据状态和默认语音。
voices列出某个提供方的语音(可能会调用其 API);提供方名称不区分大小写,且会忽略 - / _。
cacheinfo 显示 TTS 缓存位置、条目数和大小;clear 清空缓存。
mcp通过 stdio 运行 MCP 服务。--allow-command(或 SONICCRAFT_ALLOW_COMMAND=1)允许时间线运行 command 提供方;默认情况下会拒绝此类操作。

退出代码:0 表示成功,1 表示时间线无效(错误诊断),2 表示用法错误,3 表示运行时或渲染失败,130 表示中断。使用 --json 时,stdout 仅包含一份 JSON 文档(报告;命令失败时则为 {"message", "diagnostics", "hint"},包括用法错误);进度和日志输出到 stderr。由于环境或选项导致渲染停止时(例如缺少密钥、提供方无法运行、语音未安装或超出内存预算),也会以代码 1 退出,并以 error: render stopped: N errors 结尾。时间线(文件、FIFO、表示 stdin 的 -)最多读取 5 MB 文档,不会继续读取。运行 soniccraft <command> --help 查看各命令的所有选项。

MCP 服务

soniccraft mcp 通过 stdio 提供引擎服务(以换行符分隔的 JSON-RPC 2.0);soniccraft-mcp 是无需参数即可运行的同一服务。它支持两个版本的 MCP 协议:initialize 握手(2024-11-05 至 2025-11-25,Codex 和 Cursor 使用)以及无状态的 2026-07-28 版本(包含 server/discover,Claude Code 会先探测此接口)。

工具输入结果
soniccraft_validate_timeline{yaml_content?, yaml_path?, base_dir?, check_credentials?, detail?}(内容和路径二选一;path 是 yaml_path 的别名)ValidationReport
soniccraft_dry_run{yaml_content?, yaml_path?, base_dir?, detail?}PlanReport(附文本形式的图表)
soniccraft_render{yaml_content?, yaml_path?, output_path?, format?, base_dir?, export_subtitles?, no_cache?, detail?}RenderReport
soniccraft_get_schema{detail?}DSL 快速参考(detail: "full" 时附 JSON Schema)
soniccraft_list_providers{}提供商、可用情况(已探测本地服务)、凭据状态、默认语音
soniccraft_list_voices{provider}语音(可能会调用提供商 API)

报告以 structuredContent 的形式返回(同时镜像为 JSON 文本,并附简短摘要)。较长的时间线默认会生成精简报告(detail: "auto"),使结果在 Agent 的上下文中保持易读;传入 detail: "full" 可获取所有条目。渲染结果会添加带有 file:// URI 的 resource_link 块,指向音频及旁侧文件(协议修订版本早于 2025-06-18 的会话会以文本形式获取这些文件);音频绝不会以内嵌 base64 的形式返回。format 会覆盖时间线的 output.format(传入该参数时,output_path 的扩展名应对应另一种格式)。对于 mp3/ogg/opus/m4a,报告中的响度描述的是最终交付文件(母带的响度见 loudness.pre_encode)。无效时间线仍会成功完成 validate/dry-run 调用(valid: false);渲染失败或参数无效时会返回 isError: true,并说明需要修正的内容,方便 Agent 修正后重试。相对路径会依次以 base_dir、soniccraft mcp --base-dir、CLAUDE_PROJECT_DIR 或服务的工作目录为基准解析。较长的渲染会报告 notifications/progress 并响应取消请求;同时最多运行两个(SONICCRAFT_MCP_MAX_RENDERS)。每次渲染最多可使用 SONICCRAFT_MAX_RENDER_GB 内存(默认 8 GB),因此服务的峰值内存可能达到其乘积(默认 16 GB);小型机器请调低其中一个值。只有在启动服务时使用 soniccraft mcp --allow-command,时间线才会运行 command 提供商(参见安全性)。工具参数和报告结构: skills/soniccraft/reference/mcp-tools.md。

Claude Code

claude mcp add soniccraft -- soniccraft mcp                    # local scope (default): this project, private to you
claude mcp add --scope user soniccraft -- soniccraft mcp       # all your projects
claude mcp add --scope project soniccraft -- soniccraft mcp    # writes .mcp.json to commit with the project
claude mcp add soniccraft -- soniccraft mcp --allow-command    # only if your timelines use `command` providers (they run local programs)

也可以在项目的 .mcp.json 中配置(timeout 是每次调用的毫秒数上限)。stdio 服务会继承 Claude Code 运行时的环境,因此导出的 API 密钥无需 env 块即可传递给服务:

{
  "mcpServers": {
    "soniccraft": {
      "type": "stdio",
      "command": "soniccraft",
      "args": ["mcp"],
      "timeout": 900000
    }
  }
}

请勿添加 "env": {"ELEVENLABS_API_KEY": "${ELEVENLABS_API_KEY}"}:如果变量未设置,客户端会传递字面文本 ${ELEVENLABS_API_KEY}。SonicCraft 会将这类占位符视为缺少密钥,并明确提示(missing_credentials);如果需要添加 env 条目,请写成 "${ELEVENLABS_API_KEY:-}"。

无需安装 Rust,可通过 npm 使用(Node.js 20 或更高版本):soniccraft-mcp 包会在 PATH 中找到 soniccraft 时使用它;否则会在首次使用时下载适用于当前平台的预构建版本,并使用包中固定的 SHA-256 校验和进行验证。npm 上的每个版本都是发布包中的 soniccraft-mcp-X.Y.Z.tgz 资源,通过 GitHub Actions 并附带来源证明发布。

claude mcp add soniccraft -- npx -y soniccraft-mcp
{ "mcpServers": { "soniccraft": { "command": "npx", "args": ["-y", "soniccraft-mcp"] } } }

包名后的参数会传递给 soniccraft mcp(例如 --base-dir); packages/soniccraft-mcp/README.md 介绍了平台、环境变量、代理和离线安装。下文的 Cursor 和 Codex 配置也使用相同的 npx 形式(命令为 npx,参数为 ["-y", "soniccraft-mcp"])。

Cursor:~/.cursor/mcp.json(全局)或 .cursor/mcp.json(项目):

{
  "mcpServers": {
    "soniccraft": {
      "type": "stdio",
      "command": "soniccraft",
      "args": ["mcp"],
      "env": { "ELEVENLABS_API_KEY": "${env:ELEVENLABS_API_KEY}" }
    }
  }
}

在项目级文件中,可以将 "CLAUDE_PROJECT_DIR": "${workspaceFolder}" 添加到 env,让工具调用中的相对路径以工作区为基准解析。如果某个密钥变量未设置,且客户端将占位文本原样传递,SonicCraft 会报告密钥缺失,而不会发送占位文本。

Codex

codex mcp add soniccraft -- soniccraft mcp

然后在 ~/.codex/config.toml 中提高工具超时时间(Codex 默认值为 60 s;渲染可能需要更长时间),转发你使用的 API 密钥,并决定如何批准渲染工具:

[mcp_servers.soniccraft]
command = "soniccraft"
args = ["mcp"]
env_vars = ["ELEVENLABS_API_KEY", "OPENAI_API_KEY", "CARTESIA_API_KEY"]
startup_timeout_sec = 20
tool_timeout_sec = 900
default_tools_approval_mode = "approve"   # needed for non-interactive `codex exec`, see below

soniccraft_render 会写入文件,因此 Codex 会在运行前询问。交互式会话会提示用户批准;在非交互式 codex exec 中(批准策略为 never),调用会失败并显示 "MCP tool call requires approval",除非服务条目批准了它:为所有 SonicCraft 工具设置 default_tools_approval_mode = "approve",或者仅为渲染工具设置:

[mcp_servers.soniccraft.tools.soniccraft_render]
approval_mode = "approve"

单次运行时:codex exec -c 'mcp_servers.soniccraft.default_tools_approval_mode="approve"' ...。

Agent 技能

skills/soniccraft/ 是一个 Agent Skills 软件包: SKILL.md(工作流、DSL 基础知识、时长启发式、混音实践、诊断修复表),以及按需参考资料(完整的 DSL 参考、提供商、混音指南、所有诊断代码、MCP 工具)和五个模板。它围绕 CLI 编写,因此适用于任何 Agent,并将 MCP 工具作为替代方案提及。

npx skills add user-github-me/soniccraft                                              # pick agents interactively
npx skills add user-github-me/soniccraft --skill soniccraft -a claude-code -a codex -a cursor -y   # project scope
npx skills add user-github-me/soniccraft --skill soniccraft -g -a claude-code -y                   # global

或者手动复制目录:cp -R skills/soniccraft ~/.claude/skills/(Claude Code,用户级),.claude/skills/soniccraft(Claude Code,项目级),~/.agents/skills/soniccraft 或 .agents/skills/soniccraft(Codex、Cursor 以及其他会读取 .agents/skills 的 Agent)。

Claude Code 插件(一步安装技能和 MCP 服务;需要将 soniccraft 加入 PATH):

claude plugin marketplace add user-github-me/soniccraft
claude plugin install soniccraft@soniccraft

如果插件的 MCP 服务显示为失败,通常是因为 soniccraft 二进制文件不在 PATH 中:请安装它(参见快速入门),然后重启 Claude Code。技能的设置部分会向 Agent 提供相同的说明。

对于 Codex,skills/soniccraft/agents/openai.yaml 声明了 MCP 依赖项,并以 soniccraft-mcp 启动。

提供商

提供商provider:凭据 / 设置默认语音词语时间戳
ElevenLabselevenlabsELEVENLABS_API_KEY无(需要 voice_id)是
OpenAI 兼容openaiOPENAI_API_KEY;其他服务使用 base_urlalloy估算
CartesiacartesiaCARTESIA_API_KEY无(需要 voice_id)是
Kokoro(Kokoro-FastAPI)kokoro本地服务:KOKORO_BASE_URL(默认 http://localhost:8880),可选的 KOKORO_API_KEYaf_heart是
Piperpiperpip install piper-tts;语音模型(voices_dir、PIPER_VOICES_DIR 或时间线旁的目录)无(需要 voice_id)估算
macOS 语音macos_saymacOSSamantha估算
自定义命令command你的 argv 模板无(需要 voice_id)估算
模拟mock无需设置(确定性合成语音)mock精确
  • ElevenLabs 默认请求原始 pcm_24000 音频(如果你配置的格式在当前套餐中不可用,则回退到该格式);eleven_v4 仅接受 stability 和 similarity_boost。
  • openai 是通用的 OpenAI 兼容 /audio/speech 客户端。OpenAI 自有的 TTS 模型将于 2027-01-06 退役;请将 base_url 指向 Kokoro-FastAPI、Speaches、LocalAI 或其他兼容服务。
  • Cartesia 使用 API 版本 2026-08-14,默认使用 sonic-3.6。
  • Kokoro:docker run -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-cpu:latest;词级时间戳来自其带字幕的语音端点。soniccraft providers 和 validate 会通过 300 ms TCP 连接探测本地服务(Kokoro-FastAPI,以及此设备或专用网络上的 OpenAI 兼容服务);未响应的服务不可用(no Kokoro-FastAPI server answered at http://localhost:8880),而 validate 会报告 provider_unavailable。
  • Piper 由 OHF-Voice/piper1-gpl 维护:先运行 pip install piper-tts,再将语音下载到项目中:python3 -m piper.download_voices en_US-lessac-medium --data-dir voices,并在提供方中设置 voices_dir: voices(或将语音下载到时间线文件旁边)。voice_id: en_US-lessac-medium 会按以下顺序在 voices_dir、$PIPER_VOICES_DIR、时间线目录和 ~/.local/share/piper/voices 中查找;soniccraft voices piper 会列出找到的内容,或列出已搜索的目录和下载命令;如果模型缺失,validate 会报告 unknown_voice。
  • macOS say 遇到未知名称时会静默回退到默认语音,因此 SonicCraft 会先使用 say -v '?' 检查语音名称(validate 会报告 unknown_voice,并给出最接近的已安装语音名称)。
  • API 密钥只会发送到提供方自己的 API 主机、此设备上的服务(仅发送提供方自己的密钥变量,例如 OPENAI_API_KEY),或 SONICCRAFT_ALLOWED_HOSTS 中列出的主机;如果密钥将被发送到其他位置,则会在发出任何请求前拒绝(provider_unavailable)。请参阅安全性。

各提供方的设置、模型、语音、配置和限制: skills/soniccraft/reference/providers.md。

环境变量用途
ELEVENLABS_API_KEY、OPENAI_API_KEY、CARTESIA_API_KEY提供方 API 密钥(可使用 api_key_env 按实例重命名)。
KOKORO_BASE_URL、KOKORO_API_KEYKokoro-FastAPI 地址和可选密钥。
PIPER_VOICES_DIR搜索 <voice_id>.onnx 的目录(在提供方的 voices_dir 之后搜索)。
SONICCRAFT_ALLOWED_HOSTS除各提供方自己的 API 主机和此设备上的服务(这些服务只会收到提供方自己的密钥变量)外,可接收 API 密钥的其他主机(以逗号分隔,支持 *.example.com 模式)。
SONICCRAFT_CACHE_DIRTTS 缓存位置(可由 --cache-dir 覆盖)。
SONICCRAFT_MAX_RENDER_GB单次渲染的内存预算,单位为 GB(默认值为 8);需要更多内存的时间线会在发出任何 TTS 请求前以 timeline_too_long 失败。
CLAUDE_PROJECT_DIRMCP 服务:当调用未指定 base_dir 时,用作相对路径的基目录。
SONICCRAFT_ALLOW_COMMANDMCP 服务:设为 1 后,时间线可以运行本地程序(command 提供方、piper command);默认关闭,与 soniccraft mcp --allow-command 相同。
SONICCRAFT_MCP_MAX_RENDERSMCP 服务:可同时运行的渲染数量(默认值为 2);后续渲染会等待。

字幕与 HyperFrames

output.export_subtitles 接受 true(= vtt + srt)或由 vtt、srt、json 和 transcript 组成的列表。 json(<stem>.words.json)保存字幕和每个单词的时间信息;transcript (<stem>.transcript.json)是一个以秒为单位的单词数组,格式与 HyperFrames 的 transcribe 命令所需格式一致。要为 HyperFrames 视频添加 SonicCraft 配音:

soniccraft render voiceover.yaml            # with output.export_subtitles: [vtt, transcript]
npx hyperframes transcribe voiceover.transcript.json --dir my-video

并在合成中从头开始播放处理完成的音频,例如 <audio id="voiceover" src="assets/voiceover.wav" data-start="0" data-duration="21.04"></audio>。

确定性与缓存

  • 确定性输出。 相同的时间线、TTS 缓存和二进制文件会生成逐字节相同的音频、字幕和清单。渲染产物中不会包含墙上时钟时间戳、随机种子、主机名或绝对路径;抖动和模拟语音使用固定种子;所有几何数据均以整数采样帧表示。阶段耗时和缓存统计信息只显示在实时报告中,不会写入清单,因此使用热缓存进行渲染时,写出的清单与全新渲染时相同。
  • 内容寻址的 TTS 缓存。 每个提示音的键都是对规范 JSON 计算的 blake3 哈希,其中包含所有影响音频的内容(提供方类型、API 版本、非默认基础 URL、模型、语音、语言、文本、设置、输出格式;对于 command/piper,还包括模板、程序及其内容的哈希、参数所指向的文件和 piper 模型)。缓存条目为 <key>.wav(32 位浮点、提供方原生采样率、未裁剪)和 <key>.json(元数据和单词时间信息),并以原子方式写入。更改一行只会重新合成一个提示音;调整时间、重新混音或重新母带处理都无需花费。无法写入缓存时会发出 cache_write_failed 警告;渲染仍会成功。
  • 位置: --cache-dir > SONICCRAFT_CACHE_DIR > <timeline dir>/.soniccraft/cache。 soniccraft cache info 和 soniccraft cache clear 可管理缓存;render --no-cache 会重新合成,但仍会刷新缓存。
  • 免费试运行。 plan 会使用可用的缓存时长,在进程内渲染模拟语音(精确),并根据每个提供方的语速(字符数/秒)估算其余时长;它绝不会调用提供方。

安全

时间线属于数据,通常由 Agent 根据其在某处找到的文本编写,因此 SonicCraft 会将其视为不可信内容:

  • 时间线中绝不存放密钥。 时间线中的 API 密钥、令牌和密码(名为 api_key/token/secret/password 的键、sk-... 值、URL 中的密码、提供商 command 中的密钥)都会触发 secret_in_timeline 错误,诊断信息绝不会重复显示这些内容(CLI 代码片段会显示 <redacted>)。密钥只能来自环境变量(api_key_env)。
  • 密钥只能发送到该去的地方: 各提供商自己的 API 主机、本机上的服务(仅限提供商自己的密钥变量:指向本地服务的 openai 实例使用 OPENAI_API_KEY,Kokoro 使用 KOKORO_API_KEY),或你在 SONICCRAFT_ALLOWED_HOSTS 中列出的主机(在 soniccraft 或 MCP 服务的环境中设置,绝不能写入时间线)。除非主机已列入允许列表,否则时间线不能将自己选择的变量(api_key_env: GITHUB_TOKEN)发送到本地服务,也不能将任何密钥发送到本地网络中的其他设备。若要将密钥用于网络上其他位置或远程的 OpenAI 兼容服务、远程 Kokoro 或区域端点,可设置例如 SONICCRAFT_ALLOWED_HOSTS=tts.example.com。其他任何情况都会在发出请求前被拒绝。不会跟随重定向,服务器回显的密钥也会从消息中移除。
  • 本地程序: command 提供商(以及使用自身 command 的 piper)会运行程序。通过 MCP 使用时,除非以 soniccraft mcp --allow-command(或 SONICCRAFT_ALLOW_COMMAND=1)启动,否则服务会拒绝运行这些程序。程序永远不会获得提供商 API 密钥,在各自的进程组中运行(超时或取消时会整体终止),并通过文件或标准输入获取提示文本:以 - 开头的参数会被拒绝。
  • 文件: 输出会先写入临时文件,只有整个渲染成功后才会放置到目标位置;渲染失败或取消时,先前的输出保持不变。只有同类型的输出才能替换现有文件(例如,-o notes.txt 指向文本文件时会被拒绝)。通过 MCP 使用时,时间线自身的 output.path 必须位于基础目录内(显式的 output_path 参数可指向任意位置)。
  • 读取: 时间线最多为 5 MB;/dev/zero、FIFO 或无限标准输入会立即失败。

资源

渲染时,会将母带混音保存在内存中:各音轨按窗口混音,直接写入一份完整时长的母带;分轨流式写入文件,母带处理则在原处完成。实测峰值(立体声,48 kHz):音乐为主时,WAV、MP3、ogg、opus 和 m4a 每分钟输出约占 23 MB(10 分钟的铺底音乐:245 MB);语音贯穿全程时,每分钟约占 40 MB(16 分钟的旁白:615 MB);24 位 FLAC 每分钟约占 85 MB,因为其编码器会保留整个数据流(10 分钟:870 MB)。SONICCRAFT_MAX_RENDER_GB(默认值为 8)会限制渲染资源用量:超过限制的渲染会在发出任何 TTS 请求前因 timeline_too_long 而失败,validate/plan 也会提前发出警告。时间线最长为 24 h。

架构

  timeline.yaml / .json
          |
          v
  +----------------+   diagnostics: code, path, line:col, hint
  | parse + lower  |-------------------------------------------------+
  | (core)         |                                                 |
  +-------+--------+                                                 |
          | IR (Program): resolved voices, defaults, anchors          |
          v                                                          |
  +----------------+  cached / estimated durations  +-------------+   |
  | synthesis      |------------------------------->|  layout     |   |
  | (tts + cache)  |  exact durations (render)      |  (frames)   |   |
  +-------+--------+                                +------+------+   |
          | audio + word timings                          | placements|
          v                                               v           v
  +------------------------------------------------------------+  reports:
  | DSP (dsp): decode -> resample -> trim -> normalize -> clips |  validate,
  | -> pan -> stems -> ducking -> master (R128 + true peak)     |  plan,
  +-------+----------------------------------------------------+  render
          |
          v
  encode (wav/mp3/flac native; ogg/opus/m4a via ffmpeg) + captions (vtt/srt/json/transcript)
  + stems + manifest + preview.html
Crate / 目录职责
soniccraft-coreDSL 原始 AST(serde + schemars)、带源代码范围的 YAML/JSON 解析、诊断、验证及降低为 IR、JSON Schema 生成、静态提供商元数据。纯函数式:除环境变量外不进行 I/O。
soniccraft-layout以采样帧为单位的时间线几何:调度、语音重叠策略、片段长度、内容结尾和尾部;ASCII 计划示意图。纯函数式。
soniccraft-captions词语对齐(提供商时间或估算值)、字幕分段、WebVTT/SRT/JSON/转录文本写入器。
soniccraft-dspAudioBuffer、解码(symphonia;ffmpeg 回退)、重采样(rubato)、分析、片段渲染、声像、闪避、响度(ebur128)、真峰值限制器、母带处理循环、编码器(WAV、LAME MP3、FLAC;ogg/opus/m4a 使用 ffmpeg)。
soniccraft-tts提供商 trait 和八个内置提供商、内容寻址缓存、时长估算器、重试与并发、凭证检查、语音列表。
soniccraft-engine编排:validate()、plan()(试运行)、render();环境检查;所有报告类型。
soniccraft-mcp将引擎作为工具公开的 MCP stdio 服务。
soniccraft(crates/soniccraft-cli)soniccraft 二进制文件(以及 soniccraft-mcp 启动器)。支持人类可读输出和 --json 输出。
packages/soniccraft-web-preview零依赖 WebAudio 可视化工具;引擎内嵌了一份 vendored 副本(crates/soniccraft-engine/assets/preview.html),供 render --preview 使用。
packages/soniccraft-mcpnpm 启动器(npx -y soniccraft-mcp):查找或下载发行版二进制文件,并运行 soniccraft mcp。
skills/soniccraftAgent Skill:SKILL.md、参考资料、模板。
examples可运行的时间线示例,使用免版税的程序生成素材。

依赖关系是单向的:layout → core;tts → {core, dsp};engine → {core, layout、 captions、dsp、tts};mcp → engine;cli → {engine、mcp}。完整规范见 docs/DESIGN.md;贡献者可在 docs/architecture.md 中了解整个处理流程。

路线图

  • 阶段 1:DSL 和编译器(已在 v0.1 中实现)
    • Timeline DSL v1.0(YAML/JSON)、JSON Schema、严格验证并提供「你是不是想说」提示
    • 降级为解析后的 IR:语音、提供方、默认值、锚点、依赖项检查
    • 精确到采样点的布局,支持语音重叠策略、试运行计划和 ASCII 图示
  • 阶段 2:合成(已在 v0.1 中实现)
    • 八种提供方:ElevenLabs、兼容 OpenAI 的服务、Cartesia、Kokoro、Piper、macOS say、command、mock
    • 内容寻址缓存、时长估算、并发限制、重试、凭据检查
  • 阶段 3:原生 DSP 和母带处理(已在 v0.1 中实现)
    • 解码、重采样、静音裁剪、源音频归一化、循环、淡入淡出、交叉淡化、声像
    • 侧链和提示驱动的闪避、EBU R128 母带处理循环、过采样真峰值限制器
    • WAV/MP3/FLAC 编码器;通过 ffmpeg 支持 ogg/opus/m4a
  • 阶段 4:Agent 接入方式和输出(已在 v0.1 中实现)
    • WebVTT、SRT、JSON 单词时间戳和 HyperFrames 转录文本
    • 支持 --json 的命令行、MCP 服务(两代协议)、Agent Skill、Claude Code 插件
    • 分轨、清单、网页预览、包含生成资源的示例
  • 阶段 5:分发(v0.1)
    • 发布工作流:为 macOS、Linux 和 Windows 提供预构建二进制文件(包含或不包含 LGPL MP3 编码器)、SHA256SUMS、第三方许可证声明以及 soniccraft-mcp npm 启动器
    • 包管理器:单行安装程序(install.sh、install.ps1)、Homebrew tap、Scoop bucket 和容器镜像
    • 在项目的 GitHub 所有者名下列出:官方 MCP Registry (io.github.user-github-me/soniccraft)、此仓库中的 Claude Code 插件市场,以及用于 npx skills add 的 Agent Skill
    • crates.io:cargo install soniccraft 和 cargo binstall soniccraft
    • npm:npx -y soniccraft-mcp(MCP 服务会下载并验证发布的二进制文件)
    • 精选目录:Anthropic 插件目录和 Cursor Marketplace

贡献

请参阅 CONTRIBUTING.md。每个组件的行为都在 docs/DESIGN.md 中有说明;请同时修改规范和代码。

许可证

SonicCraft 根据你的选择,采用 Apache License, Version 2.0 或 MIT license 许可。除非你明确另行声明,否则根据 Apache-2.0 许可证的定义,任何有意提交以纳入本项目的贡献均按上述双重许可授权,不附加任何条款或条件。

原生 MP3 编码使用 LAME 3.100(LGPL-2.0-or-later),通过 mp3lame-sys 和 mp3lame-encoder crate(LGPL-3.0)静态链接,并由默认启用的 cargo 功能 mp3 控制。使用 --no-default-features 构建即可将其排除(例如: cargo install --locked --path crates/soniccraft-cli --no-default-features);此时,若有 ffmpeg,MP3 输出会通过 ffmpeg 处理(否则会返回 format_requires_ffmpeg)。-no-mp3 发布归档以这种方式构建,不包含任何 LGPL 代码。其他发布归档会在 licenses/ 中附带许可证文本,licenses/README.md 说明了如何使用修改后的 LAME 重新构建 soniccraft。音频解码使用 symphonia,dirs 使用 option-ext,两者均采用 MPL-2.0(文件级 copyleft;未经修改地使用,源码可在 crates.io 上获取)。其他所有依赖均采用宽松许可证(MIT、Apache-2.0、BSD-3-Clause、ISC、Zlib、Unicode-3.0)。每个发布归档都会在 THIRD-PARTY-LICENSES.txt 中列出其中编译的所有 crate 及其随附的许可证文本,CI 则通过 cargo-deny (deny.toml) 强制执行此政策。

examples/*/assets/ 中的示例音频由 scripts/generate-example-assets.sh 从头合成,并采用相同的许可证。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。