A red fabric ribbon opens into a broad sail and deep pleated folds against a charcoal background
All posts

Generate images in Claude Code with an MCP server

Claude Code has no image model of its own. Connect AIVAX's hosted Media Generation MCP to generate images with size and format control, or MP3 speech, and see each image's cost.

Ask Claude Code for a hero image and, with no image tool connected, it writes an SVG or a canvas script. That works for an icon. For a photograph or an illustration it needs an MCP server that exposes an image tool; once one is connected, the assistant decides when to call it, passes a prompt, and gets back a link to a file. Cursor and VS Code reach the same tools through their own MCP settings.

We run one of those servers. The AIVAX Media Generation MCP is hosted, so there is no local process or Python environment to keep alive, and the same connection also does text-to-speech. The full contract is in the Media Generation MCP reference, and our overview of AIVAX MCPs explains how these service connections sit next to the rest of an agent's tools.

One remote server, three tools

The server speaks Streamable HTTP at https://inference.aivax.net/v1/mcp/media-generation and authenticates with an AIVAX API key. In Claude Code, one command adds it, following the remote HTTP server option in Anthropic's docs:

claude mcp add --transport http aivax-media \
  https://inference.aivax.net/v1/mcp/media-generation \
  --header "Authorization: Bearer $AIVAX_API_KEY" \
  --header "X-Mcp-Enabled-Tools: list_models, generate_image, generate_speech"

The shell expands $AIVAX_API_KEY when you run it, and Claude Code stores the value in its local configuration. To share the server with a team through a committed .mcp.json at the project root, keep the key out of the file and let Claude Code expand it from each developer's environment:

{
  "mcpServers": {
    "aivax-media": {
      "type": "http",
      "url": "https://inference.aivax.net/v1/mcp/media-generation",
      "headers": {
        "Authorization": "Bearer ${AIVAX_API_KEY}",
        "X-Mcp-Enabled-Tools": "list_models, generate_image"
      }
    }
  }
}

The type field is required; Claude Code treats an entry with a url and no type as a local process and skips it. Run claude mcp get aivax-media to check the connection, and approve the project server the first time you start claude in that folder.

The AIVAX documentation shows the VS Code shape, with servers as the wrapper:

{
  "servers": {
    "aivax-media": {
      "type": "http",
      "url": "https://inference.aivax.net/v1/mcp/media-generation",
      "headers": {
        "Authorization": "Bearer <AIVAX_API_KEY>",
        "X-Mcp-Enabled-Tools": "list_models, generate_image, generate_speech"
      }
    }
  }
}

VS Code's MCP guide and Cursor's cover their own options; in every client the URL and the two headers are what carry over. Keep the real key in the client's secret storage or an environment variable, never in a committed file, a shared prompt, or a log.

X-Mcp-Enabled-Tools decides what the assistant can see. For an image-only setup we send list_models, generate_image; for speech, list_models, generate_speech. Names are case-insensitive and surrounding spaces are ignored. Leaving the header out exposes all three tools, while a value with no recognized name exposes none, which is the usual reason a freshly connected server shows an empty tool list. Clients cache discovery, so reconnect after changing it. The allowlist narrows one connection, not the key: a client holding the key can send a different header, which is why we treat key scope as the real control, as argued in the post on connecting third-party MCP servers safely.

All three tools need a positive account balance, including list_models, even though listing is free.

Let the assistant pick a real model name

We keep list_models enabled in every setup, because an assistant left to guess will type a model name it remembers from another provider, and generation rejects names that are not in the catalog. Called with {"type": "image"}, it returns each model's name, description, price, and whether it accepts reference images; deprecated image models are left out. The catalog is large and the cheapest image models cost under two cents per output, so the price column is worth reading before the assistant commits to something expensive.

With a name in hand, generate_image takes a prompt and a few optional controls:

{
  "prompt": "Editorial photograph of red fabric folded into a sail, charcoal background, no text",
  "model": "<IMAGE_MODEL_NAME>",
  "count": 2,
  "size": "1200x675",
  "format": "webp",
  "quality": 85
}

prompt must be non-empty and count runs from 1 to 4, defaulting to 1. size is <width>x<height> with each side between 64 and 4096 pixels; the documented default is 1080x1920, and a model may adjust the request to dimensions it supports. format is png, jpeg, or webp, and quality from 1 to 100 applies to the last two. These options arrived on 2 November, according to the changelog. Before that, a cover meant for a 1200x675 slot came back at the model's own size and format, and the assistant had to write a resize-and-convert step around it.

The tool answers with MCP text listing each image's URL and cost, the error for any image that failed, and the total. A failed image is not charged, so asking for four and getting three costs three.

To steer the result with an existing picture, pick a model whose listing says it supports references and add reference_images with up to four public HTTP(S) URLs. Models without reference support reject the call. A reference guides composition and style; it does not guarantee that a face or a product survives intact, so look at the output before you ship it. Image Generation has the prompting guidance.

Speech comes back as an MP3 link

list_models with {"type": "audio"} returns the speech models. generate_speech then needs input and model:

{
  "input": "The exhibition opens on Thursday. Please collect your ticket at the entrance.",
  "model": "<SPEECH_MODEL_NAME>"
}

Without voice, the model's default voice is used, and voices are specific to each model, so do not carry a voice name across. The optional instructions field takes direction such as "friendly and calm, moderate pace". On some providers AIVAX implements that by rewriting the input with auditory hints through an extra, billed inference step before synthesis; leave instructions out when you want only the synthesis charge. Write abbreviations, dates, and numbers the way they should be spoken, and listen to a few representative lines before settling on a voice.

The result is a public MP3 URL. There is no format argument and no inline audio on this path; the Speech Generation API returns other formats directly when you need WAV or OGG.

What it costs and where the quota runs out

Both tools bill the authenticated account at the same tariffs as the generation APIs. Image models have a fixed price per delivered output plus, where it applies, a price per reference image for each output, and image generation is exempt from the plan multiplier described in Pricing. Speech is recorded like any Speech Generation API call against the key, plus the inference charge when instructions triggers the rewrite.

Quotas are shared. Image generation counts against the account's daily image quota of 5, 150, 1,500, and 5,000 requests on Free, Pro, Max, and Ultimate (limits), where one request can produce up to four images. Text-to-speech shares its counter with the Speech Generation API: 3 per minute and 40 per hour on Free, then 20, 100, and 300 per minute on the paid plans (speech limits). Connecting a second editor does not create a second quota.

The returned URLs are public

Anyone holding a generated URL can open the image or play the audio. Authenticating the request does not make the asset private, and that matters on the speech side in particular: the Speech Generation API returns audio without storing it, while this MCP uploads the MP3 to public storage so it can hand the assistant a link. We keep this path for content we would publish anyway, and we do not pass sensitive pictures as reference URLs either. Download what you keep into storage you control, because the link travels with the transcript and with any code that embeds it.

When a different setup fits better

If you need to work offline or never want a metered bill, run a local image model behind a local MCP server, and budget for the GPU and the upkeep. A local wrapper around a paid provider's API does not remove that provider's bill. If your workflow already depends on one image provider and needs parameters outside this schema, that provider's own server may serve you better. And if the job is a batch of assets from a script rather than a conversation, the AIVAX CLI has aivax generate image with the same --size, --format, and --quality options, which keeps the assistant out of the loop entirely.

Checked against the AIVAX source, the AIVAX documentation, and Anthropic's Claude Code MCP page on 9 November 2026. No paid generation was run for this revision, so the tool output is described from the documented contract rather than shown.