Skip to main content
Glama

media-gen

An MCP server for Claude Code with two paths to media: a free, Claude-authored rendering path (SVG/HTML → image, canvas animation → video) that needs no API keys, and an optional bring-your-own-key (BYOK) path for photorealistic image/video generation via OpenAI, Gemini, or fal.ai.

What it is

render_image and render_video take content you author — SVG markup, an HTML document, or a JavaScript draw(ctx, t, frame) function — and turn it into a PNG/JPEG/WebP or MP4 on disk, using a headless, network-blocked Chromium and ffmpeg. These always work, cost nothing, and are ideal for diagrams, charts, UI mockups, and motion graphics. They are not photorealistic — they render exactly what you draw.

generate_image and generate_video call out to a real image/video model (gpt-image-1/Sora, Imagen/Veo, or FLUX/Kling) to produce photorealistic media from a text prompt. These only appear as tools when you've configured at least one provider key, and each call costs real money on your account.

list_providers reports which BYOK providers are configured and what models/capabilities each exposes.

Related MCP server: ShotAPI

Setup

npm install
npx playwright install chromium
npm run build

This installs dependencies, downloads the headless Chromium build used for SVG/HTML rendering, and compiles TypeScript to dist/.

Connecting to Claude Code

A .mcp.json is already checked into the repo root, so Claude Code will pick it up automatically when you run it from this project directory:

{
  "mcpServers": {
    "media-gen": {
      "command": "node",
      "args": ["dist/index.js"],
      "env": {
        "MEDIA_OUTPUT_DIR": "${MEDIA_OUTPUT_DIR}",
        "OPENAI_API_KEY": "${OPENAI_API_KEY}",
        "GEMINI_API_KEY": "${GEMINI_API_KEY}",
        "FAL_KEY": "${FAL_KEY}"
      }
    }
  }
}

Alternatively, register it manually from any directory:

claude mcp add media-gen -- node <absolute-path-to>\dist\index.js

Approve the server when Claude Code prompts you, then run claude mcp list to confirm media-gen shows as connected.

BYOK keys

All keys are optional and read from the environment only — they are never written to disk, logged, or echoed back in tool output or the startup message (which prints provider names, never values).

Env var

Enables

OPENAI_API_KEY

generate_image via gpt-image-1, generate_video via Sora

GEMINI_API_KEY

generate_image via Imagen 4, generate_video via Veo 3

FAL_KEY

generate_image via FLUX, generate_video via Kling

With no keys set, only the free render_image/render_video/list_providers tools are registered; generate_image/generate_video don't appear until at least one key is present. Set keys in .mcp.json's env block (they expand from your shell environment) or via claude mcp add ... -e KEY=value.

Tool reference

Tool

Purpose

Key params

render_image

Render SVG or HTML you author to an image file

source, format (svg/html), width, height, output_format (png/jpeg/webp)

render_video

Render an MP4 from a JS canvas draw(ctx, t, frame) function

draw_code, duration_seconds, fps, width, height

generate_image

Photoreal image from a text prompt (BYOK)

prompt, provider, model, aspect_ratio, num_images

generate_video

Photoreal video from a text prompt (BYOK)

prompt, provider, model, duration_seconds, aspect_ratio

list_providers

List configured BYOK providers and their models

none

Manual E2E check

Free (no keys needed) — try these prompts in a Claude Code session:

  • "render an SVG diagram of a login flow as an image"

  • "render a 3-second bouncing ball video"

Paid (uses your configured key, costs real money):

  • "generate a photo of a lighthouse (uses your key)"

Confirm the output file appears under generated-media/ and that Claude describes seeing the returned image inline.

Limits

  • render_video: duration ≤ 60s, frame budget < 3600 frames, resolution ≤ 1080p.

  • render_image: width/height ≤ 4096px per side.

  • generate_video (BYOK): polling caps out after 10 minutes per provider job.

  • Rendered (render_*) output is never photorealistic — for photoreal results you need generate_* with a configured provider key.

Available Tools

3 tools
list_providersA

List configured BYOK generation providers, their models and capabilities.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. 'List' implies a read-only operation, and the description adds useful context about scope ('configured', 'BYOK') and returned content. However, it does not disclose potential behaviors such as whether it only returns built-in providers, if it can be empty, or whether any configuration is required first.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence that conveys the action, the subject, and the output contents without filler. Every word adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter listing tool with no output schema, the description adequately conveys the purpose and the returned categories. It does not explain the BYOK acronym or give examples of capabilities, but those are minor omissions for such a simple tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so the description does not need to explain parameter behavior. The baseline for no-parameter tools is 4, and nothing in the schema requires additional clarification.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action 'List' with a clear resource 'configured BYOK generation providers' and explicitly names what is returned: 'their models and capabilities'. It is easily distinguished from sibling render_image and render_video, which perform generation rather than listing providers.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this is a discovery/list operation used to inspect available generation providers, especially before rendering tasks. However, it does not explicitly state when to use this tool versus alternatives or exclude cases, though the sibling names make the distinction reasonably clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

render_imageA

Render SVG markup or a full HTML document (authored by you) to an image file on disk. Use for illustrations, diagrams, charts, UI mockups, typographic cards. Not photorealistic.

ParametersJSON Schema
NameRequiredDescriptionDefault
widthNo
formatNosvg
heightNo
sourceYesSVG markup (format=svg) or complete HTML document (format=html)
filenameNoOptional filename slug
output_formatNopng

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It discloses the important side effect that output is written to disk, restricts input to self-authored markup, and sets expectations with 'Not photorealistic.' It does not describe overwrite behavior or return values, but the essential operational behavior is transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no wasted words. It front-loads the primary action and resource, then provides use cases and a limitation in a tightly packed second sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-parameter tool with no annotations and no output schema, the description plus schema is mostly sufficient: an agent can call it with just source and rely on defaults. However, it does not clarify what happens after rendering (returned file path? generated filename?) and does not mention how width/height or output_format influence the result, leaving some uncertainty.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, so the description needed to compensate for width, height, format, and output_format. It usefully connects source content to the format enum ('SVG markup' vs 'full HTML document'), but does not explain output_format, filename, or dimension semantics beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a concrete verb ('Render'), names the accepted source types ('SVG markup or a full HTML document'), and states the output ('image file on disk'). It clearly distinguishes itself from siblings like render_video and list_providers, and adds a boundary with 'Not photorealistic.'

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly lists intended use cases: illustrations, diagrams, charts, UI mockups, typographic cards. It also provides an exclusion with 'Not photorealistic,' but it does not explicitly contrast with render_video or list_providers, so an agent is left to infer the alternative use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

render_videoA

Render an MP4 from JavaScript canvas animation code you author. Provide draw(ctx, t, frame) as a pure function of time t in seconds (deterministic — no requestAnimationFrame, no Date.now). Optional setup(ctx) runs once. Use for motion graphics, animated diagrams, explainers. Returns file path plus sample frames.

ParametersJSON Schema
NameRequiredDescriptionDefault
fpsNo
widthNo
heightNo
filenameNo
draw_codeYesJS defining function draw(ctx, t, frame) and optionally setup(ctx)
duration_secondsNo

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral disclosure burden. It does this well by specifying that draw(ctx, t, frame) must be deterministic, forbidding requestAnimationFrame and Date.now, noting optional setup(ctx) runs once, and stating the output is a file path plus sample frames. It does not cover render time, failure modes, or resource implications, leaving some behavioral gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence earns its place: purpose, function contract, optional setup, use cases, and return value. The most important constraint (pure deterministic draw function) is front-loaded, and there is no filler or repetition of schma details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description gives an agent enough to call the tool correctly: the code contract, deterministic requirement, optional setup, and output shape. Minor gaps exist around duration_seconds semantics and more detailed return format, but the schema supplies defaults and the description covers the core complexity of code execution.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is low, so the description compensates by adding crucial semantics for the required draw_code parameter: the draw function signature, time in seconds, purity requirement, and optional setup(ctx). It does not explain duration_seconds or the dimension/fps parameters, but these are self-explanatory and have defaults in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Render an MP4 from JavaScript canvas animation code you author.' It clearly differentiates from render_image (static image) and list_providers (provider listing), and reinforces the video/animation scope with 'Use for motion graphics, animated diagrams, explainers.'

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clear use-case guidance is given ('Use for motion graphics, animated diagrams, explainers'), which implies when render_video is appropriate. However, it does not explicitly name alternative tools or state when not to use it, such as 'for static images use render_image instead.'

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. Dates show when Glama detected each change.

  1. 3 tool updatesv0.1.0
    • First observedlist_providers
    • First observedrender_image
    • First observedrender_video

TDQS

A4.4/5.0
Disambiguation5/5

The three tools have distinct purposes: render_image produces static images, render_video produces animated video, and list_providers enumerates backend providers. There is no overlap or ambiguity between them.

Naming Consistency5/5

Tool names follow a consistent snake_case verb_noun convention: render_image, render_video, list_providers. The verb precisely indicates the action and the noun indicates the output or resource, making the pattern predictable.

Tool Count5/5

With exactly three tools, this server is tightly scoped to its media generation purpose and carries no redundant tools. Each tool earns a clear place in the set.

Completeness5/5

The server covers the apparent core workflow: discover available providers, render static visual assets, and render animated video assets. Since rendering is a stateless generate-to-file operation, no update/delete/list-generated-files tools are required for the declared scope.

Maintenance

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/justapileofashes/media-gen'

If you have feedback or need assistance with the MCP directory API, please join our Discord server