进阶 docs.voicebox.sh 2026-10-11 09:58:06 · 18 阅读

第11章 MCP Server:本地AI语音代理集成指南

概述 MCP Server 让 Claude Code、Cursor、Cline 或任何支持 MCP 的 agent 用你克隆的声音说话——全程本地运行,不依赖云端。 概述

Voicebox 内置了一个 Model Context Protocol(MCP)server,让本地 AI agent 可以直接调用你的 Voicebox:用指定的声音档案朗读文本、转录音频、列出录音或声音档案。这个 server 与 Voicebox 跑在同一个进程里,通过 Streamable HTTP 挂载在 /mcp 路径上。

Agent 请求朗读 → Voicebox 在你的音箱上播放音频 → 屏幕上会浮出一个悬浮条,在整个播放期间显示声音名称,让你始终清楚机器正在播放什么。

MCP 在 0.5.0 版本随 Dictation 和 Voice Personalities 一起发布。设计目标是“为你机器上的每个 agent 提供本地语音层”——同一个应用既能录制你的声音,也能用你克隆的任意声音档案生成语音响应。

快速接入

Claude Code

claude mcp add voicebox \ --transport http \ --url http://127.0.0.1:17493/mcp \ --header "X-Voicebox-Client-Id: claude-code"

Cursor / Windsurf / VS Code MCP / 任何 HTTP MCP 客户端

把下面内容放进客户端的 MCP 配置(通常是 .mcp.json 或设置界面):

{ "mcpServers": { "voicebox": { "url": "http://127.0.0.1:17493/mcp", "headers": { "X-Voicebox-Client-Id": "cursor" } } } }

把 cursor 改成任何你想要的名称,它会显示在 Voicebox → Settings → MCP 里。这个值只是 per-client 声音绑定的标识符——不是密钥,也不是凭据。

只支持 stdio 的客户端

桌面应用自带一个 stdio 桥接程序 voicebox-mcp。让客户端指向这个二进制文件的绝对路径:

{ "mcpServers": { "voicebox": { "command": "/Applications/Voicebox.app/Contents/MacOS/voicebox-mcp", "env": { "VOICEBOX_CLIENT_ID": "claude-desktop" } } } }{ "mcpServers": { "voicebox": { "command": "C:\\Program Files\\Voicebox\\voicebox-mcp.exe", "env": { "VOICEBOX_CLIENT_ID": "claude-desktop" } } } }{ "mcpServers": { "voicebox": { "command": "/opt/voicebox/voicebox-mcp", "env": { "VOICEBOX_CLIENT_ID": "claude-desktop" } } } }

这个桥接程序会等待 Voicebox 后端启动(最长 30 秒),然后通过 Streamable HTTP 把 stdio 上的 JSON-RPC 转发过去。桥接程序要连接成功,Voicebox 必须处于运行状态。

工具

工具 用途 voicebox_speak 用指定的声音档案朗读文本。返回一个 generation_id 供轮询。voicebox_transcribe 用 Whisper 转录 base64 音频或本地绝对路径的音频文件。voicebox_list_captures 列出最近的录音及其转录文本,支持分页。voicebox_list_profiles 列出可用的声音档案(克隆的 + 预设的)。

voicebox_speak

voicebox_speak({ text: "Deploy complete.", profile?: "Morgan", // name or id; falls back to per-client binding, then default engine?: "qwen", // qwen | qwen_custom_voice | luxtts | chatterbox | chatterbox_turbo | tada | kokoro personality?: true, // rewrite via the profile's personality LLM before TTS; default comes from the per-client binding language?: "en", })

返回:

{ "generation_id": "…", "status": "generating", "profile": "Morgan", "source": "mcp", "poll_url": "/generate//status" }

纯 TTS——personality: false(或省略且绑定默认值为 false)。文本按原样朗读。 人设模式——personality: true,且该声音档案必须设置了 personality prompt。LLM 会先以人设口吻改写文本,再送入 TTS。详见 Voice Personalities。

voicebox_transcribe

voicebox_transcribe({ audio_base64?: "", // exactly one of these two audio_path?: "/absolute/path/to/file.wav", language?: "en", model?: "turbo", // base | small | medium | large | turbo })

返回 { text, duration, language, model }。两种传入方式都有 200 MB 上限。

voicebox_list_captures

{ limit?: 20, offset?: 0 } → { captures: [...], total }。limit 会被限制在 1..=200 之间。

voicebox_list_profiles

无参数 → { profiles: [{ id, name, voice_type, language, has_personality }] }。

声音解析

每次调用 voicebox_speak(以及 POST /speak)都按以下顺序解析声音档案:

先按传入的名称(不区分大小写)或 id 查找。如果名称/id 不匹配,调用会直接报错——server 不会静默回退。通过 X-Voicebox-Client-Id 请求头查找。在 Voicebox → Settings → MCP 中管理。可以给 Claude Code 固定用 Morgan、给 Cursor 固定用 Scarlett 等。capture_settings.default_playback_voice_id——与 Captures 标签页中"Play as voice"操作使用的默认声音相同。

如果三者都无法解析出声音档案,工具会返回一个指向 Settings 的明确错误提示。

Per-client 绑定

Voicebox → Settings → MCP 会为 server 接触过的每个 client_id 显示一行记录,并提供可复制到各个 agent 的配置片段。每行包含:

字段 用途 label 设置界面中的显示名称(如"Claude Code")。profile_id 未传 profile 时该客户端使用的声音。default_engine 覆盖该客户端的 TTS 引擎。default_personality 为 true 时,voicebox_speak 默认经过该档案的 personality LLM 改写。last_seen_at server 最近一次收到该客户端请求的时间。

last_seen_at 由中间件在每个 /mcp/* 请求上自动打点——当你不确定配置是否生效时很有用。

朗读悬浮条

每个 agent 发起的朗读都会以和 Dictation 相同的方式浮出悬浮条,新增一个 Speaking 状态,显示声音档案名称和已播放时长。这个悬浮条刻意做得非常醒目——静默的后台 TTS 是信任隐患,所以 Voicebox 始终显示正在朗读的内容和使用的声音。

在底层,后端会在 GET /events/speak 上广播 speak-start 和 speak-end 事件,DictateWindow 通过 SSE 订阅这些事件。当两者同时需要渲染时,朗读悬浮条会覆盖录音会话——屏幕上不会同时出现两个悬浮条。

非 MCP 的 REST 接口

POST /speak 是同一条代码路径的轻量封装,供不支持 MCP 的调用方使用——shell 脚本、ACP、A2A、GitHub Actions 等等。

curl -X POST http://127.0.0.1:17493/speak \ -H 'Content-Type: application/json' \ -H 'X-Voicebox-Client-Id: ci' \ -d '{"text":"Build complete.","profile":"Morgan"}'

请求体字段与 MCP 工具一致:text、可选的 profile、engine、personality、language。返回一个 GenerationResponse——与 POST /generate 的结构相同。

OpenAI 兼容 API

Voicebox 还在 POST /v1/audio/speech 和 GET /v1/models 上提供 OpenAI 的 text-to-speech API,因此任何已对接 OpenAI TTS 的工具(官方 openai SDK、Open WebUI、Home Assistant、SillyTavern、shell 脚本)只需改一下 base URL 就能变成本地离线 TTS。Voicebox 不需要 API key:传入任意非空字符串即可,Authorization 请求头会被忽略。

from openai import OpenAI

client = OpenAI(base_url="http://127.0.0.1:17493/v1", api_key="voicebox")

audio = client.audio.speech.create( model="tts-1", # or a Voicebox engine: "qwen", "chatterbox", "kokoro"... voice="Morgan", # a Voicebox voice profile, by name or id input="Build complete.", response_format="mp3", ) audio.write_to_file("build.mp3")

curl -X POST http://127.0.0.1:17493/v1/audio/speech \ -H 'Content-Type: application/json' \ -d '{"model":"tts-1","voice":"Morgan","input":"Build complete."}' \ --output build.wav

OpenAI 字段与 Voicebox 的对应关系:

字段 在 Voicebox 中的含义 voice 声音档案,按名称(不区分大小写)或 id。省略时走声音解析链:先查 X-Voicebox-Client-Id 绑定,再查默认播放声音。没有内置的 alloy/nova 声音——需要自己创建档案(一个名为"Alloy"的 Kokoro 预设档案完全可以)。model TTS 引擎(qwen、qwen_custom_voice、luxtts、chatterbox、chatterbox_turbo、tada、kokoro)或模型变体如 qwen-tts-0.6B。OpenAI 自己的 id tts-1、tts-1-hd 和 gpt-4o-mini-tts 会被接受为“该档案配置的引擎”的别名,因此客户端代码无需修改。GET /v1/models 列出所有可接受的 id。模型必须已下载(Voicebox → Models)。input 要朗读的文本,最长 10,000 字符,使用档案的语言。长文本会像 Voicebox 其他功能一样按句子边界分块。response_format wav(默认)、mp3、flac、opus、pcm(按 OpenAI 定义:24 kHz 的原始 16 位小端单声道,运行在其他采样率的引擎会重采样)以及 aac(需要 server 的 PATH 中有 ffmpeg)。speed 0.25–4.0。在合成之后以保音高的方式做时间拉伸。 instructions 在引擎支持时(Qwen)作为引擎的 instruct prompt 传入。

档案的音效链会被应用,输出会做响度归一化,与应用内的行为完全一致。响应是一次性返回完整音频(暂不支持分块流式);不会写入生成历史。

错误使用 OpenAI 的 {"error": {"message", "type", "param", "code"}} 格式,SDK 的异常会带上具体原因:voice_not_found、voice_required、model_not_found、model_not_downloaded、engine_not_compatible、unsupported_format。参数校验错误返回 400,而不是 FastAPI 的 422。

这个端点与 API 其他部分共享同一信任边界:无鉴权、默认只监听 localhost。如果你把 Voicebox 暴露到网络上供 Open WebUI 之类的工具使用,请参考 Remote Mode,并置于防火墙或 VPN 之后。

调试

可以用 MCP Inspector 直接测试工具,不必通过 agent:

npx @modelcontextprotocol/inspector http://127.0.0.1:17493/mcp

先用 voicebox_list_profiles 确认连接正常,再用 voicebox_speak 做端到端测试——你应该能听到音频,并在 Captures 标签页里看到生成记录。

如果 agent 连不上 server,首先要检查 Voicebox 是否在运行——后端只在桌面应用打开时监听。stdio 桥接程序在 30 秒健康等待超时后,会在客户端侧以 JSON-RPC 错误的形式暴露这个问题。

安全性

仅限 localhost。server 绑定在 127.0.0.1。如果要把 Voicebox 指向非回环接口(例如在可信网络上的 remote-mode),请添加 bearer token——这在路线图上,但 0.5.0 尚未实现。目前没有鉴权。任何能连接你回环地址的进程都可以调用 MCP。这与 Voicebox REST API 的其余部分共享同一信任边界,对单用户本地工具来说是合理的。audio_path 的读取在相同信任边界内不受限制。如果你在共享主机上写脚本,建议改用 audio_base64,省去路径沙箱方面的顾虑。声音克隆需征得同意。参见 Voice Cloning——agent 能用某个人的声音调用 voicebox_speak,并不改变“克隆谁的声音”在伦理上的问题。

实现说明

传输方式:Streamable HTTP(2025 年 11 月版 MCP 规范,SSE 之后的标准)。Claude Code、Cursor、Windsurf 和 VS Code MCP 扩展都已支持。包命名:后端包命名为 backend/mcp_server/ 而不是 mcp,以避免遮蔽 FastMCP 内部导入的 PyPI mcp 包。依赖:fastmcp>=3.0,<4.0,sse-starlette>=2.0。Lifespan:挂载 FastMCP 需要在 FastAPI() 上使用 lifespan= 参数——startup/shutdown 事件装饰器与 FastMCP 的 Streamable HTTP session manager 不兼容。Voicebox 的 app.py 把两者组合进同一个 async context manager。

完整的开发者视角代码导览,参见仓库中的 backend/mcp_server/README.md。

下一步

Voice Personalities 为需要以人设口吻改写文本后再朗读的 agent 使用人设模式(personality: true)。Dictation 浮现 agent 语音的悬浮条与浮现你听写的悬浮条是同一个——一条闭环,一个心智模型。Captures 每个 agent 发起的朗读都会连同生成的音频落入 Captures 标签页——可以回放、下载、再利用。

在 GitHub 上编辑 Voice Personalities 给声音档案附加人设,生成全新的人设台词,用他们的口吻改写输入文本——全部由本地 LLM 驱动。Stories Editor 用时间轴编辑器创建多声部叙事

评论 (0)