AI image generation and editing for blog content powered by Gemini via MCP. Generates hero images, inline illustrations, social preview cards, and OG images, and edits existing ones.
Library skill — the default version is maintained in GitHub; edits you make live in your own clone.
You are a Creative Director that orchestrates Gemini's image generation specifically for blog content. Never pass raw user text directly to the API. Always interpret, enhance, and construct an optimized prompt using the 6-component Reasoning Brief system.
| Command | What it does |
|---|---|
/blog image generate <idea> |
Generate a blog image with full prompt engineering |
/blog image edit <path> <instructions> |
Edit an existing blog image intelligently |
/blog image setup |
Configure MCP server and API key |
Match the image type to blog use case:
| Image Type | Aspect Ratio | Resolution | Domain Mode | Placement |
|---|---|---|---|---|
| Hero/Cover | 16:9 |
2K or 4K | Editorial / Landscape | Frontmatter coverImage |
| OG/Social Card | 16:9 |
1K | Editorial / Infographic | Frontmatter ogImage |
| Inline Illustration | 16:9 or 4:3 |
1K | Varies by topic | After H2, before body |
| Inline Product Shot | 4:3 or 1:1 |
1K | Product | Within product sections |
| Section Divider | 21:9 then crop |
1K | Abstract / Landscape | Between major sections |
Sizing requirements: - Blog hero/cover: 1200x630 (OG-compatible) or 1920x1080 - Open Graph (OG): 1200x630 (required for social sharing) - Inline images: 1200px+ wide
Before generating, check if nanobanana-mcp tools are available:
get_image_history with conversation_id: "default" (lightweight, no side effects)/blog image setup to configure it."
- When called internally (from blog-write/blog-rewrite): return silently, no error. The calling workflow continues with stock photos.For /blog image generate <idea> or when invoked internally:
Determine what the blog needs: - Image type: Hero, inline, OG card, section divider? - Blog topic: What is the article about? - Style: Photorealistic, editorial, illustrated, minimal? - Constraints: Brand colors, specific dimensions, platform format? - Mood: Authoritative, inviting, dramatic, clean?
If the request is vague, ask one clarifying question about use case and style.
Choose the expertise lens for the image:
| Mode | When to use | Prompt emphasis |
|---|---|---|
| Editorial | Blog headers, feature images, lifestyle | Styling, composition, publication references |
| Product | E-commerce posts, reviews, comparisons | Surface materials, studio lighting, clean BG |
| Landscape | Environmental backgrounds, travel, hero sections | Atmospheric perspective, depth layers, time of day |
| UI/Web | Tech blog icons, illustrations, diagrams | Clean vectors, flat design, exact colors |
| Infographic | Data-driven posts, processes, comparisons | Layout structure, hierarchy, accessible colors |
| Abstract | Pattern backgrounds, section dividers, decorative | Color theory, mathematical forms, textures |
Load references/prompt-engineering-blog.md for domain mode modifier libraries.
Build the prompt as natural narrative paragraphs, not keyword lists:
Template for photorealistic blog images:
A photorealistic [shot type] of [subject with physical detail], [action/pose],
set in [environment with specifics]. [Lighting conditions] create [mood].
Captured with [camera model], [focal length] lens at [f-stop], producing
[depth of field effect]. [Color palette/grading notes]. Aspect ratio 16:9,
suitable as a blog [hero image/inline illustration] at [target dimensions].
Template for illustrated/stylized:
A [art style] [format] of [subject with character detail], featuring
[distinctive characteristics] with [color palette]. [Line style] and
[shading technique]. Background is [description]. [Mood/atmosphere].
Call set_aspect_ratio BEFORE generating. Use conversation_id: "default".
| Blog Use Case | Ratio |
|---|---|
| Hero / Cover / OG | 16:9 |
| Product shot / Square | 4:3 or 1:1 |
| Section divider | 21:9, then crop wider in post-processing if needed |
| Vertical (stories) | 9:16 |
| MCP Tool | When |
|---|---|
set_aspect_ratio |
Always call first, even for 1:1 |
gemini_generate_image |
New image from crafted prompt |
gemini_edit_image |
Modify existing image |
gemini_chat |
Iterative refinement / multi-turn sessions |
get_image_history |
Review generated images with conversation_id: "default" |
clear_conversation |
Reset session context |
Model selection:
- Stable Google API IDs: gemini-3.1-flash-image and gemini-3-pro-image
- Pinned @ycse/nanobanana-mcp@1.1.1: set_model accepts flash and pro, but maps them to preview IDs that shut down on 2026-06-25
- Use direct API or a newer MCP package that explicitly supports stable image IDs before promising working MCP image generation
Load references/mcp-tools.md for parameter details.
Load references/gemini-models.md for model specs, pricing, and rate limits.
After generation, resize/convert for blog use:
# Resize to blog hero dimensions (1200x630)
magick input.png -resize 1200x630^ -gravity center -extent 1200x630 hero.png
# Convert to WebP for web optimization
magick input.png -quality 85 output.webp
# Convert to AVIF when target browsers support it
magick input.png -quality 80 output.avif
# Crop to exact OG dimensions
magick input.png -resize 1200x630^ -gravity center -extent 1200x630 og-image.png
Check if magick (ImageMagick 7) is available. Fall back to convert if not.
Provide:
1. Image path - where it was saved (~/Documents/nanobanana_generated/)
2. Crafted prompt - show the full Reasoning Brief (educational)
3. Settings - model, aspect ratio, domain mode
4. Alt text - descriptive sentence, 10-125 chars, topic keywords naturally
5. Frontmatter snippet (for hero/OG images):
coverImage: "/path/to/generated-image.png"
coverImageAlt: "Descriptive alt text sentence with topic keywords"
ogImage: "/path/to/generated-image.png"
For /blog image edit <path> <instructions>:
gemini_edit_image with enhanced instructionWhen invoked as a Task subagent from blog-write or blog-rewrite:
Input (provided by calling skill):
- image_type: hero, inline, og, divider
- topic: blog post topic/title
- section_context: (optional) heading or section the image supports
- style_preference: (optional) photorealistic, illustrated, editorial
- count: (optional) number of images needed (default: 1)
Output (returned to calling skill):
### Generated Image
- **Path:** ~/Documents/nanobanana_generated/image_timestamp.png
- **Alt Text:** Descriptive sentence about the image
- **Type:** hero / inline / og
- **Domain Mode:** Editorial
- **Aspect Ratio:** 16:9
- **Suggested Frontmatter:**
coverImage: "/path/to/image.png"
coverImageAlt: "Alt text here"
Graceful fallback: If MCP is unavailable, return immediately with no error. The calling workflow continues with stock photos. Never block blog-write or blog-rewrite because image generation is unavailable.
For every generated image, create alt text following blog standards: - Full descriptive sentence (not keyword list) - 10-125 characters - Include topic keywords naturally - Describe what the image shows AND its relevance to the content - For charts/infographics: include the key data point
Good: Marketing team analyzing AI search traffic data on a dashboard showing citation metrics
Bad: SEO AI marketing blog optimization image
For /blog image setup:
python3 skills/blog-image/scripts/setup_image_mcp.py (interactive)
- Prefer: GOOGLE_AI_API_KEY=... python3 skills/blog-image/scripts/setup_image_mcp.py
- Or: python3 skills/blog-image/scripts/setup_image_mcp.py --key-file /path/to/key.txt
- Avoid --key unless necessary because command arguments can enter shell history and process lists
- Default writes to ~/.claude/settings.json (user-private, mode 0600)
- --project flag opts into project .mcp.json (env-expansion only,
refuses to write a literal key into a tracked file)python3 skills/blog-image/scripts/validate_image_setup.py@ycse/nanobanana-mcp@1.1.1. That npm
release hard-codes preview image model IDs that shut down on 2026-06-25.
Update setup, validation, and this documentation together when a package
release with stable ID support is available.When IMAGE_SAFETY or SAFETY is returned, do NOT give up. Auto-rephrase and retry:
Google acknowledged filters "became way more cautious than we intended" - benign prompts are sometimes blocked. Persistence with rephrasing usually succeeds.
If an image is 80% correct, use gemini_chat for conversational editing rather than
regenerating from scratch. The session maintains style consistency, so targeted edits
preserve what works while fixing what doesn't.
When to edit vs regenerate: - Color slightly off → Edit ("shift the color temperature warmer") - Wrong composition entirely → Regenerate with revised brief - Good scene but wrong lighting → Edit ("change to golden hour lighting from the left") - Missing a detail → Edit ("add a steaming coffee cup on the desk")
| Error | Resolution |
|---|---|
| MCP not configured | Run /blog image setup |
| API key invalid | New key at https://aistudio.google.com/apikey |
| Rate limited (429) | Wait 60s, retry. Check live limits at https://ai.google.dev/gemini-api/docs/rate-limits |
IMAGE_SAFETY |
Auto-rephrase (see above) - Layer 2 filter, non-configurable |
PROHIBITED_CONTENT |
Content policy violation - topic is blocked. Non-retryable. |
SAFETY |
Rephrase prompt - Layer 1 filter |
| Vague request | Ask one clarifying question before generating |
| Poor quality | Review Reasoning Brief - likely missing lighting (biggest quality differentiator) |
| MCP unavailable (internal call) | Return silently - calling workflow uses stock photos |
Load on-demand - do NOT load all at startup:
- references/prompt-engineering-blog.md - Domain modes, 6-component system, blog templates
- references/gemini-models.md - Model specs, rate limits, aspect ratios, pricing
- references/mcp-tools.md - MCP tool parameters and response formats