Skip to main content
Glama

gemini-media-mcp

CI License: MIT

Deutsch: README.de.md

An MCP server that lets Claude (or any MCP client) create and edit images with Google's Nano Banana models and generate videos with Gemini Omni Flash, using the Gemini API.

It is built to be boring in the right places: every paid call is priced and checked against your budget first, files can only be read from folders you allow, nothing is ever overwritten, and every output gets a JSON sidecar that records how it was made.

Video note (2026-10-31): Google shut down the Veo 3.1 preview models on the Gemini API on 2026-10-22 and recommends Gemini Omni Flash as the replacement. The video tools use gemini-omni-1.1-flash by default. Details: docs/research.md.

Tools

Tool

What it does

Costs money

generate_image

Text → image. Options: model, aspect_ratio, resolution, output_name

yes

edit_image

Image(s) + prompt → image. Up to 14 reference images (face, logo, product …) as file paths

yes

start_video

Starts a video job (text, or an image as first frame) and returns a job_id at once. Without confirm_cost=true it only returns the price

yes

get_video_status

Polls a job; when done, downloads the MP4

no (cost is logged at start)

list_models

Configured models, prices and options

no

cost_report

Estimated spend today / this month / total, remaining budget

no

Related MCP server: genrelay-mcp

Requirements

  • Python 3.11+ and uv

  • A Gemini API key from Google AI Studio with billing enabled. None of the image or video models has a free tier.

Installation

The package is not on PyPI yet. Run it straight from GitHub with uvx:

uvx --from git+https://github.com/Wimplunch/gemini-media-mcp gemini-media-mcp

or from a local checkout:

git clone https://github.com/Wimplunch/gemini-media-mcp
uvx --from ./gemini-media-mcp gemini-media-mcp

Once published to PyPI this becomes uvx gemini-media-mcp.

API key

The server reads the key only from the GEMINI_API_KEY environment variable. Keep it out of config files and chat windows. On Linux you can make it available to desktop apps like this (input is hidden, file is readable only by you):

mkdir -p ~/.config/environment.d && (umask 077; read -rsp "Gemini key: " K && printf 'GEMINI_API_KEY=%s\n' "$K" > ~/.config/environment.d/gemini.conf; unset K)

Log out and back in afterwards. On macOS/Windows, set the variable in your shell profile or system settings.

Claude Code

claude mcp add --scope user gemini-media \
  -e GEMINI_MEDIA_OUTPUT_DIR="$HOME/Pictures/gemini" \
  -- uvx --from git+https://github.com/Wimplunch/gemini-media-mcp gemini-media-mcp

Claude Code passes its own environment to the server, so GEMINI_API_KEY is inherited and never written into the config. Check with claude mcp list.

Claude Desktop

Edit claude_desktop_config.json (Linux ~/.config/Claude/, macOS ~/Library/Application Support/Claude/, Windows %APPDATA%\Claude\):

{
  "mcpServers": {
    "gemini-media": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/Wimplunch/gemini-media-mcp", "gemini-media-mcp"],
      "env": {
        "GEMINI_MEDIA_OUTPUT_DIR": "/home/you/Pictures/gemini"
      }
    }
  }
}

Restart Claude Desktop. The server inherits GEMINI_API_KEY from the app's environment. Avoid pasting the key into this file, especially if you sync or share it.

Configuration

All settings are environment variables.

Variable

Default

Meaning

GEMINI_API_KEY

–

Your Gemini API key (required for generation with the default provider)

GEMINI_MEDIA_PROVIDER

google

google or openrouter, see Provider

OPENROUTER_API_KEY

–

Your OpenRouter key, only read when the provider is openrouter

GEMINI_MEDIA_OUTPUT_DIR

~/gemini-media

Where images, videos and sidecars are written

GEMINI_MEDIA_ALLOWED_DIRS

output dir

Folders input images may be read from, separated by : (; on Windows). Must contain the output dir

GEMINI_MEDIA_MAX_COST_PER_CALL

0.50

Max estimated USD per call

GEMINI_MEDIA_DAILY_BUDGET

2.00

Max estimated USD per day (local time)

GEMINI_MEDIA_MONTHLY_BUDGET

20.00

Max estimated USD per calendar month

GEMINI_MEDIA_MAX_INPUT_MB

7

Max size per input image

GEMINI_MEDIA_DEFAULT_IMAGE_MODEL

gemini-nano-banana-2.1

Default for image tools

GEMINI_MEDIA_DEFAULT_VIDEO_MODEL

gemini-omni-1.1-flash

Default for video tools

GEMINI_MEDIA_CONFIG

–

Path to a TOML file that overrides or adds models and prices

GEMINI_MEDIA_STATE_DIR

<output>/.gemini-media

Cost log and video job list

GEMINI_MEDIA_TIMEOUT_SECONDS

180

Timeout per API request

GEMINI_MEDIA_LOG_LEVEL

WARNING

Log level (logs go to stderr)

The default per-call limit of $0.50 blocks videos (a 10 s video costs about $1.01). Raise GEMINI_MEDIA_MAX_COST_PER_CALL deliberately if you want video.

Models and prices

The bundled catalogue is src/gemini_media_mcp/models.toml. Prices were checked on 2026-10-31 against the official price list. To change them, copy the file, edit it and point GEMINI_MEDIA_CONFIG at your copy. Each [models."<id>"] table in your file replaces the bundled entry for that ID.

Provider

By default the server talks only to Google (GEMINI_MEDIA_PROVIDER=google). Nothing changes unless you opt in.

Optionally, the image tools (generate_image, edit_image) can go through OpenRouter instead, using the same Google models:

GEMINI_MEDIA_PROVIDER=openrouter
OPENROUTER_API_KEY=...   # set it like GEMINI_API_KEY, never in a config file

What changes with openrouter:

  • Data flow: prompts and reference images go to openrouter.ai, which forwards them to Google. A second company sees your data. OpenRouter states that it does not store prompts or responses unless you opt in to logging in your account settings; check its privacy page yourself.

  • Routing: each request is pinned to Google's own providers on OpenRouter (google-ai-studio, then google-vertex), so no other company's model ever answers.

  • Models: the catalogue IDs map to OpenRouter's google/<id>, e.g. gemini-3-pro-image → google/gemini-3-pro-image. Same IDs in list_models, same options.

  • Prices: OpenRouter passes Google's token prices through, so the bundled estimates apply. Some Vertex regions are up to 10 % dearer; AI Studio is tried first. Your OpenRouter activity page is the real bill.

  • No video: OpenRouter has no video model. start_video and get_video_status return a clear error; switch back to google for video.

  • Unchanged: cost limits, the path sandbox, input checks, no-overwrite naming and the sidecar (which now records "provider"). The OpenRouter key gets the same redaction as the Gemini key, and the client refuses to contact any host other than openrouter.ai.

Cost examples

Estimates at Google's list prices from 2026-10-31 (USD, standard tier):

What

Model

Estimate

1 image, 1K

Nano Banana 2 Lite (gemini-3.1-flash-lite-image)

$0.034

1 image, 1K

Nano Banana 2.1 (gemini-nano-banana-2.1)

$0.034

1 image, 4K

Nano Banana 2.1

$0.113

1 image, 2K, 3 reference images

Nano Banana Pro (gemini-3-pro-image)

$0.141

1 image, 4K

Nano Banana Pro

$0.240

1 video, 720p, up to 10 s

Gemini Omni Flash

≈ $1.01

50 images per month, 1K

Nano Banana 2.1

≈ $1.70

The log stores estimates. Your Google bill is what counts; check it in AI Studio.

Security

  • API key: read only from GEMINI_API_KEY (or OPENROUTER_API_KEY with the opt-in OpenRouter provider) and sent only as an HTTP header to that provider. It is never logged, never part of the settings object and removed from every error message.

  • File access: input images are only read from GEMINI_MEDIA_ALLOWED_DIRS. Paths are fully resolved (symlinks included) before the check, so ../ tricks and symlinks pointing outside are rejected.

  • Input validation: the file type is detected from the file content (PNG, JPEG, WebP, HEIC/HEIF), not from the extension. Size is limited.

  • No overwrites: outputs are named YYYYMMDD-HHMMSS_<slug>.<ext> and created with exclusive-create; an existing name gets a -2, -3 … suffix.

  • Cost control: each call is priced before it is sent and rejected if it would break the per-call, daily or monthly limit. Videos need an explicit confirm_cost=true.

  • Network: the server talks only to the Google Gemini API (*.googleapis.com), or, if you opt in to the OpenRouter provider, only to openrouter.ai. No telemetry, no analytics, no update checks.

  • Dependencies: a handful of direct runtime dependencies, pinned exactly; the lockfile pins the rest. Dependabot and a gitleaks secret scan run on the repository.

More in SECURITY.md.

Transparency: sidecars and AI labelling

Every output gets a <name>.json next to it with prompt, model, provider, reference images (path and SHA-256), parameters, estimated cost and timestamp.

Google embeds an invisible SynthID watermark in every image and video generated with these models. If you publish the results, label them as AI-generated: from 2 August 2026, Article 50 of the EU AI Act requires that deepfakes, and AI-generated text published to inform the public, are disclosed as artificially generated. The sidecar files help you keep track of what was generated. (This is a pointer, not legal advice.)

Example prompts

Ask Claude in plain language, for example:

  • "Make a 16:9 header image: a robot eating lunch at a desk, flat illustration style, call it robot-lunch."

  • "Use ~/Pictures/gemini/me.jpg and ~/Pictures/gemini/logo.png: put the logo on my T-shirt, keep my face unchanged."

  • "What would a 9:16 video of waves at sunset cost?"

  • "Is the video done yet?"

  • "How much have I spent on images this month?"

Development

uv sync
uv run pytest          # tests use a fake API, no network
uv run ruff check . && uv run ruff format --check .
uv run mypy
uvx pre-commit install # gitleaks + ruff before each commit

See CONTRIBUTING.md.

License

MIT, see LICENSE.


Not affiliated with or endorsed by Google. Gemini, Nano Banana and Veo are trademarks of Google LLC.

Built by Wimplunch – Lunch is for wimps.

Available Tools

6 tools
cost_reportA
Read-only

Show estimated spend today, this month and in total, plus remaining budgets.

Inputs: no named parameters. Returns: object

edit_imageB

Edit or combine one or more images according to the prompt.

Inputs: prompt (required), image_paths (required), model, resolution, +2 more. Returns: object

generate_imageA

Create an image from a text prompt. Costs money; checked against the budget first.

Inputs: prompt (required), model, resolution, output_name, +1 more. Returns: object

get_video_statusA

Check a video job; when it is done, download the MP4 to the output directory.

Inputs: job_id (required). Returns: object

list_modelsA
Read-only

List configured models with estimated prices and supported options.

Inputs: no named parameters. Returns: object

start_videoA

Start a video generation job and return a job_id immediately (no waiting).

Inputs: prompt (required), model, resolution, output_name, +3 more. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 6 tools

    Disambiguation5/5

    Each tool targets a distinct action: image creation, image editing, model listing, video job start, video job polling, and budget reporting. The only mild overlap is that list_models shows prices while cost_report shows spend, but their purposes (catalog vs. accounting) are clearly separated.

    Naming Consistency4/5

    Five of six tools follow a clean verb_noun pattern (generate_image, edit_image, list_models, start_video, get_video_status). cost_report is a noun phrase and breaks the pattern slightly, but the set remains highly readable and predictable.

    Tool Count5/5

    Six tools is well-scoped for a media generation + budget server, with each tool earning its place. The async video flow is correctly split into start/status rather than bloating the surface.

    Completeness4/5

    Core lifecycle is covered: model discovery, image create/edit, video start/poll, and cost tracking. Minor gaps exist — no job cancellation, no way to list previously generated assets or inspect a single video job without downloading, and no equivalent edit_video.

    Related MCP Connectors

    Related MCP Servers