● LIVE· № 001 · SANITIZE EVERYTHING THAT HITS GIT: CLEANING PUBLIC REPOS FROM IDENTITY LEAKS · 2026.05.11· № 002 · IMAGEGEN-MCP: A HOMEGROWN MCP SERVER FOR BLOG COVERS · 2026.05.11· № 003 · SMART PASTE: STRIPPING TERMINAL NOISE BEFORE PASTING, WITH ONE HOTKEY · 2026.05.10· № 004 · CLAUDE CODE TEAM TELEMETRY: CENTRALIZED USAGE STATS · 2026.05.07· № 005 · CLAUDE CODE ONBOARDING GUIDE FOR NEWCOMERS · 2026.05.06· 11 POSTS · 0 DRAFTS
EN / RU
·5 MIN

imagegen-mcp: a homegrown MCP server for blog covers

Generating a cover for a post used to be curl + jq + sips + two manual edits. Now it's a single tool call inside Claude Code: prompt, size, path — done. Tiny TS server, public on GitHub, provider-agnostic.

The pain

Every blog post here now ships with an editorial cover — cartoon, 16:7, part of the robot-vacuum desk-scene series. Before this MCP, the flow looked like:

  1. Open a different tool: ChatGPT with image generation, Midjourney via Discord, web DALL·E, Leonardo, whatever. Each one with its own UI.
  2. Write the prompt from scratch. Each time, manually recall: what was the exact style of the last cover? Cartoon with which accents? Swiss-cartoon or just flat? Which character? — no history, no template you can hook into.
  3. Hit generate. Want variants — generate a few. Find one you like — download the PNG from the browser.
  4. Open Finder, drag the file into the project folder (apps/blog/public/assets/posts/<slug>/). Or attach it in Claude Code and say "here's a cover, wire it up".
  5. Claude copies it, updates the frontmatter, crops to 16:7 — if you have sips or ImageMagick locally. If not — yet another trip to another tool.

That's context-switching between two or three apps for a single image. And the bigger problem — you have to invent the style again every time, because ChatGPT/Midjourney doesn't remember between sessions that your blog has a cartoon series with a robot vacuum and a red accent at the bottom. You yourself are the only living memory of that style language.

I went looking for an existing MCP server that would work straight from Claude Code chat (no UI-switching, no manual file shuffling) and would also:

  • generate + edit + crop in one package,
  • be provider-agnostic (I want gpt-image-1.5 on OpenAI, sd3 on Stability, something on Replicate when the mood strikes),
  • not hardcode a model enum (because gpt-image-1 is gone, gpt-image-1.5 exists, some gpt-image-2 will appear tomorrow).

Nothing in the community fit. The ones I found were either OpenAI-only with stale enums, or missing edits, or missing crop. So I built one.

What I open-sourced

imagegen-mcp — github.com/acrossoffwest/imagegen-mcp. MIT, TS + @modelcontextprotocol/sdk. Four tools:

  • generate_image — text-to-image. The model is just a string, no enum hardcode.
  • edit_image — image edit / inpaint. Where a provider doesn't support it, the tool throws not_supported.
  • list_image_models — query /v1/models (or a known list), filter to image-capable IDs.
  • crop_image — sharp-based resize. cover / contain / fill modes, any gravity.

Built-in providers:

  • OpenAI native (gpt-image-1.5, dall-e-3, dall-e-2)
  • OpenAI-compatible via a custom baseUrl — handy for locally-hosted backends
  • Stability AI v2beta (sd3, core, ultra)
  • Replicate (flux, sdxl, ideogram, and any owner/name:version)

Config lives at ~/.config/imagegen-mcp/config.json. Per-provider env files:

{
  "providers": {
    "openai": {
      "type": "openai",
      "envFile": "~/.config/imagegen-mcp/openai.env",
      "envVar": "OPENAI_API_KEY"
    },
    "local": {
      "type": "openai",
      "envFile": "~/.config/imagegen-mcp/local.env",
      "envVar": "LOCAL_API_KEY",
      "baseUrl": "http://localhost:8000/v1"
    }
  },
  "defaultProvider": "openai",
  "defaultModel": "gpt-image-1.5"
}

Wire it into Claude Code:

claude mcp add imagegen -- npx -y tsx ~/projects/own-projects/imagegen-mcp/src/server.ts

After a restart, mcp__imagegen__* tools show up inside Claude Code. That's the whole install.

What this changes for the blog flow

Before: open ChatGPT (or Midjourney via Discord), build a prompt from scratch by hand, mentally reconstruct what style the last cover had, hit generate, pick from variants, download the PNG into ~/Downloads, drag it into the project folder, and only then say in Claude Code "here, wire it up as a cover" — which would copy the file and update the frontmatter, but I'd still go cropping to 16:7 separately.

Now: in Claude Code chat, "generate a cover for the new post, keep the cartoon series" — and it:

  1. Calls mcp__imagegen__generate_image with my standard prompt template, model gpt-image-1.5, size 1536x1024.
  2. Follows up with mcp__imagegen__crop_image down to 1536×672 (16:7), cover mode.
  3. Writes cover.png to apps/blog/public/assets/posts/<slug>/.
  4. Updates frontmatter in both locales.
  5. If something looks off — re-generate with a tweaked prompt, never leaving the chat.

No UI switching, no dragging files between Finder and the project. And the bigger win — the style language for the series lives in docs/post-covers/ and in my blog-specific CLAUDE.md, so Claude itself proposes "continue the series" instead of me reciting the style from memory every single time. This post's cover got generated through the MCP while I was writing the text: "let's draw something fitting, keep the series" → done, in frontmatter, on disk, rendering locally.

Gotchas

  • gpt-image-1 is gone, gpt-image-1.5 is what you use. The original gpt-image-1 is no longer in production (existing projects get does not exist from the API). Any third-party tool or MCP wrapper that hardcodes gpt-image-1 will fail. Just put gpt-image-1.5 everywhere.
  • dall-e-3 doesn't support edits. Text-to-image only. Edit/inpaint works on gpt-image-1.5 (and the legacy dall-e-2).
  • No native 16:7 from any provider. gpt-image: 1024×1024 / 1024×1536 / 1536×1024. dall-e-3 adds 1792×1024. Closest is 1536×1024, then crop_image to 1536×672.
  • MCP-server enum hardcodes in popular wrappers. spartanz51's imagegen-mcp only knows gpt-image-1 / dall-e-3 / dall-e-2 and dies on gpt-image-1.5. My version takes the model as a string — whatever you type goes straight to the API.

What I want to add

  • Reference-image mode: for posts that have a source photo I want to pass it into edit_image as a reference instead of describing it in words. Already works on gpt-image-1.5 through /v1/images/edits, but the tool-wrapper UX could be smoother.
  • Batch covers — n: 4 variants at once, pick visually. Right now defaults to n: 1, but the parameter does pass through.
  • Variations: dall-e-2's /v1/images/variations — for "same scene, slightly different" iterations. Not in edit_image yet, needs its own tool.
  • Spark imggen — my self-hosted Stable Diffusion on the home lab. The openai-compatible provider type works via custom baseUrl in theory, still need to wire it up against the real backend.

If anyone wants the shape for their own cover pipeline — clone, edit the config, claude mcp add, done. A single ~/.config/imagegen-mcp/config.json file controls everything.