Skip to main content
Workflows Library MCP Directory Realtime AI News Sponsor Tier Subscribe
Front Page / AI Tools / Deep Dive

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

Deepak Bagada

CEO, SaaSNext

Aug 19, 2026 Published
|
Aug 19, 2026 Updated
|
9 Minutes Reading Time
Core Takeaways for Founders & Builders
  • 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_video returns an operation ID immediately; the client polls with get_generation_status until done is true and reads the output GCS URIs from result.
  • Replace _google_token with Application Default Credentials (google.auth.default()) in production so tokens refresh automatically.
  • Seedream responses include image_url plus 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.predictions on 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 env at 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, and prod key (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.

Executive Briefing

Enjoyed this breakdown? Get our morning dispatch in your inbox.

Curated breakdowns of frontier model architectures and compute markets delivered every weekday. Zero fluff.

Frequently Asked Questions
Veo 3.1 is served through Google's Vertex AI generation endpoints on a Google Cloud project with the AI Platform API enabled; you authenticate with an OAuth 2.0 service account.
Typically 60-300 seconds depending on duration and resolution, which is why the server returns an operation ID immediately and the client polls with get_generation_status.
Yes. Region-precise editing uses a mask image where white pixels are editable; everything outside the masked regions stays pixel-identical.
Yes. generate_video returns an operation ID immediately, and get_generation_status lets any MCP client poll until the output is ready.
It merges 2-5 reference images (identity, pose, and style) into a single coherent Seedream 5.0 Pro composition, ideal for character consistency across ads.
Deepak Bagada
Author Profile

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

Briefing AI Tools

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...

Deepak Bagada Deepak Bagada
12m read
Breaking AI Tools

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...

Deepak Bagada Deepak Bagada
4m read
Audio Briefing
Accessibility Preferences
High Contrast Mode
Accessible Reading Font

Keyboard Shortcuts

Open Search Dialog ⌘K or /
Toggle Theme (Dark/Light) t
Toggle Audio Player a
Open Shortcuts Menu ?
Close Active Dialog Esc