{
  "source_file": "0930",
  "source_platform": "Dev.to",
  "author": "xbill",
  "title_listed": "Nano Banana 2 Lite in Kiro CLI 3: MCP 2.0, the New Interactions API, and Headless Permissions",
  "keywords": "",
  "domain": "大模型算法",
  "content_type": "工程实践",
  "is_paid_flag": "否",
  "url": "https://dev.to/gde/nano-banana-2-lite-in-kiro-cli-3-mcp-20-the-new-interactions-api-and-headless-permissions-3faj",
  "publish_date": "2026-09-15",
  "corpus_stage": "",
  "notes": "",
  "id": "02371588bd4c",
  "collected_at": "2026-10-02T13:51:28",
  "title": "Nano Banana 2 Lite in Kiro CLI 3: MCP 2.0, the New Interactions API, and Headless Permissions - DEV Community",
  "body_markdown": "This article provides a step by step update guide for a Python MCP server that drives Google Nano Banana 2 Lite (\ngemini-3.1-flash-lite-image\n) 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.\nhttps://github.com/xbill9/nb2lite-kiro\nHaven't You Done This One Before?\nWhat is old is new — again.\nThe same update was written up for Claude Code, Codex and Antigravity CLI:\nNano Banana 2 Lite, Revisited: MCP 2.0, the New Interactions API, and Three Agent CLIs\nThis is the Kiro edition.\nnb2lite-kiro\ntracks\nxbill9/nb2lite\n, and\nserver.py\n,\ntest_agent.py\n,\nrequirements.txt\nand the\nMakefile\nare 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.\nBefore\nAfter\nMCP SDK\nmcp.server.fastmcp.FastMCP\nmcp.server.mcpserver.MCPServer\ngoogle-genai\nunpinned, 1.x\ngoogle-genai>=2,<3\nTools\n4\n5 — adds\nedit_local_image_with_style\nKiro server name\nnb2lite-agent\nnb2lite\nAPI key\nwritten into\nmcp.json\nand\n.env\nread from\n~/gemini.key\nat launch\nLive check\nmanual\n.kiro/skills/verify-live\nWhat is Nano Banana 2 Lite?\nNano Banana 2 Lite\nis the nickname for\nGemini 3.1 Flash-Lite Image\n, Google's low-latency image generation and editing model:\nGemini 3.1 Flash-Lite Image (Nano Banana 2 Lite) | Google Cloud Documentation\nSo What is the Secret Sauce?\nThe\nInteractions API\n. Every call is stored server-side with\nstore=True\nand returns an interaction ID. Pass that ID back as\nprevious_interaction_id\nand the model edits the image it already made, instead of redrawing a scene from a fresh prompt.\nThat keeps the MCP surface small.\ngenerate_image\nstarts a session,\nedit_image\ncontinues one, and Kiro only has to carry an ID between turns.\nWhat Broke in the Interactions API?\nThe server's code did not change. The API moved away from the SDK it was installed with.\nThis is the call\nserver.py\nmakes, run with google-genai 1.x from a scratch install:\nc\n=\ngenai\n.\nClient\n(\napi_key\n=\n...)\nc\n.\ninteractions\n.\ncreate\n(\nmodel\n=\n\"\ngemini-3.1-flash-lite-image\n\"\n,\ninput\n=\n\"\na small red cube on a white table\n\"\n,\nresponse_format\n=\n{\n\"\ntype\n\"\n:\n\"\nimage\n\"\n},\ngeneration_config\n=\n{\n\"\nthinking_level\n\"\n:\n\"\nminimal\n\"\n},\nstore\n=\nTrue\n,\n)\nEnter fullscreen mode\nExit fullscreen mode\ngoogle-genai 1.75.0\nBadRequestError: 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'}}\nEnter fullscreen mode\nExit fullscreen mode\nThe message names the fix. Inside Kiro it is easy to miss: every tool catches the exception and returns it as a\n🔴\nstring, so the agent reports \"Image generation failed\" with the version number buried in the text.\nWhat Changed in the Response?\ngoogle-genai 2.x reads the new schema, where the model's output arrives as a list of\nsteps\n. The SDK exposes the generated image as\ninteraction.output_image\n, with\ndata\nand\nmime_type\n.\nserver.py\nalready read\noutput_image\n, so upgrading the SDK was the whole fix:\nimage_output\n=\ngetattr\n(\ninteraction\n,\n\"\noutput_image\n\"\n,\nNone\n)\n...\ndata\n=\ngetattr\n(\nimage_output\n,\n\"\ndata\n\"\n,\nNone\n)\nif\nisinstance\n(\ndata\n,\nstr\n):\nimage_bytes\n=\nbase64\n.\nb64decode\n(\ndata\n)\nelse\n:\nimage_bytes\n=\ndata\nEnter fullscreen mode\nExit fullscreen mode\nThe legacy schema was removed on 2026-06-08.\n🔎 Tip: Mocked Tests Cannot See This Break\nThe unit tests mock\n_get_client\n, so the SDK never builds a real response and they pass against a broken API. One test now builds a real steps-schema\nInteraction\nwith the SDK's own model and runs it through the response handler:\ninteraction\n=\nInteraction\n.\nmodel_validate\n(\n{\n\"\nid\n\"\n:\n\"\nint_steps\n\"\n,\n\"\nstatus\n\"\n:\n\"\ncompleted\n\"\n,\n\"\nsteps\n\"\n:\n[\n{\n\"\ntype\n\"\n:\n\"\nmodel_output\n\"\n,\n\"\ncontent\n\"\n:\n[\n{\n\"\ntype\n\"\n:\n\"\nimage\n\"\n,\n\"\ndata\n\"\n:\n\"\naGVsbG8=\n\"\n,\n\"\nmime_type\n\"\n:\n\"\nimage/png\n\"\n}\n],\n}\n],\n}\n)\nresult\n=\n_handle_response\n(\ninteraction\n,\n\"\nsteps\n\"\n)\nEnter fullscreen mode\nExit fullscreen mode\nOn 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.\nWhat Changed for MCP 2.0?\nThe import and the constructor:\n-from mcp.server.fastmcp import FastMCP\n+from mcp.server.mcpserver import MCPServer\n-# Initialize FastMCP Server\n-mcp = FastMCP(\"NB2Lite Agent\")\n+# Initialize MCP Server (mcp>=2 renamed FastMCP to MCPServer)\n+mcp = MCPServer(\"NB2Lite Agent\")\nEnter fullscreen mode\nExit fullscreen mode\n@mcp.tool()\n,\nmcp.run()\nand every tool body stay as they are. The full walk-through of the 2.x changes is in the companion article:\nFastMCP Is Now MCPServer: Migrating a Python MCP Server to the MCP SDK 2.x\nlist_tools()\nis async on\nMCPServer\n.\nThe old test reached into a private attribute:\n-        tools = [t.name for t in mcp._tool_manager.list_tools()]\n+        tools = [t.name for t in asyncio.run(mcp.list_tools())]\nEnter fullscreen mode\nExit fullscreen mode\nBoth requirements now carry a floor and a ceiling, so the next major version arrives on purpose:\n-google-genai\n-mcp\n+google-genai>=2,<3\n+mcp>=2,<3\nEnter fullscreen mode\nExit fullscreen mode\nAt This Point You Should Have…\nPython 3.10 or newer, installed globally — no virtualenv\nA Gemini API key from\nGoogle AI Studio\nKiro CLI installed and logged in\nSetup the Basic Environment\ncd\n~\ngit clone https://github.com/xbill9/nb2lite-kiro\ncd\nnb2lite-kiro\nmake\ninstall\nsource\nset_env.sh\nEnter fullscreen mode\nExit fullscreen mode\nset_env.sh\nreads the key from\n~/gemini.key\n, or prompts for it and saves it there with mode\n600\n. It then rewrites the\nnb2lite\nentry in\n.kiro/settings/mcp.json\nwith this checkout's path.\npython3\n-m\npip show mcp google-genai |\ngrep\n-E\n\"^(Name|Version)\"\nkiro-cli\n--version\nEnter fullscreen mode\nExit fullscreen mode\nName: google-genai\nVersion: 2.22.0\nName: mcp\nVersion: 2.2.0\nkiro-cli 2.21.4\nEnter fullscreen mode\nExit fullscreen mode\nLint and Test\nmake lint\nEnter fullscreen mode\nExit fullscreen mode\nruff check .\nAll checks passed!\nruff format --check .\n6 files already formatted\nmypy .\nSuccess: no issues found in 2 source files\nEnter fullscreen mode\nExit fullscreen mode\nmypy\nis not in\nrequirements.txt\n. On this machine\nmake lint\nfirst failed with\nmake: mypy: No such file or directory\n, and\npython3 -m pip install mypy\nfixed it.\nmake\ntest\nEnter fullscreen mode\nExit fullscreen mode\n----------------------------------------------------------------------\nRan 12 tests in 0.412s\n\nOK\nEnter fullscreen mode\nExit fullscreen mode\nTest the Protocol by Hand\nKiro speaks JSON-RPC over stdio, so test that too. Hold stdin open with\nsleep\n, or the server sees end-of-input before it answers:\n{\nprintf\n'%s\\n'\n\\\n'{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2025-06-18\",\"capabilities\":{},\"clientInfo\":{\"name\":\"probe\",\"version\":\"0\"}}}'\n\\\n'{\"jsonrpc\":\"2.0\",\"method\":\"notifications/initialized\"}'\n\\\n'{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/list\",\"params\":{}}'\n;\nsleep\n4\n;\n}\n\\\n| python3 server.py 2>/dev/null\nEnter fullscreen mode\nExit fullscreen mode\nSummarised:\ninitialize OK: name='NB2Lite Agent' version='' proto 2025-06-18\ntools/list OK: 5 tools -> generate_image, edit_image, edit_local_image, edit_local_image_with_style, get_help\nEnter fullscreen mode\nExit fullscreen mode\n🟢 Five tools. The blank\nversion\nis what an unversioned MCP 2.x server reports.\nRegistering the Server with Kiro\nThe workspace config registers the server as\nnb2lite\n:\n{\n\"mcpServers\"\n:\n{\n\"nb2lite\"\n:\n{\n\"command\"\n:\n\"bash\"\n,\n\"args\"\n:\n[\n\"-c\"\n,\n\"GEMINI_API_KEY=$(cat ~/gemini.key) exec python3 /home/xbill/nb2lite-kiro/server.py\"\n],\n\"disabled\"\n:\nfalse\n}\n}\n}\nEnter fullscreen mode\nExit fullscreen mode\n🔎 Tip: the old setup put the key in the config.\nThe previous\ninit.sh\ninjected\nGEMINI_API_KEY\ninto the server's\nenv\nblock in\nmcp.json\nand wrote a\n.env\nfile beside it. The\nbash -c\nlaunch reads\n~/gemini.key\neach time Kiro starts the server, so the key never lands in a file inside the repository.\nkiro-cli mcp list\nkiro-cli mcp status\n--name\nnb2lite\nEnter fullscreen mode\nExit fullscreen mode\n🤖 default:\n  kiro_default\n    • aws-mcp      uvx\n    • nb2lite      bash\n\nScope   : 🤖 default\nAgent   : kiro_default\nCommand : bash\nTimeout : 120000 ms\nDisabled: false\nEnv Vars: (none)\nEnter fullscreen mode\nExit fullscreen mode\nEnv Vars: (none)\nis the point: nothing secret in the registration.\nKiro CLI 3 is Opt-In\nOn kiro-cli 2.21.4, the next generation agent is a flag:\nkiro-cli chat\n--v3\nEnter fullscreen mode\nExit fullscreen mode\nIt starts the Kiro Agent Server, which logs its own version:\n[INFO] kas.server.starting {\"product\":\"KAS (Kiro Agent Server)\",\"version\":\"0.63.3\"}\nEnter fullscreen mode\nExit fullscreen mode\nThe\nmcp.json\nabove works unchanged under v3, and skills in\n.kiro/skills/<name>/SKILL.md\nare picked up the same way.\nValidation with Kiro CLI 3: Headless is Denied\nInteractive Kiro asks before each MCP tool call. A non-interactive session has nobody to ask:\nkiro-cli chat\n--v3\n--no-interactive\n\"Call the nb2lite MCP server's get_help tool. Reply with only the first line of its output verbatim, then the names of the nb2lite tools available to you.\"\nEnter fullscreen mode\nExit fullscreen mode\n[tool] @nb2lite/get_help\n[denied] tool permission approval is not supported in non-interactive mode. Use --trust-all-tools to auto-approve.\n[tool] status: Failed\nEnter fullscreen mode\nExit fullscreen mode\nThe workspace\n.kiro/settings/cli.json\nin this repository sets\n\"trustedTools\": [\"*\"]\n. The v3 session denied the call anyway.\nThe error names one fix, and it works:\nkiro-cli chat\n--v3\n--no-interactive\n--trust-all-tools\n\"Call the nb2lite MCP server's get_help tool. ...\"\nEnter fullscreen mode\nExit fullscreen mode\n[tool] @nb2lite/get_help\n[tool] status: Completed\nFirst line: `### 🌌 NB2Lite Agent (gemini-3.1-flash-lite-image) Help & Configuration`\n\nAvailable nb2lite tools:\n- `generate_image`\n- `edit_image`\n- `edit_local_image`\n- `edit_local_image_with_style`\n- `get_help`\nEnter fullscreen mode\nExit fullscreen mode\n--trust-all-tools\ntrusts every tool, including shell. The narrower fix is a rule.\nAllow Just the Image Tools with permissions.yaml\nKiro 3 reads permission rules from\npermissions.yaml\n: globally in\n~/.kiro/settings/\n, or per workspace under\n~/.kiro/workspace-roots/<hash>/\n. Both live outside the repository, so a checkout cannot grant itself permissions.\nrules\n:\n-\ncapability\n:\nmcp\nmatch\n:\n[\n\"\nnb2lite/*\"\n]\neffect\n:\nallow\nEnter fullscreen mode\nExit fullscreen mode\nWith that file in\n~/.kiro/settings/\nand no trust flag:\nkiro-cli chat\n--v3\n--no-interactive\n\"Call the nb2lite MCP server's get_help tool. Reply with only the first line of its output verbatim.\"\nEnter fullscreen mode\nExit fullscreen mode\n[tool] @nb2lite/get_help\n[tool] status: Completed\n### 🌌 NB2Lite Agent (gemini-3.1-flash-lite-image) Help & Configuration\nEnter fullscreen mode\nExit fullscreen mode\n✅ MCP tools are addressed as\n<server>/<tool>\n. A rule accepts only\ncapability\n,\neffect\n,\nmatch\nand\nexclude\n; the parser in the shipped agent server rejects any other key as an unknown field.\nThere is A Skill for That!\nMocked tests pass while the API is broken, so the repository ships\n.kiro/skills/verify-live/SKILL.md\n. It runs the unit tests and lint, then chains all four image tools through the running MCP server at\nthinking_level=\"minimal\"\n, and opens every image it saved.\nRun headless from Kiro 3:\nkiro-cli chat\n--v3\n--no-interactive\n--trust-all-tools\n\"Run the verify-live skill exactly as written. For every nb2lite tool call, print the call and the tool's full result text verbatim, then your inspection of the image. Finish with a pass/fail table per step.\"\nEnter fullscreen mode\nExit fullscreen mode\nStep\nTool\nResult\n1\ngenerate_image\n— a red cube on a white table\n🟢 red cube, white table\n2\nedit_image\n— make the cube blue\n🟢 same composition, only the cube recoloured\n3\nedit_local_image\n— add a green sphere\n🟢 sphere added beside the cube\n4\ngenerate_image\n— watercolor sunflowers\n🟢 the style reference\n5\nedit_local_image_with_style\n— cube in the reference's style\n🟢 the cube scene as a watercolor, no sunflowers\nKiro followed the skill's ordering, calling steps 1 and 4 together and then 2, 3 and 5 together, and deleted the images once it had inspected them. Step 2 is the Interactions API test, since it proves the stored session came back.\nEnough, Already! Show me the Money!\nThe same headless Kiro 3 session style, with four calls chained by the agent:\ngenerate_image(prompt=\"a friendly pixel-art ghost banana with big eyes typing on a tiny glowing laptop, dark indigo background, crisp 16-bit style\", thinking_level=\"minimal\", aspect_ratio=\"16:9\")\n\n🟢 Image successfully saved!\n• Saved to: /home/xbill/nb2lite-kiro/gen_1789484185_cb29a061.jpg\n• Interaction ID: v1_ChdtRnlwYXBPRUtfbXUxTWtQNFB1UjRBVRIXbUZ5cGFwT0VLX211MU1rUDRQdVI0QVU\nEnter fullscreen mode\nExit fullscreen mode\nContinue the stored session with the interaction ID:\nedit_image(previous_interaction_id=\"v1_ChdtRnlwYXBPRUtfbXUxTWtQNFB1UjRBVRIXbUZ5cGFwT0VLX211MU1rUDRQdVI0QVU\", edit_prompt=\"give the banana a small wizard hat and make the laptop screen show green terminal text\", thinking_level=\"minimal\")\n\n🟢 Image successfully saved!\n• Saved to: /home/xbill/nb2lite-kiro/edit_1789484197_dd06d5b0.jpg\n• Interaction ID: v1_ChdtRnlwYXBPRUtfbXUxTWtQNFB1UjRBVRIXcEZ5cGFxNmREOUNhOU1vUHR1REpvQUk\nEnter fullscreen mode\nExit fullscreen mode\nThe window, the shelves, the lantern and the pose all carried over. Only the hat and the screen changed.\nThe new tool takes a style from a second image. First, a reference:\ngenerate_image(prompt=\"a Bauhaus poster, flat geometric shapes, primary colors, heavy black lines, off-white paper\", thinking_level=\"minimal\", aspect_ratio=\"16:9\")\n\n🟢 Image successfully saved!\n• Saved to: /home/xbill/nb2lite-kiro/gen_1789484204_75f1e1e0.jpg\nEnter fullscreen mode\nExit fullscreen mode\nThe model added poster lettering on its own — an exhibition, a venue and dates. All of it is invented.\nThen the original banana, in that style:\nedit_local_image_with_style(image_path=\"/home/xbill/nb2lite-kiro/gen_1789484185_cb29a061.jpg\", style_image_path=\"/home/xbill/nb2lite-kiro/gen_1789484204_75f1e1e0.jpg\", edit_prompt=\"keep the banana, its eyes and the laptop\", thinking_level=\"minimal\", aspect_ratio=\"16:9\")\n\n🟢 Image successfully saved!\n• Saved to: /home/xbill/nb2lite-kiro/style_edit_1789484214_51da1f65.jpg\nEnter fullscreen mode\nExit fullscreen mode\nThe banana, the laptop and the room props came through. The poster's shapes and paper did too; its lettering did not.\n🔎 About That Cover\nThe cover of this article was generated by the server this article describes, headless from Kiro 3. One\ngenerate_image\ncall at\nthinking_level=\"high\"\n, because the cover carries lettering:\ngenerate_image(prompt=\"A wide tech blog cover illustration, all important content kept inside a central horizontal band ... Large crisp title text in the center band: 'Nano Banana 2 Lite in Kiro CLI 3'. Smaller subtitle beneath it: 'MCP 2.0 + the new Interactions API'. Accurate, typo-free lettering.\", aspect_ratio=\"16:9\", thinking_level=\"high\")\n\n🟢 Image successfully saved!\n• Saved to: /home/xbill/nb2lite-kiro/gen_1789484250_dd316079.jpg\n• Interaction ID: v1_ChcyVnlwYXBpUEVhalZqckVQdTRLeGlBTRIXMlZ5cGFwaVBFYWpWanJFUHU0S3hpQU0\nEnter fullscreen mode\nExit fullscreen mode\nThe subtitle came out exact. The title lost a word — \"Nano Banana 2 Lite Kiro CLI 3\" — and a line on the tiny terminal screen read\nKire CLI\n. That is the stateful edit loop's job, so the fix was an\nedit_image\non the same interaction:\nedit_image(previous_interaction_id=\"v1_ChcyVnlwYXBpUEVhalZqckVQdTRLeGlBTRIXMlZ5cGFwaVBFYWpWanJFUHU0S3hpQU0\", edit_prompt=\"Fix only the lettering. The title must read exactly 'Nano Banana 2 Lite in Kiro CLI 3', and any on-screen text reading 'Kire' must read 'Kiro'. Keep everything else exactly the same.\", thinking_level=\"high\")\nEnter fullscreen mode\nExit fullscreen mode\nThat put \"in\" back and dropped \"Lite\". A second edit, naming each line of the title separately, got the title exact:\nedit_image(previous_interaction_id=\"v1_ChcyVnlwYXBpUEVhalZqckVQdTRLeGlBTRIXQ0YycGF1bUxNdGFZak1jUHlaQ3prUW8\", edit_prompt=\"Fix only two pieces of lettering. The two-line title must read 'Nano Banana 2 Lite' on the first line and 'in Kiro CLI 3' on the second line. On the computer screen, the bottom line 'Kire CLI' must read 'Kiro CLI'. Keep everything else exactly the same.\", thinking_level=\"high\")\n\n🟢 Image successfully saved!\n• Saved to: /home/xbill/nb2lite-kiro/edit_1789484421_431dff69.jpg\nEnter fullscreen mode\nExit fullscreen mode\nThe characters, frames and composition held through both edits. The screen line did not:\nKire CLI\nis still there, in the bottom line of the terminal. On this cover, the headline took two edits and the few-pixel screen text never came right. No retouching, beyond cropping the 16:9 output to the box dev.to displays.\nCheat Sheet\n# pins\n#   google-genai>=2,<3   (1.x: 400 \"legacy Interactions API schema is no longer supported\")\n#   mcp>=2,<3            (FastMCP -> MCPServer)\nmake\ninstall\n&&\nmake lint\n&&\nmake\ntest\n# lint needs mypy installed\nsource\nset_env.sh\n# key from ~/gemini.key, path into .kiro/settings/mcp.json\n# check the registration\nkiro-cli mcp list\n&&\nkiro-cli mcp status\n--name\nnb2lite\n# Kiro 3\nkiro-cli chat\n--v3\n# headless: either trust everything...\nkiro-cli chat\n--v3\n--no-interactive\n--trust-all-tools\n\"Run the verify-live skill\"\n# ...or allow only nb2lite, in ~/.kiro/settings/permissions.yaml\n# rules:\n#   - capability: mcp\n#     match: [\"nb2lite/*\"]\n#     effect: allow\nEnter fullscreen mode\nExit fullscreen mode\nSummary\nThe goal of this article was to bring the Kiro edition of the Nano Banana 2 Lite MCP server back to a working state on current dependencies, and to run it from Kiro CLI 3. The key to the solution was reading the error messages, which named every fix, and then proving the live API path from a headless Kiro session instead of trusting mocked tests. The update results were:\n❌ google-genai 1.x gets HTTP 400 from the Interactions API; the fix was\ngoogle-genai>=2,<3\n, with no change to\nserver.py\n🟢 The MCP 2.0 port was the import and the constructor; all five tools register unchanged\n🟢 The API key moved out of\nmcp.json\n; the server reads\n~/gemini.key\nat launch\n⚠️ Kiro 3 denies MCP calls in\n--no-interactive\nmode, even with\ntrustedTools\nset in the workspace\ncli.json\n🟢\n--trust-all-tools\nor a\npermissions.yaml\nrule for\nnb2lite/*\nboth unblock it, and\nverify-live\npassed all five steps\nScope: one Debian 13 workstation, Python 3.14.7, mcp 2.2.0 and google-genai 2.22.0, with google-genai 1.75.0 as the failing reference from the upstream repository's run on the identical\nserver.py\n. kiro-cli 2.21.4 with\n--v3\n(KAS 0.63.3), every Kiro run headless with\n--no-interactive\n; the interactive approval prompt was not exercised. Every demo image call ran once at\nthinking_level=\"minimal\"\nagainst\ngemini-3.1-flash-lite-image\n; nothing here measures latency or cost.\nThe strategy for using MCP with Nano Banana 2 Lite in Kiro CLI 3 was validated with an incremental step by step approach.\nReferences\nnb2lite-kiro | GitHub\nnb2lite | GitHub\nNano Banana 2 Lite, Revisited: MCP 2.0, the New Interactions API, and Three Agent CLIs\nInteractions API breaking changes | Gemini API\nInteractions API | Gemini API\nMigration Guide: v1 to v2 | MCP Python SDK\nFastMCP Is Now MCPServer: Migrating a Python MCP Server to the MCP SDK 2.x\nmcp 2.2.0, google-genai 2.22.0, Python 3.14.7, ruff 0.16.7, mypy 2.3.1, kiro-cli 2.21.4 (KAS 0.63.3),\ngemini-3.1-flash-lite-image\n.",
  "metadata": {
    "title": "Nano Banana 2 Lite in Kiro CLI 3: MCP 2.0, the New Interactions API, and Headless Permissions - DEV Community",
    "description": "The Kiro edition of the Nano Banana 2 Lite MCP server, updated: FastMCP is now MCPServer, google-genai 1.x gets a 400 from the Interactions API, and Kiro CLI 3 needs a permissions rule before it will call the tools headless. Tagged with kiro, mcp, gemini, python.",
    "keywords": "kiro, mcp, gemini, python, software, coding, development, engineering, inclusive, community",
    "author": null,
    "og:type": "article",
    "og:url": "https://dev.to/gde/nano-banana-2-lite-in-kiro-cli-3-mcp-20-the-new-interactions-api-and-headless-permissions-3faj",
    "og:title": "Nano Banana 2 Lite in Kiro CLI 3: MCP 2.0, the New Interactions API, and Headless Permissions",
    "og:description": "The Kiro edition of the Nano Banana 2 Lite MCP server, updated: FastMCP is now MCPServer, google-genai 1.x gets a 400 from the Interactions API, and Kiro CLI 3 needs a permissions rule before it will call the tools headless.",
    "og:site_name": "DEV Community",
    "og:image": "https://media2.dev.to/dynamic/image/width=1200,height=627,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fxbill9%2Fnb2lite-kiro%2Fmain%2Fdocs%2Fdevto-cover.1bc9f155.jpg",
    "twitter:site": "@thepracticaldev",
    "twitter:creator": "@",
    "twitter:title": "Nano Banana 2 Lite in Kiro CLI 3: MCP 2.0, the New Interactions API, and Headless Permissions",
    "twitter:description": "The Kiro edition of the Nano Banana 2 Lite MCP server, updated: FastMCP is now MCPServer, google-genai 1.x gets a 400 from the Interactions API, and Kiro CLI 3 needs a permissions rule before it will call the tools headless.",
    "twitter:card": "summary_large_image",
    "twitter:widgets:new-embed-design": "on",
    "twitter:image:src": "https://media2.dev.to/dynamic/image/width=1200,height=627,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fxbill9%2Fnb2lite-kiro%2Fmain%2Fdocs%2Fdevto-cover.1bc9f155.jpg"
  },
  "paywall": {
    "listed_paid": false,
    "detected": false,
    "marker": "",
    "public_only": false,
    "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
  },
  "crawl": {
    "success": true,
    "status_code": 200,
    "error": ""
  },
  "code_blocks": [
    {
      "file": "attachments/02371588bd4c/code/body-000.txt",
      "chars": 251,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-001.txt",
      "chars": 418,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-002.txt",
      "chars": 201,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-003.txt",
      "chars": 392,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-004.txt",
      "chars": 243,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-005.txt",
      "chars": 131,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-006.txt",
      "chars": 50,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-007.txt",
      "chars": 101,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-008.txt",
      "chars": 84,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-009.txt",
      "chars": 76,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-010.txt",
      "chars": 10,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-011.txt",
      "chars": 130,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-012.txt",
      "chars": 10,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-013.txt",
      "chars": 98,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-014.txt",
      "chars": 347,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-015.txt",
      "chars": 174,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-016.txt",
      "chars": 230,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-017.txt",
      "chars": 53,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-018.txt",
      "chars": 185,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-019.txt",
      "chars": 19,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-020.txt",
      "chars": 84,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-021.txt",
      "chars": 192,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-022.txt",
      "chars": 162,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-023.txt",
      "chars": 105,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-024.txt",
      "chars": 261,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-025.txt",
      "chars": 70,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-026.txt",
      "chars": 138,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-027.txt",
      "chars": 121,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-028.txt",
      "chars": 263,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-029.txt",
      "chars": 379,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-030.txt",
      "chars": 421,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-031.txt",
      "chars": 258,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-032.txt",
      "chars": 372,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-033.txt",
      "chars": 530,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-034.txt",
      "chars": 330,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-035.txt",
      "chars": 496,
      "language": "text"
    },
    {
      "file": "attachments/02371588bd4c/code/body-036.txt",
      "chars": 697,
      "language": "text"
    }
  ],
  "images": [
    {
      "status": "ok",
      "url": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9jquryt7itkucjmuukmu.jpg",
      "bytes": 95278,
      "reused": true,
      "local_path": "attachments/02371588bd4c/images/003.jpg",
      "src": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9jquryt7itkucjmuukmu.jpg",
      "alt": "A glowing pixel-art ghost banana typing on a small laptop in a dark indigo room with a moonlit window and shelves",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fml07r7tky2xccoi31hgj.jpg",
      "bytes": 102808,
      "reused": true,
      "local_path": "attachments/02371588bd4c/images/004.jpg",
      "src": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fml07r7tky2xccoi31hgj.jpg",
      "alt": "The same ghost banana in the same room and pose, now wearing a starry wizard hat, with green terminal text on the laptop",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff6gjmnsf5heilj7t1264.jpg",
      "bytes": 168934,
      "reused": true,
      "local_path": "attachments/02371588bd4c/images/005.jpg",
      "src": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff6gjmnsf5heilj7t1264.jpg",
      "alt": "A generated Bauhaus-style poster with a black circle, diagonal black bars, a red square and yellow triangles on off-white paper",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhuf96s9vrwnbbiye438d.jpg",
      "bytes": 145674,
      "reused": true,
      "local_path": "attachments/02371588bd4c/images/006.jpg",
      "src": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhuf96s9vrwnbbiye438d.jpg",
      "alt": "The ghost banana at its laptop redrawn as a flat illustration with black outlines on cream paper, over the poster's black circle and diagonals",
      "downloaded": true
    }
  ],
  "audio": [],
  "videos": [],
  "links": [
    {
      "href": "https://github.com/xbill9/nb2lite-kiro",
      "label": "https://github.com/xbill9/nb2lite-kiro",
      "type": "a"
    },
    {
      "href": "https://dev.to/gde/nano-banana-2-lite-revisited-mcp-20-the-new-interactions-api-and-three-agent-clis-37g5",
      "label": "Nano Banana 2 Lite, Revisited: MCP 2.0, the New Interactions API, and Three Agent CLIs",
      "type": "a"
    },
    {
      "href": "https://github.com/xbill9/nb2lite",
      "label": "xbill9/nb2lite",
      "type": "a"
    },
    {
      "href": "https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/gemini/3-1-flash-lite-image",
      "label": "Gemini 3.1 Flash-Lite Image (Nano Banana 2 Lite) | Google Cloud Documentation",
      "type": "a"
    },
    {
      "href": "https://dev.to/gde/fastmcp-is-now-mcpserver-migrating-a-python-mcp-server-to-the-mcp-sdk-2x-2nhj",
      "label": "FastMCP Is Now MCPServer: Migrating a Python MCP Server to the MCP SDK 2.x",
      "type": "a"
    },
    {
      "href": "https://aistudio.google.com/apikey",
      "label": "Google AI Studio",
      "type": "a"
    },
    {
      "href": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9jquryt7itkucjmuukmu.jpg",
      "label": "",
      "type": "a"
    },
    {
      "href": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fml07r7tky2xccoi31hgj.jpg",
      "label": "",
      "type": "a"
    },
    {
      "href": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff6gjmnsf5heilj7t1264.jpg",
      "label": "",
      "type": "a"
    },
    {
      "href": "https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhuf96s9vrwnbbiye438d.jpg",
      "label": "",
      "type": "a"
    },
    {
      "href": "https://ai.google.dev/gemini-api/docs/interactions-breaking-changes-may-2026",
      "label": "Interactions API breaking changes | Gemini API",
      "type": "a"
    },
    {
      "href": "https://ai.google.dev/gemini-api/docs/interactions-overview",
      "label": "Interactions API | Gemini API",
      "type": "a"
    },
    {
      "href": "https://py.sdk.modelcontextprotocol.io/v2/migration/",
      "label": "Migration Guide: v1 to v2 | MCP Python SDK",
      "type": "a"
    }
  ],
  "repair_version": 2,
  "repaired_at": "2026-10-14T10:48:30Z",
  "source_url": "https://dev.to/gde/nano-banana-2-lite-in-kiro-cli-3-mcp-20-the-new-interactions-api-and-headless-permissions-3faj",
  "papers": [],
  "actual_video_files": [],
  "body_chars": 20016,
  "expected_body_images": 4,
  "discovery_status": "ok",
  "delivery_status": "ok",
  "missing_reason": "",
  "raw_html": "attachments/02371588bd4c/pages/source.html",
  "local_html": "attachments/02371588bd4c/pages/article.html",
  "body_base_path": "attachments/02371588bd4c/pages/",
  "body_markdown_path": "attachments/02371588bd4c/pages/article.md"
}