Skip to main content
Glama
Ccccr231
by Ccccr231
README.md
# gpt-soviuts-mcp

[![tests](https://github.com/Ccccr231/gpt-soviuts-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/Ccccr231/gpt-soviuts-mcp/actions/workflows/ci.yml)

GPT-SoVITS MCP Server:本地语音合成的 MCP 桥接服务。

把已经运行的 GPT-SoVITS `api_v2.py` 服务接入 Codex 和其他 MCP 客户端。Python 3.11+;使用官方 MCP Python SDK **2.3.0**,支持 stdio 和 Streamable HTTP。

MVP 提供五个工具、参考音频情绪映射、受限音频资源读取和 WAV 对话拼接。不需要修改、导入或重新分发 GPT-SoVITS 核心源码。

## 安装与启动

```shell
git clone https://github.com/Ccccr231/gpt-soviuts-mcp.git
cd gpt-soviuts-mcp
```

```powershell
# 在本项目根目录,使用正常安装的 Python 3.11+(与 GPT-SoVITS 环境隔离)
python -m venv .venv
.venv/Scripts/python -m pip install -e ".[dev]"
Copy-Item config.example.toml config.local.toml
```

Linux/macOS 使用 `.venv/bin/python`。也可使用 `uv venv --python 3.11`、`uv pip install -e '.[dev]'`。复现锁定环境使用 `uv sync --frozen --extra dev`。

1. 修改 `config.local.toml`,填写自己的参考录音路径及其**准确转写**。文件路径相对于配置文件目录。
2. 在 GPT-SoVITS 自己的环境和安装目录启动 API:

```powershell
# 在 GPT-SoVITS 安装目录运行;整合包可用 runtime/python.exe
python api_v2.py -a 127.0.0.1 -p 9880 -c GPT_SoVITS/configs/tts_infer.yaml
```

3. 启动 MCP:

```powershell
.venv/Scripts/python -m gpt_sovits_mcp --config config.local.toml
# 或本地 HTTP,端点 http://127.0.0.1:8000/mcp
.venv/Scripts/python -m gpt_sovits_mcp --config config.local.toml --transport streamable-http
```

stdio 启动后等待客户端输入是正常行为,日志写 stderr。项目不自动启动/停止上游、不切换模型、不调用上游 `/control`。

示例配置不附带录音,仍可启动并列出音色,但录音缺失时会显示 `available=false` 并拒绝合成。最小可用配置只需一个音色和一条 neutral 参考;五种情绪完整体验需要相应录音。

## 五个工具

| 工具 | 输入 | 返回 |
| --- | --- | --- |
| `list_voices` | 无 | 音色、情绪、参考强度和文件可用性,不泄露参考路径 |
| `synthesize_speech` | `text`, `voice_id`,及下表可选项 | `resource_uri`, MIME、大小、实际选择的情绪和强度;stdio 额外返回 `file_path` |
| `set_emotion` | `voice_id`, `emotion`, `intensity=1` | 显式 `emotion_preset`,用于后续请求 |
| `synthesize_dialogue` | `dialogue={segments:[...], pause_ms:250}` | 一个 WAV 资源及每段起止时间 |
| `get_tts_status` | 无 | 连通性、OpenAPI 字段兼容性、进程内繁忙状态 |

`synthesize_speech` 可选项:

| 参数 | 默认/范围 | 含义 |
| --- | --- | --- |
| `text_lang` | `zh` | `zh/en/ja/ko/yue/auto/all_zh/all_ja/all_ko/all_yue`;具体模型不支持的语言由上游拒绝 |
| `emotion` | `neutral` | `neutral/gentle/angry/shy/tsundere`,可在配置中添加其他标识符 |
| `intensity` | `1.0`,0–1 | 自定义离散参考选择,见下文 |
| `speed` | `1.0`,0.5–2 | 映射为上游 `speed_factor` |
| `prompt_text` | 所选参考的转写 | 映射为上游 `prompt_text`;空字符串允许无转写推理 |
| `prompt_lang` | 所选参考的语言 | 参考文本语言 |
| `output_format` | `wav` | `wav/ogg/aac`;依赖上游相应编码能力 |
| `emotion_preset` | 无 | `set_emotion` 返回的预设 ID,覆盖本次 `emotion/intensity` |

示例工具参数:

```json
{"text":"你好,今天想学习什么?","voice_id":"demo","emotion":"gentle","intensity":0.7,"speed":1.0,"output_format":"wav"}
```

```json
{"dialogue":{"segments":[{"text":"你来了。","voice_id":"demo","emotion":"gentle"},{"text":"才没有等你呢。","voice_id":"demo","emotion":"tsundere"}],"pause_ms":300}}
```

## 情绪与 intensity 的实际语义

GPT-SoVITS api_v2 没有原生 `emotion` 或 `intensity` 字段。这里通过不同表情语气的参考录音引导生成,**不保证连续或严格可测量的情绪强弱**,也不把采样温度伪装成情绪强度。

- `intensity=0`:选择 neutral。
- 大于 0:从所请求情绪的参考列表选择强度差最小的条目;相同距离取较低强度。例如 angry 有 0.4/1.0 两条参考,请求 0.5 时选 0.4。
- 仅有一条参考时,大于 0 的强度都使用这条参考。返回值包含 `selected_intensity`,方便客户端判断。
- 缺少所请求情绪时直接报错,不隐式退回 neutral。
- 扩展情绪:增加 `[[voices.demo.emotions.happy]]` 等配置;标识符限小写字母开头及数字、`_`、`-`。
- `set_emotion` 创建有效期一小时、进程内最多 256 个的预设。将返回的 `emotion_preset` 显式传入合成请求。不会修改全局默认状态;重启或被容量淘汰后需重新创建。

所有音色使用上游**当前已加载的同一组 GPT/SoVITS 模型**,通过参考音频区分音色。需要多组微调权重时,为各模型启动独立 API/桥接实例。MVP 不在请求之间切换全局权重。

## 音频路径与资源

合成返回 `audio://generated/<随机ID>.wav` 等 URI。客户端用标准 `resources/read` 获取二进制音频(MCP 返回 base64 blob),这不是 HTTP 下载链接。MCP Host 是否支持保存/播放资源取决于客户端。

stdio 返回的 `file_path` 是桥接所在机器上、配置输出目录内的绝对路径。远程 HTTP 只返回 URI,避免把服务端路径当成客户端可访问路径。

工具不接收任意参考路径、输出文件名或下载 URL。参考文件只来自管理员配置并限制在 `reference_roots` 内;读取资源只允许随机 ID 和已知扩展名,校验解析后的路径包含关系以阻止 `..`、绝对路径和符号链接越界。配置目录和输出目录应只允许可信管理员写入,避免本地攻击者并发替换文件。

上游 GPT-SoVITS 与桥接默认同机运行。远程 backend 必须使用与桥接相同路径的共享文件系统;桥接不会上传参考录音。参考文本覆盖后必须仍与所选录音匹配。

## Codex 接入

见 [完整配置示例](docs/codex.md)。在 `~/.codex/config.toml` 添加(替换绝对路径):

```toml
[mcp_servers.gpt_sovits]
command = 'C:\path\gpt-sovits-mcp\.venv\Scripts\python.exe'
args = ['-m', 'gpt_sovits_mcp', '--config', 'C:\path\gpt-sovits-mcp\config.local.toml']
startup_timeout_sec = 20
tool_timeout_sec = 210
```

重新加载客户端后,先调用 `list_voices`、`get_tts_status`,再尝试短句合成。不要把 `inference_verified=false` 的健康检查当作已完成 GPU 推理。

## 远程 Streamable HTTP

默认仅监听 loopback。监听 `0.0.0.0` 或其他非 loopback 地址时,必须设置至少 32 字符的 token,并明确填写外部域名的 Host/Origin 白名单:

```toml
[http]
host = "0.0.0.0"
port = 8000
token_env = "GPT_SOVITS_MCP_TOKEN"
allowed_hosts = ["tts.example.com", "127.0.0.1:8000"]
allowed_origins = ["https://tts.example.com"]
```

通过环境变量提供随机 token(不写进配置或 Git),在可信 TLS 反向代理后运行 HTTP。客户端发送 `Authorization: Bearer <token>`。服务端在进入 MCP 前检查 token;Host 和 Origin 校验由 SDK 处理,不启用宽泛 CORS。

这是**单租户私有部署**,共用一个 token 和资源命名空间,不实现 OAuth 授权服务器或租户隔离。拥有访问权的客户端可能读取其知道 URI 的既有音频;不要把它当成多用户公共 SaaS。只运行一个 worker,多个进程/实例需要外部推理队列和独立存储。不要把原始 GPT-SoVITS API 暴露到公网。

## 限制与异常

- 文本最多 5000 字符;对话最多 50 段、总计 20000 字符,所有段先校验再推理。
- 对话为非流式 PCM WAV 拼接;采样率、声道或采样宽度不一致时拒绝拼接;任一段失败不留下部分成品。
- 一个请求的总超时包括排队等待。HTTP 网络读写另有超时和响应大小上限。不自动重试,避免重复消耗 GPU。
- MCP 客户端取消或桥接超时后,上游 GPU 推理可能继续;本项目无法保证中断 api_v2 的计算。
- 拒绝非音频响应、空文件、明显错误的容器头、超限响应;上游错误正文不回传,避免泄露路径或文本。
- 输出配额默认 1000 文件/1 GiB,不自动删除。达到配额时由管理员清理输出目录。参考文本、音频和模型不纳入开源包。
- `raw` 缺少采样元数据,MVP 不提供;`mp3` 不在本次核对的上游 API 格式列表内。
- 状态探测核对 OpenAPI,不触发推理,也不能确认模型权重、GPU 或音质。

## 测试与贡献

```powershell
.venv/Scripts/python -m pytest -q
.venv/Scripts/python -m ruff check .
.venv/Scripts/python -m ruff format --check .
# 可选真实 GPU 验收,配置必须使用已存在的参考录音和正在运行的 api_v2
$env:GPT_SOVITS_LIVE_CONFIG = (Resolve-Path config.local.toml).Path
.venv/Scripts/python -m pytest -q -m live
```

单元测试使用明确标记的测试替身及 HTTP MockTransport;传输测试通过真实 MCP stdio/HTTP 连接;真实推理测试仅在设置环境变量后运行,不把模拟 WAV 当作模型成功。CI 自动验证 Python 3.11/3.12/3.13。

架构、适配证据和后续扩展见 [docs/architecture.md](docs/architecture.md)、[docs/compatibility.md](docs/compatibility.md);本次测试证据见 [docs/validation.md](docs/validation.md)。可运行 [stdio 客户端示例](examples/stdio_client.py)。贡献流程见 [CONTRIBUTING.md](CONTRIBUTING.md),安全边界见 [SECURITY.md](SECURITY.md)。

## 上游与许可

本项目使用 MIT 许可。依赖、GPT-SoVITS 模型权重、参考录音及生成声音的使用权需分别遵守其许可;仓库不包含模型、个人参考音频或安装路径配置。

- [官方 MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) · [SDK 文档](https://py.sdk.modelcontextprotocol.io/)
- [GPT-SoVITS](https://github.com/RVC-Boss/GPT-SoVITS) · [api_v2.py](https://github.com/RVC-Boss/GPT-SoVITS/blob/main/api_v2.py)
- [Codex MCP 官方说明](https://developers.openai.com/codex/mcp/)