Build a Veo 3.1 & Seedream 5.0 Media-Generation MCP Server
Google's Veo 3.1 and ByteDance's Seedream 5.0 Pro landed in July-August 2026. This dispatch wraps both generation APIs behind one Python FastMCP server so agents can generate video, edit regions, and fuse references via tool calls.
Deepak Bagada
CEO, SaaSNext
- Veo 3.1 adds native synchronized audio, longer 1080p shots, first/last-frame conditioning, and instruction-based clip editing.
- Seedream 5.0 Pro does region-precise mask editing and 2-5 reference image fusion, keeping everything outside the mask pixel-identical.
- A stateless Python FastMCP server exposes both APIs as tools, returning operation IDs that clients poll asynchronously.
- Harden the server with scoped Google service accounts, rotated ByteDance API keys, and per-agent spend budgets.
By Deepak Bagada, CEO at SaaSNext & Principal AI Architect.
Build a Veo 3.1 & Seedream 5.0 Media-Generation MCP Server
Summer 2026 was the season generative media finally became a platform capability rather than a demo. Google shipped Veo 3.1, the video-generation model with native synchronized audio and multi-second coherent shots. ByteDance shipped Seedream 5.0 Pro, an image model that does region-precise editing and multi-reference image fusion. Both arrived in July–August 2026, and both become dramatically more useful when exposed to AI agents through the Model Context Protocol (MCP).
This dispatch builds a Python FastMCP server that wraps the Veo 3.1 and Seedream 5.0 Pro generation APIs behind a single MCP endpoint — so Claude, Cursor, or any MCP client can generate a video, edit a specific region of an image, or fuse two reference photos with nothing but a tool call. We cover inputSchema definitions, async job polling, a Claude Desktop mcpServers block, and a security guide for service-account and API-key authentication.
Prefer the directory approach? The MCP Directory tracks ready-made media servers, and the Workflows desk shows full content pipelines built on them. Model releases land on the latest AI news desk.
The 2026 Media Stack: What You Are Wrapping
Veo 3.1 (Google)
Veo 3.1 is Google's flagship video generator on Vertex AI, the successor to Veo 3 (which first shipped native audio in 2025). The 3.1 update, released in July 2026, focuses on production realism:
- Native synchronized audio. Dialogue, foley, and room tone are generated with the video — no separate audio pass, no lip-sync patchwork.
- Longer coherent shots. Single generations up to 120 seconds at 1080p, with consistent subject identity across the clip.
- First-frame and last-frame conditioning. Supply a start image, an end image, or both, and the model interpolates the motion between them.
- Instruction-based editing. Describe a change to an existing clip ("change the lighting to golden hour") and Veo 3.1 regenerates only the affected timeline.
- Deterministic seeds. A seed gives repeatable output so you can A/B test prompts properly.
Seedream 5.0 Pro (ByteDance)
Seedream 5.0 Pro is ByteDance's high-fidelity image model, released in August 2026. Two capabilities define it:
- Region-precise editing. Instead of editing the whole canvas, you supply a mask and a prompt: replace only the text on a storefront, change the shirt in this region to navy. Everything outside the mask stays pixel-identical.
- Multi-reference image fusion. Feed 2–5 reference images (a person's face, a specific pose, a brand's art direction) and the model merges identity, pose, and style into one coherent composition.
Architecture Overview
The server is deliberately stateless, aligned with the MCP 2026-07-28 stateless spec: every tool call carries its own credentials, and every long-running generation is tracked as an operation the client polls. Video and image generation are asynchronous — a Veo 3.1 clip can take 60–300 seconds to render — so the server returns an operation ID immediately and exposes a get_generation_status tool for polling.
Claude Desktop / Cursor (MCP client)
|
v
media-studio FastMCP server (Python)
| |
v v
Vertex AI ByteDance Seedream
Veo 3.1 API (Volcengine)
Project Setup
Create a requirements.txt with the dependencies:
fastmcp>=2.0
httpx>=0.28
pydantic>=2.10
python-dotenv>=1.1
Install with pip install -r requirements.txt, then create a .env file with your credentials (see the security guide below) and load it via python-dotenv.
inputSchema Definitions
FastMCP Python generates each tool's inputSchema from Pydantic models. Define the request shapes once; the schema that appears in tools/list for the video tool looks like this:
{
"name": "generate_video",
"inputSchema": {
"type": "object",
"properties": {
"prompt": { "type": "string" },
"duration_seconds": { "type": "integer", "minimum": 4, "maximum": 120 },
"resolution": { "enum": ["720p", "1080p"], "type": "string" },
"fps": { "enum": [24, 30, 60], "type": "integer" },
"audio": { "type": "boolean" },
"first_frame_uri": { "type": ["string", "null"] },
"last_frame_uri": { "type": ["string", "null"] },
"seed": { "type": ["integer", "null"] }
}
}
}
The Pydantic models below are the single source of truth for that schema.
Full Server Implementation
import os
import json
from typing import Literal, Optional
import httpx
from dotenv import load_dotenv
from pydantic import BaseModel, Field
from mcp.server.fastmcp import FastMCP
load_dotenv()
mcp = FastMCP("media-studio", version="2.1.0")
LOCATION = os.environ.get("GOOGLE_VEO_LOCATION", "us-central1")
PROJECT = os.environ["GOOGLE_CLOUD_PROJECT"]
VEO_MODEL = "veo-3.1-generator"
SEEDREAM_BASE = os.environ["SEEDREAM_BASE_URL"]
SEEDREAM_KEY = os.environ["SEEDREAM_API_KEY"]
class GenerateVideoRequest(BaseModel):
prompt: str = Field(description="Concrete description: subject, action, camera, lighting.")
duration_seconds: int = Field(default=8, ge=4, le=120)
resolution: Literal["720p", "1080p"] = "1080p"
fps: Literal[24, 30, 60] = 30
audio: bool = Field(default=True, description="Native synchronized audio (Veo 3.1)")
first_frame_uri: Optional[str] = Field(default=None, description="gs:// URI for start frame")
last_frame_uri: Optional[str] = Field(default=None, description="gs:// URI for end frame")
seed: Optional[int] = Field(default=None, description="Deterministic seed")
class RegionEdit(BaseModel):
mask_uri: str = Field(description="Mask image; white pixels are editable")
prompt: str = Field(description="Instruction scoped to the masked region")
class RegionEditRequest(BaseModel):
image_uri: str
regions: list[RegionEdit] = Field(min_length=1, max_length=8)
seed: Optional[int] = None
class FusionRequest(BaseModel):
reference_uris: list[str] = Field(min_length=2, max_length=5)
prompt: str
mode: Literal["identity", "pose", "style", "auto"] = "auto"
@mcp.tool(description="Generate a cinematic video clip with Google Veo 3.1")
def generate_video(req: GenerateVideoRequest) -> str:
operation = _start_veo(req.model_dump())
return json.dumps({"operation": operation})
@mcp.tool(description="Poll a running Veo or Seedream generation operation")
def get_generation_status(operation: str) -> str:
status = _poll_operation(operation)
return json.dumps(status, indent=2)
@mcp.tool(description="Generate an image with ByteDance Seedream 5.0 Pro")
def generate_image(prompt: str, size: Literal["1:1", "16:9", "9:16"] = "1:1") -> str:
return json.dumps(_seedream_post("/generate", {"prompt": prompt, "size": size}))
@mcp.tool(description="Region-precise editing: only masked regions change")
def region_edit(req: RegionEditRequest) -> str:
payload = {
"image": req.image_uri,
"regions": [r.model_dump() for r in req.regions],
"seed": req.seed,
}
return json.dumps(_seedream_post("/region_edit", payload))
@mcp.tool(description="Fuse 2-5 reference images (identity, pose, style)")
def fuse_references(req: FusionRequest) -> str:
payload = {
"references": req.reference_uris,
"prompt": req.prompt,
"mode": req.mode,
}
return json.dumps(_seedream_post("/fusion", payload))
def _start_veo(payload: dict) -> str:
url = (
f"https://{LOCATION}-aiplatform.googleapis.com/v1/"
f"projects/{PROJECT}/locations/{LOCATION}/publishers/google/"
f"models/{VEO_MODEL}:predictLongRunning"
)
body = {"instances": [{"prompt": payload["prompt"]}], "parameters": payload}
resp = httpx.post(url, headers={"Authorization": f"Bearer {_google_token()}"}, json=body, timeout=60)
resp.raise_for_status()
return resp.json()["name"]
def _poll_operation(operation: str) -> dict:
url = f"https://{LOCATION}-aiplatform.googleapis.com/v1/{operation}"
resp = httpx.get(url, headers={"Authorization": f"Bearer {_google_token()}"}, timeout=30)
resp.raise_for_status()
data = resp.json()
return {
"done": data.get("done", False),
"result": data.get("response", {}).get("generatedSamples", []),
}
def _google_token() -> str:
return os.environ["GOOGLE_ACCESS_TOKEN"]
def _seedream_post(path: str, payload: dict) -> dict:
headers = {"X-API-Key": SEEDREAM_KEY, "Content-Type": "application/json"}
resp = httpx.post(f"{SEEDREAM_BASE}{path}", headers=headers, json=payload, timeout=120)
resp.raise_for_status()
return resp.json()
Notes on the implementation:
generate_videoreturns an operation ID immediately; the client polls withget_generation_statusuntildoneistrueand reads the output GCS URIs fromresult.- Replace
_google_tokenwith Application Default Credentials (google.auth.default()) in production so tokens refresh automatically. - Seedream responses include
image_urlplus an edit report so region edits are verifiable before publishing.
Claude Desktop mcpServers Configuration
Run the server over stdio and pass credentials through the environment:
{
"mcpServers": {
"media-studio": {
"command": "uv",
"args": ["run", "media-studio-mcp"],
"env": {
"GOOGLE_CLOUD_PROJECT": "prod-creative",
"GOOGLE_VEO_LOCATION": "us-central1",
"GOOGLE_ACCESS_TOKEN": "",
"GOOGLE_APPLICATION_CREDENTIALS": "/secure/creds/sa-video.json",
"SEEDREAM_BASE_URL": "https://api.volcengine.com/v1/seedream",
"SEEDREAM_API_KEY": "sk-live-****"
}
}
}
}
For HTTP transport, expose the same server with --transport http and use "type": "http" with a url instead of command/args. Never hard-code GOOGLE_ACCESS_TOKEN; prefer GOOGLE_APPLICATION_CREDENTIALS and let the Google SDK refresh the token for you.
Comparison: Veo 3.1 vs Seedream 5.0 Pro
| Capability | Veo 3.1 (Google) | Seedream 5.0 Pro (ByteDance) |
|---|---|---|
| Medium | Video + native audio | Images (edit + fusion) |
| Signature trick | First/last-frame conditioning, clip editing | Region-precise mask editing, multi-reference fusion |
| Output scale | Up to 120 s at 1080p | 1:1 / 16:9 / 9:16 stills |
| Determinism | Seed + prompt | Seed + mask fidelity |
| Auth | OAuth 2.0 service account | API key + request signing |
| Billing | Per video second | Per generated image |
| Best used for | Brand films, product shots, explainers | Catalog retouching, character consistency, ads |
Use them together: fuse a hero's identity with Seedream, then generate the motion story with Veo 3.1 conditioned on that still. That pipeline is exactly what the Workflows desk catalogs.
Security Guide: Service Accounts, API Keys, and Signing
- Google: scoped service accounts. Create a dedicated service account with only
aiplatform.predictionson the video models, bound to a Cloud Storage bucket your pipeline reads. Use Application Default Credentials so tokens auto-refresh; never commit a raw access token. - ByteDance: API keys and HMAC. Keep the Seedream key in a secret manager and inject it via
envat launch. For high-volume production, switch to Volcengine-style HMAC-SHA256 request signing so the key is never transmitted in a plain header. - Per-environment credentials. A
dev,stage, andprodkey (or service account) lets you shut down a leaked dev credential without touching production. - Rotation. Rotate the Seedream key every 30–90 days; rotate the Google service-account key at least annually, or use workload identity federation to eliminate static keys entirely.
- Never log prompts with PII or credentials. Veo and Seedream prompts often contain faces, addresses, or brand assets. Redact them in audit logs.
- Rate limit and budget. Both APIs bill per generation. Add a per-agent token budget in the MCP server so a runaway agent cannot burn a month of video budget in one night.
- Output governance. Store generated assets in private buckets and serve them through a signing proxy; do not let the MCP tool return public URLs to arbitrary clients.
Wrapping Up
A media-generation MCP server is the fastest way to put Veo 3.1 and Seedream 5.0 Pro inside your agents' working memory. With the FastMCP server above, Claude can brief a storyboard, generate a hero video, edit a single region of a product shot, and fuse reference images — all through plain tool calls, with an inputSchema your client validates before any API spend.
For more composable pieces, check the MCP Directory, and keep an eye on the latest AI news desk for the next Veo, Seedream, or MCP spec update.
Enjoyed this breakdown? Get our morning dispatch in your inbox.
Curated breakdowns of frontier model architectures and compute markets delivered every weekday. Zero fluff.
Deepak Bagada
CEO, SaaSNext
Deepak Bagada is the CEO of SaaSNext and founder of Daily AI World. He covers AI workflows, agentic automation, LLM architectures, and founder growth strategies.
Related Intelligence Analysis
Vercel AI SDK Tool Calling React: 5 Steps (2026)
Vercel AI SDK tool calling React integration is a programming pattern that executes server-side functions based on large language model decisions and streams the results to a React frontend. By combining streamText with...
Fact-Density vs. Word Count: The New SEO for 2026
Fact Density is the ratio of verifiable, unique information to the total word count of a piece of content. In 2026, AI search engines like Perplexity and Gemini prioritize high fact density over traditional word count. A...
NVIDIA Audex vs Qwen3.5-Audio: Best Open Audio-Text LLM for Voice AI 2026
NVIDIA Audex 30B-A3B (July 2026) and Qwen3.5-35B-A3B are the two leading open audio-text LLMs. Audex uniquely handles both audio understanding and generation in a single model while preserving text intelligence. Qwen3.5-...