HeyGen Video MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@HeyGen Video MCPestimate and generate a 5s 16:9 768p video of a cat surfing"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
HeyGen Video MCP
A stdio MCP server that lets Codex, Claude Desktop, and other MCP agents generate videos with heygen/heygen-video-1 on OpenRouter. Python 3.11+ and uv are required. It uses the official MCP Python SDK.
Install
git clone https://github.com/stevenke1981/heygen-video-mcp.git
cd heygen-video-mcp
uv sync --locked
uv run heygen-video-mcpSet OPENROUTER_API_KEY in the launching process environment or your host's secret store. The server does not load .env automatically. Never paste secrets into prompts, commits, or command arguments. Optional HEYGEN_DATA_DIR selects persistent storage; its default is ~/.heygen-video-mcp.
Codex registration (replace the path with your clone's absolute path):
codex mcp add heygen-video -- uv run --directory /absolute/path/heygen-video-mcp --locked heygen-video-mcpGeneric MCP host configuration:
{
"mcpServers": {
"heygen-video": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/heygen-video-mcp", "--locked", "heygen-video-mcp"]
}
}
}The host must inherit OPENROUTER_API_KEY. On Windows, use an absolute uv.exe path if the host cannot find it; JSON paths need escaped backslashes. Restart/reload your MCP host after registration. Local agents need access to the same data directory to resume jobs.
For a Windows NAS/mapped-drive checkout, put the virtual environment on a local disk: set UV_PROJECT_ENVIRONMENT=C:\Users\YOUR_USER\.cache\heygen-video-mcp\venv both when running uv sync and in your MCP host environment. This avoids native DLL loading failures from UNC paths.
Related MCP server: kairouter-mcp
Agent workflow
Call
heygen_estimatewithrequest(prompt, duration, resolution, aspect_ratio, optional seed). This only reads the public model catalog.Explain the selected model, purpose, USD rate and estimated total to the user. Obtain explicit consent for this paid call.
Call
heygen_submitwith the same request, a uniquerequest_key, the actual user consent inapproval, and theirmax_cost_usd. This checks current pricing again and sends one POST.Poll
heygen_status(job_id)about every 30 seconds. Continue an existing job after a timeout; never automatically regenerate.Call
heygen_download(job_id, filename)after completion. Inspect the actual MP4 before claiming creative approval.
heygen_receipt(request_key) recovers the locally saved job ID. Repeating submit with the same key and parameters returns the receipt without charging again. Changing parameters under a used key is rejected. Keep your ledger directory persistent. A different key is a different authorization responsibility, not provider-side idempotency.
Submission failure leaves an UNKNOWN receipt. Check OpenRouter activity/support before any retry; a timeout does not prove the provider rejected the job. The current API has no documented idempotency header or lookup-by-local-key endpoint. Receipts contain prompts and consent and should be kept private.
HTTP failures retain their status and redacted response text in the local receipt so parameter or account errors can be diagnosed without another paid request. API keys and response URLs are removed from these diagnostics. Reconciliation and renewed approval are still required before another submission.
Cost and feature scope
This release supports text-to-video, 5–15 seconds, 480p/768p/2K and the six advertised aspect ratios. It validates capabilities against the live catalog. It intentionally exposes one model and no model-routing fallback. Reference inputs and separate voice generation are outside this release.
HeyGen Video 1 always renders an audio track. Its live generation endpoint rejects generate_audio: false, despite the discovery catalog currently advertising that value. This server therefore omits the audio toggle and uses the provider's native behavior. Ask for silence or suitable sound in the prompt; this is not a guaranteed mute control. Listening review is separate from decoding.
Prices are fetched at execution time from GET /videos/models. On 2026-10-31, 768p was listed at $0.036/second ($0.18 for five seconds), while the web model page advertised a 50% discount. Estimates use the undiscounted SKU price. max_cost_usd is a local estimate gate, not a billing cap enforced by OpenRouter. It cannot guarantee final charges; use provider account/key spending controls as well. The consent field is a workflow record, not authentication of a human approval.
The tools do not log API keys or return signed asset URLs. Downloads use the fixed OpenRouter content endpoint; HTTPX removes Authorization across origins. Downloads refuse existing files, retain incomplete .part files, and return a SHA256. An MP4 signature is only a format check, not full media validation.
Children's example: 老鼠娶親
examples/mouse-wedding.json is a five-second 768p, 16:9 prompt: a friendly mouse wedding procession, red embroidered clothes, lanterns, flower petals and a sunny village. No frightening animals, chasing, violence, fireworks or readable generated text. It is a prompt, not a generated result.
Use the included MCP client to preview tools and estimate, without a paid call:
uv run python examples/client.pyAfter actual user approval, the same client can submit through MCP:
uv run python examples/client.py --submit --approval "ACTUAL USER CONSENT" --max-cost-usd 0.18
uv run python examples/client.py --status JOB_ID
uv run python examples/client.py --download JOB_IDThe example uses the stable request key mouse-wedding-v1. Do not change it to bypass an uncertain receipt.
Development
uv sync --locked --group dev
uv run pytest
uv run ruff check .
uv buildTests mock external generation; the stdio test launches the real server and checks MCP discovery and invalid arguments without charging. CI never receives an OpenRouter key. Live generation requires separate consent.
Sources
MIT license. This community project is not affiliated with HeyGen or OpenRouter. The license covers this code, not provider service terms or generated-media rights.
Available Tools
5 toolsheygen_downloadA
Download an existing completed job into HEYGEN_DATA_DIR/outputs; never overwrite. Returns local path and SHA256. No new generation.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | ||
| filename | No | video.mp4 |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds real context beyond the annotations: it writes into a specific directory, refuses to overwrite, and reports a local path plus SHA256 for integrity checking. That 'never overwrite' guarantee is exactly the behavior an agent needs, though it doesn't say whether a collision raises an error or picks a new name.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short clauses, each earning its place: action plus destination, the overwrite guarantee, and the return value. Front-loaded with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists so return values needn't be spelled out, but two gaps remain for a tool that writes to disk: behavior when the target file already exists, and behavior when the job isn't complete yet. The filename parameter's role is left entirely implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry both parameters, and it explains neither. job_id is only indirectly constrained by 'completed job', and the filename parameter (default video.mp4) — the one that interacts with the 'never overwrite' rule — is never mentioned.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Download an existing completed job') plus the destination ('HEYGEN_DATA_DIR/outputs'), and the closing 'No new generation' rules out the generation siblings like heygen_submit. It never names heygen_status or heygen_receipt, so differentiation is by negation rather than explicit routing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'existing completed job' implies a precondition (the job must already be finished) but never tells the agent to verify via heygen_status first, nor what to do if the job is still running. No alternatives are named; usage is inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
heygen_estimateBRead-only
Fetch current capabilities and conservative USD SKU estimate. No generation or charge. Text-to-video only.
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true; the description reinforces this with a no-charge, no-generation guarantee and a modality restriction ('text-to-video only'), which is real added context. It doesn't say whether the estimate is deterministic or how the 'conservative' bound is derived, which keeps it below a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, front-loaded sentences with no filler; the safety guarantee follows immediately after the purpose. Slight loss for the jargon-heavy 'conservative USD SKU estimate' phrasing that needs unpacking.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be explained, and annotations cover the safety profile. But with five nested parameters at 0% schema coverage, the description should say at least which fields affect the estimate and what 'capabilities' returns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the nested VideoRequest exposes prompt, duration, resolution, aspect_ratio, and seed with no explanation anywhere. The description never mentions that duration/resolution drive the SKU estimate, so an agent gets no help mapping inputs to price.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific action (fetch capabilities and a USD SKU estimate) and scopes it to text-to-video, which separates it from heygen_submit's generation role via 'No generation or charge.' 'Capabilities' remains vague, but the verb+resource pairing is clear enough to select the tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'No generation or charge' clause implies this is the pre-flight/dry-run option before heygen_submit, but the description never says 'use this before submitting' or names the sibling explicitly. Usage is inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
heygen_receiptARead-only
Read the saved request and job ID without generating again. UNKNOWN requires dashboard reconciliation.
| Name | Required | Description | Default |
|---|---|---|---|
| request_key | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds meaningful behavioral context beyond the readOnly annotation: it confirms no generation occurs and notes that an UNKNOWN result requires dashboard reconciliation. It does not explain what UNKNOWN refers to or what the receipt includes, but the annotations already cover the safety profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences with no wasted words, and the core action is front-loaded. The UNKNOWN reconciliation note is compact even if slightly cryptic.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema and read-only annotations mean return values and safety need not be re-explained, but the missing definition of 'request_key' and the cryptic UNKNOWN note leave gaps for a tool whose only parameter is undocumented. The description is minimal but not quite complete for reliable invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage for the sole parameter is 0%, and the description never explains what 'request_key' represents, where to obtain it, or how it relates to the saved request. The phrase 'saved request' is suggestive but does not compensate for the missing schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Read') and resource ('saved request and job ID') and clarifies it does not regenerate content. It is clear enough to distinguish from heygen_submit, but it does not explicitly differentiate from heygen_status or heygen_download.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by 'without generating again' and the UNKNOWN reconciliation note, but the description does not explicitly say when to use this versus heygen_status, heygen_submit, or heygen_download. The agent must infer the context from the sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
heygen_statusBRead-only
Poll once. Wait about 30 seconds between polls. Terminal failures must not trigger automatic regeneration.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered; the description adds genuinely new behavior — single-shot polling semantics, a recommended interval, and explicit handling of terminal failures. It stops short of describing job states or whether repeated polling has limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the action, then cadence, then the failure rule. Every sentence carries information, though the terseness borders on under-specification.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be explained, but the description omits where job_id comes from and how this step fits the submit → status → download flow. For a polling tool in a multi-step pipeline that is a meaningful gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single required parameter job_id has 0% schema description coverage — only a regex pattern — and the description never mentions it, its provenance (from heygen_submit), or its format. With one undocumented parameter the description is expected to compensate and does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Poll once" implies a status check, but the description never names the resource being polled (a HeyGen generation job) or what a poll returns. Combined with the name heygen_status the intent is inferable, but it is not a stated verb+resource, and it draws no boundary against heygen_receipt or heygen_download.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete operational guidance — poll once, ~30s between polls — and a guardrail against auto-regeneration on terminal failure. What is missing is routing: nothing says when to call this instead of heygen_receipt, or what to do after a successful/non-terminal poll.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
heygen_submitAIdempotent
PAID: submit once AFTER explicit user approval. Record the user's consent in approval and their USD limit. Never invent either. Reuse request_key to recover a receipt; uncertain submissions must be reconciled manually.
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes | ||
| approval | Yes | ||
| request_key | Yes | ||
| max_cost_usd | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral context beyond the annotations: the call is PAID, requires explicit user approval, must record consent and a cost ceiling, must never invent either, and uses request_key for idempotent receipt recovery. These details align with idempotentHint=true and openWorldHint=true and tell the agent exactly how to behave around a costly, state-changing submission.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with PAID and the one-time approval requirement. Every sentence carries distinct operational value: approval, cost limit, and request_key reconciliation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for the critical behavioral aspects of a paid, idempotent submission, and output details are covered by the output schema. The main remaining gap is that it does not point the agent to heygen_estimate for determining max_cost_usd, nor does it explain the request payload fields.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description does important semantic work for approval, max_cost_usd, and request_key, clarifying consent, spending limit, and idempotency. However, it says nothing about the request object or its fields such as prompt, duration, resolution, and aspect_ratio, leaving the main payload undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action—submitting a paid request—but does not explicitly name the resource as video generation; that is inferred from the schema and sibling names. It distinguishes itself from retrieval siblings by emphasizing one-time paid submission and request_key receipt recovery.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives strong usage constraints: submit once, only after explicit user approval, with recorded consent and a USD limit. It also mentions reusing request_key for receipt recovery and manual reconciliation for uncertain submissions, though it does not explicitly route the agent to heygen_estimate before setting max_cost_usd.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
heygen_download - First observed
heygen_estimate - First observed
heygen_receipt - First observed
heygen_status - First observed
heygen_submit
TDQS
Scored across 5 tools
Each tool has a clearly distinct role in the paid video-generation workflow: estimate, submit, recover receipt, poll status, and download. The descriptions sharply separate actions that might otherwise overlap, such as submit versus receipt and status versus download.
All tools use the same heygen_ prefix and readable snake_case, which keeps the set predictable. However, the suffix pattern mixes verbs (submit, download, estimate) with nouns (receipt, status), so it is not a strict verb_noun convention.
Five tools are well scoped to the single-video generation lifecycle, with no redundant or trivial tools. Each tool earns its place by covering a specific stage from cost estimation through download.
The surface covers the full core workflow for paid HeyGen generation: estimate cost, submit with approval, recover a saved receipt, poll status, and download a completed result. Optional extras like cancellation or listing jobs are not essential for the stated per-request lifecycle.
Maintenance
Related MCP Connectors
Plan, compare, price, generate, and recover AI video from compatible MCP clients.
Generate AI video from any MCP client. Pick the model, see the per-second price before you spend.
Build, run, schedule, and publish AI video pipelines to YouTube and TikTok from any MCP client.
Create images & video from any MCP agent — 17 models, spend limits, one URL.
Related MCP Servers
AlicenseNot gradedqualityFmaintenanceEnables video generation from text, images, and more through MCP-compatible apps like Claude and Cursor.54MIT- AlicenseAqualityCmaintenanceEnables MCP-compatible agents to access KaiRouter's video generation API, providing tools to list available video models, generate videos (text-to-video or image-to-video) asynchronously, check job status, and list recent jobs.4MIT
- FlicenseAqualityBmaintenanceEnables AI agents to generate videos from text prompts, monitor job status, retrieve completed videos, and cancel ongoing generation tasks through stdio-based MCP tools.4-
- AlicenseBqualityBmaintenanceEnables AI agents to create Vidu image-to-video and reference-to-video generation tasks, poll asynchronous results, and check pricing across two model variants. Works from Claude Code, Codex, Cursor, VS Code, and other MCP-compatible hosts.5253 npmApache 2.0