{"slug": "claude-code-vs-gemini-my-stateful-image-workflow", "title": "Claude Code vs Gemini: My Stateful Image Workflow", "summary": "A developer has built a stateful image generation workflow using Google's Gemini 3.1 Flash Lite Image model (NB2Lite) wrapped in an MCP server, enabling iterative edits without losing visual context. The setup leverages the Interactions API to maintain state via interaction IDs, allowing follow-up prompts like \"add a neon sign\" without re-describing the entire scene. The developer reports cutting prompt-tweaking time by about 60% by avoiding stateless \"prompt and pray\" methods.", "body_md": "# Claude Code vs Gemini: My Stateful Image Workflow\n\nThe problem with most image gen is that it's basically goldfish memory. You ask for a cyberpunk kitchen, it gives you one. You ask to add a ramen sign, and suddenly the kitchen is gone, the lighting changed, and the \"cyberpunk\" vibe shifted to \"generic 90s sci-fi.\" It's stateless misery.\n\nI've been using a setup that wraps `gemini-3.1-flash-lite-image`\n\n(aka NB2Lite) into an [MCP](/en/tags/mcp/) server to feed it into Google Antigravity. Unlike the usual \"prompt and pray\" method, this uses the Interactions API, which actually maintains state. You generate an image, get an `interaction_id`\n\n, and then you can just say \"add a neon sign\" without re-describing the entire room.\n\n## The Technical Plumbing\n\nThe magic happens because the server handles the `interaction_id`\n\nhandoffs. If you're trying to build something similar, here is how the stateful loop actually functions:\n\n1. Initial call: `client.interactions.create(prompt=\"...\", store=True)`\n\n2. Response: You get an `interaction_id`\n\n.\n\n3. Follow-up: You send the new prompt + `previous_interaction_id`\n\n.\n\nThe server implementation I'm using (via FastMCP) basically abstracts this so the agent doesn't have to manage the IDs manually. Here is a snippet of how the tool definition looks in the `server.py`\n\nlogic:\n\n```\n# Example of how the stateful edit is handled in the MCP server\n@mcp.tool()\nasync def edit_image(prompt: str, interaction_id: str):\n    \"\"\"Edits an existing image using its interaction ID to maintain visual state.\"\"\"\n    response = await client.interactions.create(\n        prompt=prompt,\n        previous_interaction_id=interaction_id,\n        store=True\n    )\n    return {\n        \"image_url\": response.url,\n        \"new_interaction_id\": response.interaction_id\n    }\n```\n\n## Real-World Constraints (The \"Gotchas\")\n\nSince I'm the one actually dogfooding this while my team asks \"why isn't it perfect yet,\" here are the specific technical walls you'll hit:\n\n**The Aspect Ratio Trap:** You set the ratio (`1:1`\n\n,`16:9`\n\n, etc.) at the start. If you try to change it during a stateful edit, the pixel continuity falls apart. The server I'm using explicitly blocks aspect ratio changes during edits to prevent the model from hallucinating a new composition.**Thinking Levels:** The API documentation mentions`minimal`\n\nand`medium`\n\nthinking levels. In reality, if you send those to the flash-lite-image model, you get a crisp HTTP 400 error. Stick to`low`\n\nfor fast drafts and`high`\n\nfor when you actually need the text in the image to be readable.**ID Forking:** Every edit generates a*new*ID. If your agent accidentally references an ID from three turns ago, it doesn't error out—it just \"forks\" the image state back to that version, which is a nightmare to debug if you don't have logging enabled.\n\n## Deployment Workflow\n\nFor those who want to stop wasting time with stateless prompts, the deployment is straightforward. You need the `nb2lite-skill-agy`\n\npackage, which acts as both the MCP server and the Antigravity skill definition.\n\n1. Install the server dependencies.\n\n2. Configure your [Gemini](/en/tags/gemini/) API key in the environment.\n\n3. Link the MCP server to your Antigravity config.\n\nOnce that's done, the workflow changes from \"Write a 50-word prompt describing every detail\" to \"Change the color of that chair to red.\" It's significantly faster, and I've managed to cut my \"prompt tweaking\" time by about 60% because I'm not fighting the model to keep the background consistent.\n\n[Next System Design: Mastering Back-of-the-Envelope Estimation →](/en/threads/2801/)", "url": "https://wpnews.pro/news/claude-code-vs-gemini-my-stateful-image-workflow", "canonical_source": "https://promptcube3.com/en/threads/2817/", "published_at": "2026-07-24 16:50:14+00:00", "updated_at": "2026-07-24 17:07:46.140159+00:00", "lang": "en", "topics": ["generative-ai", "ai-tools", "developer-tools"], "entities": ["Google", "Gemini 3.1 Flash Lite Image", "NB2Lite", "MCP", "Google Antigravity", "Interactions API", "FastMCP", "nb2lite-skill-agy"], "alternates": {"html": "https://wpnews.pro/news/claude-code-vs-gemini-my-stateful-image-workflow", "markdown": "https://wpnews.pro/news/claude-code-vs-gemini-my-stateful-image-workflow.md", "text": "https://wpnews.pro/news/claude-code-vs-gemini-my-stateful-image-workflow.txt", "jsonld": "https://wpnews.pro/news/claude-code-vs-gemini-my-stateful-image-workflow.jsonld"}}