--- name: blog-image description: > 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. Supports 6 domain modes (Editorial, Product, Landscape, UI/Web, Infographic, Abstract). Works standalone or internally from blog-write and blog-rewrite; falls back gracefully when MCP is unavailable. Use when user says "blog image", "generate hero image", "blog illustration", "edit blog image", "OG image". user-invokable: true argument-hint: "[generate|edit|setup] [description-or-path]" license: MIT metadata: author: AgriciDaniel version: "2.1.1" mcp-package: "@ycse/nanobanana-mcp" --- # Blog Image - AI Image Generation for Blog Content 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. ## Quick Reference | Command | What it does | |---------|-------------| | `/blog image generate ` | Generate a blog image with full prompt engineering | | `/blog image edit ` | Edit an existing blog image intelligently | | `/blog image setup` | Configure MCP server and API key | ## Blog Image Types 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 ## MCP Availability Check Before generating, check if nanobanana-mcp tools are available: 1. Try calling `get_image_history` with `conversation_id: "default"` (lightweight, no side effects) 2. If it succeeds: MCP is available, proceed with generation 3. If it fails: MCP not configured - inform the user: - "Image generation requires the nanobanana-mcp server. Run `/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. ## Generation Workflow For `/blog image generate ` or when invoked internally: ### Step 1: Analyze Intent 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. ### Step 2: Select Domain Mode 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. ### Step 3: Construct the 6-Component Reasoning Brief Build the prompt as natural narrative paragraphs, not keyword lists: 1. **Subject** - Who/what, with rich physical detail (textures, materials, scale) 2. **Action** - What is happening, pose, gesture, movement, state 3. **Context** - Environment, setting, time of day, season, weather 4. **Composition** - Camera angle, shot type, framing, negative space, depth 5. **Lighting** - Light source, quality, direction, color temperature, shadows 6. **Style** - Art medium, aesthetic, film stock, reference artists/eras **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]. ``` ### Step 4: Set Aspect Ratio 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` | ### Step 5: Generate via MCP | 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. ### Step 6: Post-Processing (when needed) After generation, resize/convert for blog use: ```bash # 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. ### Step 7: Deliver 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): ```yaml coverImage: "/path/to/generated-image.png" coverImageAlt: "Descriptive alt text sentence with topic keywords" ogImage: "/path/to/generated-image.png" ``` 6. **Refinement suggestions** - 1-2 ideas if relevant ## Edit Workflow For `/blog image edit `: 1. Read the image path and edit instruction 2. Enhance the instruction (never pass raw): | User says | Claude crafts | |-----------|---------------| | "remove background" | Detailed edge-preserving background removal | | "make it warmer" | Specific color temperature shift with preservation notes | | "add text" | Font style, size, placement, contrast, readability notes | | "make it brighter" | Increase exposure, lift shadows, maintain highlights | | "crop for social" | Resize to 1200x630 with center-gravity crop | 3. Call `gemini_edit_image` with enhanced instruction 4. Return modified image path and description ## Internal API (for blog-write / blog-rewrite) When 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): ```markdown ### 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. ## Alt Text Generation 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` ## Setup For `/blog image setup`: 1. Run `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) 2. Verify: `python3 skills/blog-image/scripts/validate_image_setup.py` 3. Requires: - Node.js 18+ (npx) - Google AI API key, free to create at https://aistudio.google.com/apikey - A billing-enabled project may be required for image models 4. The script pins the package to `@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. ## Safety Filter Auto-Rephrase When `IMAGE_SAFETY` or `SAFETY` is returned, do NOT give up. Auto-rephrase and retry: 1. Identify the likely trigger (violence, public figures, NSFW-adjacent, or overly cautious filter) 2. Rephrase using positive framing - describe what you WANT, not what to avoid 3. If the subject is a person, make them generic (remove celebrity-like specifics) 4. If the scene is dramatic, soften: "intense" → "focused", "battle" → "competition" 5. Retry with the rephrased prompt (max 3 attempts before reporting to user) Google acknowledged filters "became way more cautious than we intended" - benign prompts are sometimes blocked. Persistence with rephrasing usually succeeds. ## Edit, Don't Re-roll 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 Handling | 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 | ## Reference Documentation 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