Ask your AI assistant to "make an OG image for this post" and you get one of two failures. If it reaches for a diffusion model you get soft gradients, warped typography and a title that looks photographed through water. If it does not, it writes you a perfectly good block of HTML and CSS and then apologises, because it has nowhere to render it.
The second failure is the interesting one. The model already did the design work. Layout, spacing, type scale, brand colour, all expressed precisely in the one design language every LLM has read millions of examples of. It was not missing ability. It was missing a render step.
This post wires that step in over MCP, so your agent can design, render and refine real image assets inside the conversation. It is a condensed version of our full guide, How to generate images from an AI agent with MCP, which also covers VS Code, Windsurf and the other clients.
Why diffusion is the wrong tool
Diffusion models are remarkable for photographic concepts and a lottery for layout. They cannot reliably render text, cannot hit exact pixel dimensions, cannot reuse your brand tokens and cannot produce the same output twice. A pricing card, an invoice, a certificate or an OG image needs all four.
HTML and CSS are the opposite: deterministic, pixel-exact, versionable and the most documented visual format in the model's training data. An LLM that mangles the word "Launch" in a generated picture will happily set it in Inter 800 at 96px with correct kerning, because that is just text.
So let the model design in the language it is fluent in, and bolt a renderer onto the end.
Prerequisites
- An MCP-capable client (Claude Code or Cursor below)
- An HTML to Image API key on a paid plan
The server is remote, so there is nothing to install or host. It lives at https://app.html2img.com/mcp, speaks Streamable HTTP and takes the API key as a bearer token.
Step 1: connect the server
Claude Code is one line:
claude mcp add --transport http html2img https://app.html2img.com/mcp \
--header "Authorization: Bearer YOUR_API_KEY"
Cursor takes the same server in ~/.cursor/mcp.json, or .cursor/mcp.json for a single project:
{
"mcpServers": {
"html2img": {
"url": "https://app.html2img.com/mcp",
"headers": { "Authorization": "Bearer YOUR_API_KEY" }
}
}
}
That exposes two tools. generate-image-from-html renders complete HTML to a PNG or PDF. screenshot-url captures a live page, with optional injected CSS and an element selector. Both cost one credit per image.
Step 2: ask for an image
With the server connected, image generation is just conversation:
Make me a 1200x630 launch card for "Relay 2.0". Dark background, big title, a one-line subtitle that says "Webhooks that retry themselves", and our accent green #10B981.
The agent writes something like this and calls the tool with it:
<!doctype html>
<html>
<head>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@500;800&display=swap');
body {
width: 1200px; height: 630px; margin: 0;
display: flex; flex-direction: column; justify-content: center;
padding: 80px; box-sizing: border-box;
background: #0B1220; font-family: 'Inter', sans-serif;
}
.pill {
color: #10B981; font-weight: 500; font-size: 22px;
letter-spacing: 0.14em; text-transform: uppercase;
}
h1 { color: #fff; font-size: 96px; font-weight: 800;
letter-spacing: -0.02em; margin: 18px 0 24px; }
p { color: #94A3B8; font-size: 30px; margin: 0; }
</style>
</head>
<body>
<span class="pill">Now shipping</span>
<h1>Relay 2.0</h1>
<p>Webhooks that retry themselves.</p>
</body>
</html>
Two seconds later the rendered card is in the chat with a permanent CDN URL. No Chromium install, no Puppeteer script, no switch to a design tool.
Step 3: let it look at its own work
Here is the part that makes this better than fire-and-forget generation. The tool returns two things to the model: the full-resolution URL, and a downscaled preview image. The preview means the model sees what it made.
So it reviews its render the way you would. It notices the subtitle crowding the title, or a long product name clipping the right edge, then edits the HTML and renders again. You can steer with plain language ("tighten the spacing, the title feels lost") or tell it to critique its own output before showing you. Either way you iterate at conversation speed.
Each pass costs a credit, so three refinements is three credits. For design work that is the right trade, because the alternative is your afternoon.
Step 4: put your brand in a rules file
The highest-value trick is the simplest. Every agent runtime has a standing-instructions file (CLAUDE.md, Cursor rules, Copilot instructions). Put your visual system in it once:
When generating images with the html2img MCP server:
- Canvas 1200x630 for OG images, 1080x1080 for Instagram
- Fonts: Inter for UI, weights 500 and 800 only
- Background #0B1220, text #FFFFFF, muted #94A3B8, accent #10B981
- Embed any image as a base64 data URI, never a remote URL
- Complete, self-contained HTML with styles in one <style> block
Every image the agent produces from then on is on-brand without restating anything. The data URI rule is technical as well as stylistic: the renderer skips remote <img> sources by design, so assets go inline. Google Fonts are the exception and load server-side, which is why the @import above just works.
When not to use MCP
MCP and the REST API are the same engine, so the question is only who calls it. A person or agent in the loop, designing assets or screenshotting pages mid-task: MCP. Your application rendering an OG image per post at build time or an invoice per order: the REST API, because pipelines want code paths, not conversations.
They compose well. Design the template in a chat, iterate until the render is right, then lift the final HTML into your codebase and call the API with real data. The MCP session is the design phase, the API call is production.
We eat this cooking ourselves: every cover image on the HTML to Image blog is produced by an agent that writes the HTML, renders it, inspects the preview and fixes its own mistakes before anything ships. The full guide covers the remaining clients, the complete tool parameters and the PDF output mode.
Have you wired image rendering into your agent setup, and what did you have it build first? Share it in the comments.
Top comments (0)