Nano Banana 2 Lite in Kiro CLI 3: MCP 2.0, the New Interactions API, and Headless Permissions A developer published an update guide for the nb2lite-kiro project, a Python MCP server that drives Google's Gemini 3.1 Flash-Lite Image model (nicknamed Nano Banana 2 Lite) through the Gemini Interactions API inside Kiro CLI 3. The update migrates the server to MCP Python SDK 2.x and google-genai 2.x after Google removed the legacy Interactions API schema on 2026-06-08, and adds a fifth tool, edit_local_image_with_style, plus headless permission rules and a live verification skill. The server code itself was unchanged, since it already read the interaction's output_image field. This article provides a step by step update guide for a Python MCP server that drives Google Nano Banana 2 Lite gemini-3.1-flash-lite-image through the Gemini Interactions API, running inside Kiro CLI 3. Two dependency lines moved underneath the server: the MCP Python SDK went to 2.x, and the Interactions API dropped the schema that google-genai 1.x speaks. The server is then registered with Kiro, given a permission rule, and validated end to end against the live API from a headless Kiro 3 session. https://github.com/xbill9/nb2lite-kiro https://github.com/xbill9/nb2lite-kiro What is old is new — again. The same update was written up for Claude Code, Codex and Antigravity CLI: Nano Banana 2 Lite, Revisited: MCP 2.0, the New Interactions API, and Three Agent CLIs https://dev.to/gde/nano-banana-2-lite-revisited-mcp-20-the-new-interactions-api-and-three-agent-clis-37g5 This is the Kiro edition. nb2lite-kiro tracks xbill9/nb2lite https://github.com/xbill9/nb2lite , and server.py , test agent.py , requirements.txt and the Makefile are byte-identical between the two. Everything that differs is how Kiro launches the server, how it is allowed to call it, and where it finds the skill. | | Before | After | |---|---|---| | MCP SDK | mcp.server.fastmcp.FastMCP | mcp.server.mcpserver.MCPServer | | google-genai | unpinned, 1.x | google-genai =2,<3 | | Tools | 4 | 5 — adds edit local image with style | | Kiro server name | nb2lite-agent | nb2lite | | API key | written into mcp.json and .env | read from ~/gemini.key at launch | | Live check | manual | .kiro/skills/verify-live | Nano Banana 2 Lite is the nickname for Gemini 3.1 Flash-Lite Image , Google's low-latency image generation and editing model: Gemini 3.1 Flash-Lite Image Nano Banana 2 Lite | Google Cloud Documentation https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/gemini/3-1-flash-lite-image The Interactions API . Every call is stored server-side with store=True and returns an interaction ID. Pass that ID back as previous interaction id and the model edits the image it already made, instead of redrawing a scene from a fresh prompt. That keeps the MCP surface small. generate image starts a session, edit image continues one, and Kiro only has to carry an ID between turns. The server's code did not change. The API moved away from the SDK it was installed with. This is the call server.py makes, run with google-genai 1.x from a scratch install: c = genai.Client api key=... c.interactions.create model="gemini-3.1-flash-lite-image", input="a small red cube on a white table", response format={"type": "image"}, generation config={"thinking level": "minimal"}, store=True, google-genai 1.75.0 BadRequestError: Error code: 400 - {'error': {'message': 'The legacy Interactions API schema is no longer supported. Please upgrade your google-genai Python SDK to version = 2.0.0 e.g., run pip install -U google-genai to use the Interactions API. For details and migration examples, see: https://ai.google.dev/gemini-api/docs/interactions-breaking-changes-may-2026', 'code': 'invalid request'}} The message names the fix. Inside Kiro it is easy to miss: every tool catches the exception and returns it as a 🔴 string, so the agent reports "Image generation failed" with the version number buried in the text. google-genai 2.x reads the new schema, where the model's output arrives as a list of steps . The SDK exposes the generated image as interaction.output image , with data and mime type . server.py already read output image , so upgrading the SDK was the whole fix: image output = getattr interaction, "output image", None ... data = getattr image output, "data", None if isinstance data, str : image bytes = base64.b64decode data else: image bytes = data The legacy schema was removed on 2026-06-08. The unit tests mock get client , so the SDK never builds a real response and they pass against a broken API. One test now builds a real steps-schema Interaction with the SDK's own model and runs it through the response handler: interaction = Interaction.model validate { "id": "int steps", "status": "completed", "steps": { "type": "model output", "content": {"type": "image", "data": "aGVsbG8=", "mime type": "image/png"} , } , } result = handle response interaction, "steps" On google-genai 1.x that import does not exist, so the test fails loudly instead of the API failing quietly. The rest of the gap is the live check later in this article. The import and the constructor: python -from mcp.server.fastmcp import FastMCP +from mcp.server.mcpserver import MCPServer - Initialize FastMCP Server -mcp = FastMCP "NB2Lite Agent" + Initialize MCP Server mcp =2 renamed FastMCP to MCPServer +mcp = MCPServer "NB2Lite Agent" @mcp.tool , mcp.run and every tool body stay as they are. The full walk-through of the 2.x changes is in the companion article: FastMCP Is Now MCPServer: Migrating a Python MCP Server to the MCP SDK 2.x https://dev.to/gde/fastmcp-is-now-mcpserver-migrating-a-python-mcp-server-to-the-mcp-sdk-2x-2nhj list tools is async on MCPServer . The old test reached into a private attribute: - tools = t.name for t in mcp. tool manager.list tools + tools = t.name for t in asyncio.run mcp.list tools Both requirements now carry a floor and a ceiling, so the next major version arrives on purpose: -google-genai -mcp +google-genai =2,<3 +mcp =2,<3 cd ~ git clone https://github.com/xbill9/nb2lite-kiro cd nb2lite-kiro make install source set env.sh set env.sh reads the key from ~/gemini.key , or prompts for it and saves it there with mode 600 . It then rewrites the nb2lite entry in .kiro/settings/mcp.json with this checkout's path. python3 -m pip show mcp google-genai | grep -E "^ Name|Version " kiro-cli --version Name: google-genai Version: 2.22.0 Name: mcp Version: 2.2.0 kiro-cli 2.21.4 make lint ruff check . All checks passed ruff format --check . 6 files already formatted mypy . Success: no issues found in 2 source files mypy is not in requirements.txt . On this machine make lint first failed with make: mypy: No such file or directory , and python3 -m pip install mypy fixed it. make test ---------------------------------------------------------------------- Ran 12 tests in 0.412s OK Kiro speaks JSON-RPC over stdio, so test that too. Hold stdin open with sleep , or the server sees end-of-input before it answers: { printf '%s\n' \ '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"0"}}}' \ '{"jsonrpc":"2.0","method":"notifications/initialized"}' \ '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'; sleep 4; } \ | python3 server.py 2 /dev/null Summarised: initialize OK: name='NB2Lite Agent' version='' proto 2025-06-18 tools/list OK: 5 tools - generate image, edit image, edit local image, edit local image with style, get help 🟢 Five tools. The blank version is what an unversioned MCP 2.x server reports. The workspace config registers the server as nb2lite : { "mcpServers": { "nb2lite": { "command": "bash", "args": "-c", "GEMINI API KEY=$ cat ~/gemini.key exec python3 /home/xbill/nb2lite-kiro/server.py" , "disabled": false } } } 🔎 Tip: the old setup put the key in the config. The previous init.sh injected GEMINI API KEY into the server's env block in mcp.json and wrote a .env file beside it. The bash -c launch reads ~/gemini.key each time Kiro starts the server, so the key never lands in a file inside the repository. kiro-cli mcp list kiro-cli mcp status --name nb2lite 🤖 default: kiro default • aws-mcp uvx • nb2lite bash Scope : 🤖 default Agent : kiro default Command : bash Timeout : 120000 ms Disabled: false Env Vars: none Env Vars: none is the point: nothing secret in the registration. On kiro-cli 2.21.4, the next generation agent is a flag: kiro-cli chat --v3 It starts the Kiro Agent Server, which logs its own version: INFO kas.server.starting {"product":"KAS Kiro Agent Server ","version":"0.63.3"} The mcp.json above works unchanged under v3, and skills in .kiro/skills/