尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

VoiceStudio MCP 服务器接入指南:让 AI 智能体以你的声音说话

VoiceStudio MCP 服务器接入指南:让 AI 智能体以你的声音说话 VoiceStudio MCP 服务器接入指南让 AI 智能体以你的声音说话【免费下载链接】VoiceStudioVoiceStudio is the open-source, fully-local ElevenLabs alternative — voice cloning, voice design, video dubbing, dictation, transcription audiobook creation in 646 languages.项目地址: https://gitcode.com/GitHub_Trending/om/VoiceStudioVoiceStudio 内置了一个挂载在运行中后端之上的 MCPModel Context Protocol服务器地址为/mcp无需额外启动任何进程。通过它Claude Code、Cursor 等 AI 智能体可以直接调用语音合成、声音克隆、语音转写与音色列表等工具在完全本地化的环境中以你指定的音色发声。读完本文你将掌握/mcp端点的完整工具面、三种音频输出模式与文件输入安全边界、Streamable HTTP 与 stdio 两种连接方式以及每个智能体绑定不同音色的完整配置方案。核心思路MCP 直接挂在运行中的后端上传统做法是单独拉起一个 MCP 进程再与后端通信而 VoiceStudio 选择把 FastMCP 应用直接 sub-mount 到主 FastAPI 应用的/mcp路径上。这意味着只要 VoiceStudio 打开、后端在http://localhost:3900上监听MCP 端点就天然可用不需要部署额外的常驻服务。从源码看这一挂载由 backend/mcp_server.py 中的mount_mcp(app)函数完成通过create_mcp_server()构建 FastMCP 实例并显式将streamable_http_path设置为/避免 sub-mount 时出现/mcp/mcp双重前缀调用mcp.streamable_http_app()得到 ASGI 应用后执行app.mount(/mcp, mcp_app)并把 session manager 存入app.state供主应用生命周期管理挂载是尽力而为的任何Exception或SystemExit都会被捕获并降级为/mcp已禁用的日志绝不影响后端主流程启动对应 issue #1156 的退出隔离设计。对应地tests/test_mcp_mount.py 断言了create_mcp_server()构建出的工具集、streamable_http_app()的根路径路由以及主应用main导入后路由表中确实存在/mcpMount。工具面七个工具覆盖合成、克隆、转写、枚举、健康检查create_mcp_server()暴露的工具与文档描述一致测试test_server_builds_with_expected_tools逐一校验了工具名称集合工具作用关键参数generate_speechtext → WAV。默认使用该智能体绑定的音色除非显式传入profile_id默认返回 base64也可切换为 URL 文件见输出模式text必填、language默认Auto、profile_id、instruct风格指令如whisper、excited、narrator、speed0.5–2.0默认 1.0、steps8快速草稿 / 16均衡 / 32高质量clone_voice参考音频base64或 base path 下的ref_audio_path→ 新建音色档案返回可用于generate_speech的profile_idname必填、ref_audio_base64/ref_audio_path二选一、ref_text参考音频转写文本可提升部分引擎质量、instruct、languagetranscribe音频base64 或audio_path→ 文本支持 646 种语言audio_base64/audio_path二选一、language可选提示缺省自动检测list_voices/list_personalities/list_languages枚举可用的音色档案、人格预设、语言列表—check_health后端状态 当前激活的 GPU 设备—除工具外服务器还暴露两类 MCP Resourcesvoice://{profile_id}音色档案元数据和history://recent最近 20 条生成历史。所有工具内部都通过httpx调用后端的 REST 接口/generate、/profiles、/transcribe、/health、/history、/personalities后端 API 基地址由OMNIVOICE_API_URL指定默认http://localhost:3900。几个值得注意的实现细节data URI 容错LLM 智能体在把音频交给文件上传工具时常常会加上data:audio/wav;base64,…前缀。_decode_ref_audio()会先剥离data:前缀再解码让这种常见形态直接通过验证而不是校验失败见 tests/test_mcp_mount.py 的test_decode_ref_audio_strips_data_uri_prefix。按魔数嗅探扩展名_sniff_audio_ext()通过文件头字节识别真实容器格式fLaC→.flac、ID3/0xfffb→.mp3、OggS→.ogg、ftyp→.m4a其余默认.wav。原因是/profiles路由会按上传文件名扩展名存储参考片段而下游消费者HTML5 播放、ffmpeg 管线把扩展名当作格式提示——MP3 存成.wav会在那里静默失败issue #1198。200 MB 输入上限_MAX_INPUT_BYTES 200 * 1024 * 1024同时约束 base64 与路径两条输入通道防止异常/恶意智能体提交无界 blobbase64 通道在解码前就会按编码长度预检避免浪费解码开销。输出模式与文件输入把音频移出智能体上下文LLM 智能体为进入上下文的每个字节付费而 base64 形式的 WAV 是巨量字节——一段短片段就接近单次结果上限一段旁白直接超限。为此 VoiceStudio 提供了三个环境变量把音频从对话中移到磁盘上让智能体把路径交给播放器或其他工具。变量取值效果OMNIVOICE_MCP_OUTPUT_MODEresources默认·files·bothresources内联返回wav_base64原始契约files返回audio_url后端本就保留渲染产物并托管在/audio/audio_id.wav且当配置了 base path 时返回output_path写入该目录的 WAVboth全部返回OMNIVOICE_MCP_TIMEOUT_S秒数默认120工具等待后端返回的时长。CPU 主机渲染一段旁白需要数分钟且生成是串行的排在他人渲染后面的智能体可能超过默认值建议与OMNIVOICE_GENERATE_TIMEOUT_S同步调大OMNIVOICE_MCP_BASE_PATH一个目录文件形态流量的安全边界。transcribe(audio_path…)与clone_voice(ref_audio_path…)只能从该目录内读取相对路径相对它解析绝对路径必须已经位于其中符号链接在检查前先被解析files 模式也只写入该目录。未配置 base path 时路径类参数会被拒绝并给出原因这些变量的解析逻辑在 backend/mcp_server.py 中_output_mode()对未识别值回退到resources并告警而非失败_post_timeout_s()对非数字或非正值回退到 120 秒_base_path()对配置的目录做realpath规范化。测试 tests/test_mcp_output_mode.py 用参数化用例覆盖了这些回退分支以及_speech_result()在三种模式下返回字段的差异。安全边界受限的 no-follow 描述符仅仅校验路径字符串并不足以防御 TOCTOU 攻击——攻击者可以在校验通过后、打开文件前把被检查的父目录替换成指向外部的符号链接。VoiceStudio 的防护是纵深式的路径解析_resolve_under_base()对相对路径与绝对路径两侧都做realpath再通过commonpath判定是否落在 base path 内任何逃逸都抛出让智能体可读的ValueError无跟随打开_open_under_base()尽可能利用O_NOFOLLOW、O_CLOEXEC与dir_fd以目录描述符逐级打开路径组件从根上杜绝组件被替换后重定向读取打开后复核_opened_file_is_confined()在描述符打开后通过/proc/self/fd/fd或fstat与samestat复核描述符仍指向 base path 内的普通文件确保并发替换父目录也无法把读取带出边界。test_concurrent_parent_replacement_cannot_escape_base专门模拟了解析完成后把目录改名并替换为指向外部的符号链接的攻击断言读取被拒绝test_speech_result_does_not_follow_existing_output_symlink则验证写输出时不会跟随已存在的符号链接去覆盖外部文件。配置位置与双容器注意事项这些变量设置在后端的环境上启动器、systemd service 文件、Docker-e或独立运行python -m backend.mcp_server时设置在该入口的env上。base path 必须对后端与智能体双方都可见若二者运行在不同容器或不同文件系统命名空间需要在两边以相同路径挂载同一个共享目录output_path以后端命名空间为准报告智能体的工作目录仅当该共享挂载存在时才适用。按此配置OMNIVOICE_MCP_OUTPUT_MODEfiles能把每次渲染都挡在智能体上下文之外同时仍返回智能体可用的路径。可选参考模板见 docs/mcp.json其中注释说明了两种连接模式与输出模式设置的要点。连接方式一Streamable HTTP现代客户端将客户端直接指向挂载端点即可http://localhost:3900/mcp若要把该智能体绑定到特定音色发送X-VoiceStudio-Client-Id请求头例如claude-code具体见下文按智能体绑定音色。注意 FastMCP 在内部读取的是x-omnivoice-client-id请求头_current_client_id()从请求上下文中读取两种大小写写法均可命中。容器内或跨机器运行的智能体MCP SDK 默认拒绝非 localhost 的 Host 头DNS 重绑定防护。此时需设置OMNIVOICE_MCP_ALLOWED_HOSTS值为智能体来源主机模式的逗号分隔列表例如host.containers.internal:*,192.168.1.50:*在 backend/mcp_server.py 中create_mcp_server()会把这些主机模式扩展进transport_security.allowed_hosts并同时为每种主机生成http://与https://两种 Origin 加入allowed_origins浏览器类客户端或反向代理可能发送 Origin 头。测试test_mcp_allowed_hosts_env_extends_allowlist验证了这一行为。请务必把该端点限制在可信局域网内或置于 TLS 之后如 Tailscale Serve、带 HTTPS 的反向代理——MCP 传输本身不做认证切勿暴露在公网。连接方式二stdio只支持 stdio 的客户端对于只支持 stdio 的 MCP 客户端仓库附带了一个代理 shimbackend/mcp_shim/main.py负责 stdio ↔ 挂载的 HTTP 端点之间的中继。把它填入客户端的 MCP 配置即可docs/mcp.json 是现成模板{ mcpServers: { omnivoice: { command: python, args: [-m, backend.mcp_shim], cwd: /path/to/VoiceStudio, env: { OMNIVOICE_PORT: 3900, OMNIVOICE_CLIENT_ID: claude-code } } } }shim 的行为细节均可在源码中印证环境变量OMNIVOICE_PORT后端端口默认 3900、OMNIVOICE_HOST默认 127.0.0.1、OMNIVOICE_CLIENT_ID作为X-OmniVoice-Client-Id头转发到每个请求从而让按智能体绑定音色在 stdio 路径下同样生效等待后端就绪启动后先以 30 秒超时轮询/health后端未响应则以退出码 2 结束并提示应用是否在运行JSON-RPC 中继逐行读取 stdin 上的 JSON-RPC 消息POST 到http://host:port/mcp/透传mcp-session-id会话头把 SSE 流或 JSON 响应写回 stdoutstdout 只允许 JSON-RPC诊断信息一律走 stderr干净退出客户端关闭时退出码为 0传输错误为 1。按智能体绑定音色Per-agent voices每个智能体用一个client id标识自己。把 client id 绑定到音色档案就能让不同智能体说不同的话——Claude Code 说 Morgan 的声音Cursor 说 Scarlett 的声音。每次generate_speech调用的音色解析优先级显式传入的profile_id参数否则使用调用方智能体的绑定音色否则使用全局默认音色core.prefs中mcp_default_profile_id偏好否则使用 VoiceStudio 的默认音色。这套优先级在 backend/services/mcp_bindings.py 的resolve_voice()中实现返回{profile_id, default_engine, source}其中source取explicit/binding/global/none便于诊断。绑定数据持久化在mcp_client_bindings表中touch_last_seen()会记录最后活跃时间用于排序且是尽力而为的遥测绝不抛异常。绑定管理走回环 REST APISettings 界面用的就是这套接口路由器位于 backend/api/routers/mcp_bindings.py挂载前缀/api/mcp并受管理员鉴权保护# 列出全部绑定按最近活跃排序 curl localhost:3900/api/mcp/bindings # 绑定 claude-code → 某个音色档案 curl -X PUT localhost:3900/api/mcp/bindings \ -H Content-Type: application/json \ -d {client_id:claude-code,label:Claude Code,profile_id:voice-profile-id} # 移除绑定 curl -X DELETE localhost:3900/api/mcp/bindings/claude-codeupsert_binding()采用合并更新语义已存在的绑定若某个字段传入null则保留原值新建记录则字段默认为空client_id为空字符串会直接拒绝。绑定接口还支持可选的default_engine字段允许把某个智能体固定到特定引擎。任何代表你发声的智能体都应优先使用经授权验证consent-verified的音色档案相关背景可参考 docs/competitive-analysis.md。禁用 MCP设置OMNIVOICE_MCP_DISABLE1即可完全跳过/mcp挂载。测试test_mcp_disable_env_skips_mount验证了设置该变量后主应用路由表中不再包含/mcp且测试结束后会恢复默认挂载状态。此外main.py中 MCP session manager 的启动是best-effort的它不在启动关键路径上若在OMNIVOICE_MCP_START_TIMEOUT_S默认 30 秒内未就绪后端会正常提供服务而不等待 MCP对应 issue #632。独立运行模式与故障排查除了内嵌挂载MCP 服务器也支持作为独立 CLI 运行入口backend.mcp_server的main()python -m backend.mcp_server # stdio 传输如 Claude Desktop python -m backend.mcp_server --sse # SSE 传输默认端口 8765面向远程智能体独立运行时 MCP SDK 缺失是致命错误以非零退出码结束与内嵌路径的降级不阻塞契约不同。内嵌场景下 SDK 是惰性导入的_ensure_mcp()未使用 MCP 时后端启动不会为它付出导入开销若导入失败错误信息会携带底层原因例如 Windows 上 pywin32 传递依赖损坏避免误诊为未安装。排查提示若提示 SDK 缺失应用环境内可用启动器的 Clean Retry 或uv sync重装独立运行时执行pip install mcp[cli]。小结VoiceStudio 的 MCP 支持是一个零额外进程的设计/mcp端点随后端就绪即用七个工具覆盖语音合成到克隆转写的全链路OMNIVOICE_MCP_OUTPUT_MODE与OMNIVOICE_MCP_BASE_PATH的组合在省 token 与安全边界之间取得平衡X-VoiceStudio-Client-Id/OMNIVOICE_CLIENT_ID让每个智能体拥有专属音色。对需要进一步定制或排查的开发者核心实现集中在 backend/mcp_server.py 与 backend/mcp_shim/main.py行为契约可对照 tests/test_mcp_mount.py 与 tests/test_mcp_output_mode.py 阅读。【免费下载链接】VoiceStudioVoiceStudio is the open-source, fully-local ElevenLabs alternative — voice cloning, voice design, video dubbing, dictation, transcription audiobook creation in 646 languages.项目地址: https://gitcode.com/GitHub_Trending/om/VoiceStudio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表