zvex MCP server
AI video dubbing as an MCP tool: hand it a video URL or a local file, get back a fully dubbed video in Russian, English or Spanish — keeping the original speakers' voices through per-speaker voice cloning.
Powered by zvex (声桥).
The server is a thin stdio client over zvex's HTTP API, so it runs anywhere Python does — no GPU, no local models.
Install
uvx zvex # run it without installing anything
# or
uv tool install zvex # install the `zvex` command
# or
pip install zvex
(Working from a source checkout instead? Use uv tool install ./mcp/zvex.)
Get an API key
- Sign in at https://zvex.cn
- Open Account → API keys and create one
- Copy the
zvex-…value — it is shown only once
Jobs are billed from the same credit balance as the web app, at a flat 10 credits per minute of video. A failed job is refunded in full. Top-up supports WeChat Pay, Alipay and PayPal.
Configure your MCP client
Claude Desktop (claude_desktop_config.json) or Cursor (.cursor/mcp.json):
{
"mcpServers": {
"zvex": {
"command": "uvx",
"args": ["zvex"],
"env": {
"ZVEX_API_KEY": "zvex-your-key-here"
}
}
}
}
| Variable | Required | Default | Meaning |
|---|---|---|---|
ZVEX_API_KEY |
yes | — | zvex-… key from the account page |
ZVEX_BASE_URL |
no | https://zvex.cn |
API base URL (self-hosted deployments) |
Tools
| Tool | Purpose |
|---|---|
estimate_cost(minutes, tier) |
Credit cost and current balance |
upload_video(file_path) |
Upload a local file, returns a file_id |
submit_dubbing_job(video_url, target_language, tier, file_id) |
Queue a dubbing job, returns job_id |
get_job_status(job_id) |
Poll once; final states carry the output URLs |
wait_for_job(job_id, timeout_seconds) |
Block until the job finishes |
Typical flow — public URL:
submit_dubbing_job(video_url="https://example.com/episode-01.mp4", target_language="ru")
→ {"job_id": 42, "credits_cost": 240, "duration_sec": 1441.0, …}
wait_for_job(42)
→ {"status": "completed", "final_video_url": "…", "subtitle_url": "…"}
Typical flow — local file (no public URL needed):
upload_video("/home/me/clip.mov")
→ {"file_id": "a1b2c3d4e5f60718", "duration_sec": 92.4, …}
submit_dubbing_job(file_id="a1b2c3d4e5f60718", target_language="ru")
→ {"job_id": 43, …}
Notes
submit_dubbing_jobtakes exactly one ofvideo_urlorfile_id.video_urlmust be a publicly reachablehttp(s)link, up to 500 MB.upload_videosends the file to the server (up to 500 MB); the uploaded copy persists, so one upload can back several submissions.target_languagedepends on the deployment (ru,en,eson the hosted service).tierisfast,standardorprofessional— it selects which features are available, not the price.- One job per account runs at a time; a second submission returns HTTP 409.
- Output links are signed, time-limited URLs (valid ~24 h) — they download without signing in. Re-poll the job to get a fresh link once one expires.
No expert mode over MCP — use the web app for that
The MCP tools are the fully automatic path: you hand over a video URL and get back a finished dub, with no review step in between. That is deliberate — an LLM client has no way to listen to a waveform or judge whether a line landed.
Expert mode is not exposed as an MCP tool. For the full expert mode, go to
zvex.cn and open an order's Review page
(/expert/{run_id}).
What you get there, and why it is worth the trip:
| Capability | What it fixes |
|---|---|
| Segment-by-segment editing | Edit the source text, the translation, and the start/end timing of every segment — the automatic pass gets the gist right, this gets the details right. |
| Waveform timeline | Drag region borders to re-time a line, click a row to jump-play it, right-click to merge or split. Split a run-on sentence or merge two fragments without touching a text file. |
| Re-translate after editing | Fix the source line, then re-translate just that segment — no need to rerun the whole job. |
| Per-segment dub on/off | Untick "Dub" to keep a segment's original voice. Essential for songs, on-screen text, or a line the clone cannot carry. |
| Speaker & gender correction | Fix mis-clustered speakers and wrong gender assignments; the TTS gate respects your manual choice instead of re-deriving it. |
| Emotion labels | Tag a segment calm / happy / angry / sad / whisper / excited / steady — the TTS intonation follows it. |
| Terminology pre-learning | Extract names and jargon from the script first, so they translate consistently across the whole episode. |
| Mixing controls | Dubbing volume, background-music level, dubbing speed, cross-speaker gap, subtitle font size and position — tuned per job instead of accepting the defaults. |
| Subtitle removal | Blur or delogo burned-in source subtitles (or mask them with a bar) so you don't end up with double subtitles. |
| Optional heavy features | Active-speaker detection, face clustering and cross-episode voice_bank reuse for serials. |
| Safety review gate | Low-confidence segments (possible speaker mismatch, singing, uncertain BGM) are flagged and block video generation until you resolve them — the automatic path would have shipped them silently. |
In short: MCP is the "just give me the video" path; the web app's expert mode is where you fix the 5% that a machine cannot judge. Run the automatic pass over MCP first, then open the same order in the web app whenever the result needs a human ear.
Alipay AI Pay agents (zero sign-up)
If your agent is wired into Alipay AI Pay (the A2M 402 protocol — OpenClaw-style clients), you can skip sign-up and top-up entirely and pay per call:
| Resource | Endpoint | Pricing |
|---|---|---|
| Text translation | POST https://zvex.cn/a2m/v1/translate |
¥0.1 / call |
| Video dubbing | POST https://zvex.cn/a2m/v1/dubbing |
¥1 / minute (min ¥2, billed on measured duration) |
Flow: call without credentials → 402 + Payment-Needed signed bill →
pay via Alipay AI Pay → retry with Payment-Proof → resource delivered.
Dubbing is asynchronous; poll /a2m/v1/dubbing/status/{out_trade_no} for
the finished video and subtitles.
Both services are live on the Alipay AI Pay service bazaar (search "声桥" or "zvex"). Protocol details: https://zvex.cn/docs/mcp. Regular MCP clients without 402 support should use the API-key path above.
Development
uv venv --python 3.11 .venv-test
uv pip install --python .venv-test/bin/python -e .
ZVEX_API_KEY=zvex-… .venv-test/bin/python -m zvex.server
Release files for zvex 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| zvex-0.1.5.tar.gz | 13.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| zvex-0.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size:24.3 kB
Release files / zvex-0.1.5.tar.gz
| Download URL | zvex-0.1.5.tar.gz |
|---|---|
| Size | 13.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f65fc5740560d12a9a26fc6cdb8303e520cbe7dd2fee1436d119e6f39f4f682e
|
|
BLAKE2b-256 checksum How to use checksums |
10b6e8c00c6b4f915f305750838ecd0f5e2618a4d9803f2689aed0c88f052ed1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.13
|
Release files / zvex-0.1.5-py3-none-any.whl
| Download URL | zvex-0.1.5-py3-none-any.whl |
|---|---|
| Size | 10.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
14154eb872bbec319f9c09f4fcc213460714f112224280feabe10df35ad7fa88
|
|
BLAKE2b-256 checksum How to use checksums |
8f401c3e8446866ab0d21efa6071042104f7ec71f3e05b26cbaf19dafa5ab858
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.13
|