{
  "source_file": "0930",
  "source_platform": "Dev.to",
  "author": "xbill",
  "title_listed": "Nano Banana 2 Lite, Revisited: MCP 2.0, the New Interactions API, and Three Agent CLIs",
  "keywords": "",
  "domain": "大模型算法",
  "content_type": "工程实践",
  "is_paid_flag": "否",
  "url": "https://dev.to/gde/nano-banana-2-lite-revisited-mcp-20-the-new-interactions-api-and-three-agent-clis-37g5",
  "publish_date": "2026-09-13",
  "corpus_stage": "",
  "notes": "",
  "id": "0650e8ceb5d9",
  "collected_at": "2026-10-02T13:51:31",
  "title": "Nano Banana 2 Lite, Revisited: MCP 2.0, the New Interactions API, and Three Agent CLIs - 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. Two dependency lines moved underneath it since it was first published: the MCP Python SDK went to 2.x, and the Interactions API dropped the schema that google-genai 1.x speaks. The same server is then registered with Claude Code, Codex and Antigravity CLI, and validated end to end against the live API.\nhttps://github.com/xbill9/nb2lite\nHaven't You Done This One Before?\nWhat is old is new — again.\nThe original article set up this server with Claude Code in July:\nNano Banana 2 Lite with Claude Code\nThe code in that article no longer runs on a fresh install. Nothing in the repository was broken;\nrequirements.txt\nlisted\nmcp\nand\ngoogle-genai\nwith no version bounds, and both resolved to a new major version.\nJuly (original article)\nSeptember (this article)\nMCP SDK\nfrom mcp.server.fastmcp import FastMCP\nfrom mcp.server.mcpserver import MCPServer\ngoogle-genai\nunpinned, 1.x\ngoogle-genai>=2,<3\nInteractions response\nlegacy schema\nsteps\n, read via\noutput_image\nTools\n4\n5 — adds\nedit_local_image_with_style\nClients\nClaude Code, via\n.mcp.json\nClaude Code plugin, Codex, Antigravity CLI\nLive check\nmanual\na\nverify-live\nskill\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. The launch details are in the original article and here:\nGemini 3.1 Flash-Lite Image (Nano Banana 2 Lite) | Google Cloud Documentation\nSo What is the Secret Sauce?\nThe\nInteractions API\nis still the secret sauce. 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 is what makes a small MCP surface useful.\ngenerate_image\nstarts a session,\nedit_image\ncontinues one, and the agent only has to carry an ID.\nWhat Broke in the Interactions API?\nThe server's code did not change. The SDK underneath it did not change either — the API moved away from it.\nHere is the exact call\nserver.py\nmakes, run with google-genai 1.x from a scratch\npip install --target\ndirectory, so the global Python keeps 2.x:\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\nLike the MCP 2.x import error, this message deserves credit: it names the fix and links the migration notes. Inside an MCP server it is less visible. Each tool catches the exception and returns it as a\n🔴\nstring, so the agent reports \"Image generation failed\" and the version number is buried in the text.\nWhat Changed in the Response?\ngoogle-genai 2.x reads the new response schema, where the model's output arrives as a list of\nsteps\n. The SDK exposes the generated image as a convenience property,\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. No tool function changed:\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\nIf your own code walks the legacy output fields by hand, that is the part the migration notes linked from the error cover.\n🔎 Tip: Mocked Tests Cannot See This Break\nThe unit tests passed the whole time the server was broken. They mock\n_get_client\n, so the SDK never builds a real response and the API is never called.\nThe fix was one test that 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 covered by a live check, later in this article.\nWhat Changed for MCP 2.0?\nThe MCP port was the smaller of the two. The whole code change:\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()\nand\nmcp.run()\nstay as they are, and so does every tool body. The full walk-through of the 2.x changes, with the exposure greps, is in the companion article:\nFastMCP Is Now MCPServer: Migrating a Python MCP Server to the MCP SDK 2.x\nTwo 2.x details showed up in this repository.\nlist_tools()\nis async on\nMCPServer\n.\nThe old test reached into a private attribute. The new one uses the public API:\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\nThe server version went blank.\nAn unversioned 2.x server reports an empty string in the handshake, which shows up in the protocol test below.\nPin Both Major Versions\nBoth breaks came from unbounded requirements, so both lines now carry a floor and a ceiling:\n-google-genai\n-mcp\n+google-genai>=2,<3\n+mcp>=2,<3\nEnter fullscreen mode\nExit fullscreen mode\nThe floor documents what the code needs. The ceiling means the next major version arrives on purpose rather than through\npip install\n.\nAt This Point You Should Have…\nPython 3.10 or newer, and no virtualenv — these projects install into one system Python\nA Gemini API key from\nGoogle AI Studio\nAt least one of Claude Code, Codex or Antigravity CLI installed\nSetup the Basic Environment\nClone the repository and install into the Python the agent will launch:\ncd\n~\ngit clone https://github.com/xbill9/nb2lite\ncd\nnb2lite\nmake\ninstall\nEnter fullscreen mode\nExit fullscreen mode\nThen run\nset_env.sh\n. It reads the key from\n~/gemini.key\n, or prompts for it and saves it there, and exports\nGEMINI_API_KEY\n:\nsource\nset_env.sh\nEnter fullscreen mode\nExit fullscreen mode\nCheck what is installed:\npython3\n-m\npip show mcp google-genai |\ngrep\n-E\n\"^(Name|Version)\"\nEnter fullscreen mode\nExit fullscreen mode\nName: mcp\nVersion: 2.2.0\nName: google-genai\nVersion: 2.22.0\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 .\n8 files already formatted\nmypy .\nSuccess: no issues found in 2 source files\nEnter fullscreen mode\nExit fullscreen mode\nmake\ntest\nEnter fullscreen mode\nExit fullscreen mode\n----------------------------------------------------------------------\nRan 12 tests in 0.305s\n\nOK\nEnter fullscreen mode\nExit fullscreen mode\nTest the Protocol by Hand\nUnit tests call Python. A client 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\nThe responses are JSON; summarised:\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, and\nversion=''\n— the blank version from MCP 2.x.\nValidation with Claude Code\nThe July article registered the server with a project\n.mcp.json\n. The repository is now also a Claude Code plugin marketplace, which bundles the server and the\nverify-live\nskill:\nclaude plugin marketplace add xbill9/nb2lite\nclaude plugin\ninstall\nnb2lite@nb2lite\nEnter fullscreen mode\nExit fullscreen mode\nThe API key goes in the plugin's configuration under\n/plugin\n. Left blank, the server falls back to\nGEMINI_API_KEY\nfrom the environment Claude Code started in.\n🔎 Tip: a plugin\nenv\nvalue wins even when it is empty.\nMapping the plugin's key setting straight to\nGEMINI_API_KEY\nwould blank a key the user had already exported. The plugin sets its own variable,\nNB2LITE_GEMINI_API_KEY\n, and the server checks that first, then\nGEMINI_API_KEY\n, then\nGOOGLE_API_KEY\n.\nManual registration still works, and reads the key at launch so it never lands in a config file:\nclaude mcp add\n--scope\nuser nb2lite\n--\nbash\n-c\n'GEMINI_API_KEY=$(cat ~/gemini.key) exec python3 /path/to/nb2lite/server.py'\nEnter fullscreen mode\nExit fullscreen mode\nAfter changing\nserver.py\nor upgrading a dependency, reconnect the server from\n/mcp\n.\nValidation with Codex\nSame command, Codex syntax:\ncodex mcp add nb2lite\n--\nbash\n-c\n'GEMINI_API_KEY=$(cat ~/gemini.key) exec python3 /path/to/nb2lite/server.py'\nEnter fullscreen mode\nExit fullscreen mode\nInteractive Codex asks before each MCP tool call. Non-interactive\ncodex exec\nhas nobody to ask, so the call fails:\nmcp: nb2lite/get_help started\nmcp: nb2lite/get_help (failed)\nMCP tool call requires approval, but approval policy is never\nEnter fullscreen mode\nExit fullscreen mode\nThe fix is a per-server setting in\n~/.codex/config.toml\n:\n[mcp_servers.nb2lite]\ncommand\n=\n\"bash\"\nargs\n=\n[\n\"-c\"\n,\n\"GEMINI_API_KEY\n=\n$(cat\n~/gemini.key)\nexec\npython\n3\n/path/to/nb\n2\nlite/server.py\n\"]\ndefault_tools_approval_mode\n=\n\"approve\"\nEnter fullscreen mode\nExit fullscreen mode\nmcp: nb2lite/get_help (completed)\n### 🌌 NB2Lite Agent (gemini-3.1-flash-lite-image) Help & Configuration\nEnter fullscreen mode\nExit fullscreen mode\nInside the repository, Codex also picked up\nAGENTS.md\nand the\nverify-live\nskill from\n.agents/skills/\n. ✅\nValidation with Antigravity CLI\nagy mcp add nb2lite\n--\nbash\n-c\n'GEMINI_API_KEY=$(cat ~/gemini.key) exec python3 /path/to/nb2lite/server.py'\nagy mcp list\nEnter fullscreen mode\nExit fullscreen mode\nAdded MCP server \"nb2lite\" (stdio)\nNAME     TYPE   STATUS   COMMAND/URL\nnb2lite  stdio  enabled  bash -c GEMINI_API_KEY=$(cat ~/gemini.key) exec python3 /home/xbill/nb2lite/server.py\nEnter fullscreen mode\nExit fullscreen mode\nPrint mode called the tools with no extra approval setting. Attach the prompt to the flag and put other flags first — a bare\n-p\nfollowed by another flag takes that flag as the prompt:\nagy\n--print-timeout\n3m\n-p\n=\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### 🌌 NB2Lite Agent (gemini-3.1-flash-lite-image) Help & Configuration\n\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🔎 Tip: agy did not find the repository's skills.\nCodex read\n.agents/skills/\n; agy's CLI did not, even for a real directory rather than a symlink. It does read the global skills folder, and a symlink there works:\nmkdir\n-p\n~/.gemini/config/skills\nln\n-s\n/path/to/nb2lite/skills/verify-live ~/.gemini/config/skills/verify-live\nEnter fullscreen mode\nExit fullscreen mode\nThere is A Skill for That!\nMocked tests pass while the API is broken, so the repository ships a skill that checks the path users actually hit.\nverify-live\nruns the unit tests, then chains all four image tools through the running MCP server at\nthinking_level=\"minimal\"\n, and opens every image it saved.\nThe skill is written once and exposed to each client: through the plugin for Claude Code,\n.agents/skills/\nfor Codex, and the global link for agy.\nThe run from Claude Code:\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\nStep 2 is the Interactions API test, since it proves the stored session came back. Step 5 is the new tool. The style reference must look nothing like the cube photo, or a transfer cannot be told apart from a copy.\nEnough, Already! Show me the Money!\nClaude Code was started for a hands-on session with the migrated server:\ngenerate_image(prompt=\"pixel-art ghost banana character with big friendly eyes, floating, dark indigo background, crisp 16-bit style\", aspect_ratio=\"16:9\", thinking_level=\"minimal\")\n\n🟢 Image successfully saved!\n• Saved to: /home/xbill/nb2lite/gen_1789322371_4fc516ed.jpg\n• Interaction ID: v1_ChdndVNtYXN6ZkRQcmRqTWNQbXV5QjJBZxIXZ3VTbWFzemZEUHJkak1jUG11eUIyQWc\nEnter fullscreen mode\nExit fullscreen mode\nNot a fan of plain bananas? Continue the stored session with the interaction ID:\nedit_image(previous_interaction_id=\"v1_ChdndVNtYXN6ZkRQcmRqTWNQbXV5QjJBZxIXZ3VTbWFzemZEUHJkak1jUG11eUIyQWc\", edit_prompt=\"make the ghost banana steampunk: brass gears, rivets and goggle eyes\", thinking_level=\"minimal\")\n\n🟢 Image successfully saved!\n• Saved to: /home/xbill/nb2lite/edit_1789322402_e466080a.jpg\n• Interaction ID: v1_ChdndVNtYXN6ZkRQcmRqTWNQbXV5QjJBZxIXb2VTbWFxaVhEcUt3MU1rUGt1Zmh3UXM\nEnter fullscreen mode\nExit fullscreen mode\nThe pose, the glow, the stars and the constellation lines all carried over. Only the banana changed.\nNot a fan of steampunk? The new tool takes a style from a second image. First, a reference:\ngenerate_image(prompt=\"a traditional Japanese ukiyo-e woodblock print of a great wave, flat colors, bold outlines, visible paper grain\", aspect_ratio=\"16:9\", thinking_level=\"minimal\")\n\n🟢 Image successfully saved!\n• Saved to: /home/xbill/nb2lite/gen_1789322407_8dc09a3f.jpg\nEnter fullscreen mode\nExit fullscreen mode\nThen the original banana, in that style:\nedit_local_image_with_style(image_path=\"gen_1789322371_4fc516ed.jpg\", style_image_path=\"gen_1789322407_8dc09a3f.jpg\", edit_prompt=\"keep the banana character and its big eyes\", aspect_ratio=\"16:9\", thinking_level=\"minimal\")\n\n🟢 Image successfully saved!\n• Saved to: /home/xbill/nb2lite/style_edit_1789322423_7efbadf5.jpg\nEnter fullscreen mode\nExit fullscreen mode\n🔎 About That Cover\nThe cover of this article was generated by the server this article describes, from the same Claude Code session. 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, Revisited'. 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/gen_1789323099_2380472d.jpg\n• Interaction ID: v1_ChdXdWVtYXNMTkw5aW5fUFVQOXUtRHFRURIXV3VlbWFzTE5MOWluX1BVUDl1LURxUVE\nEnter fullscreen mode\nExit fullscreen mode\nThe title and subtitle came out exact. The middle frame did not: it was labelled\nSTEAMBOAT\n. That is the stateful edit loop's job, so the fix was one more call on the same interaction rather than a new prompt:\nedit_image(previous_interaction_id=\"v1_ChdXdWVtYXNMTkw5aW5fUFVQOXUtRHFRURIXV3VlbWFzTE5MOWluX1BVUDl1LURxUVE\", edit_prompt=\"Change only the label under the middle frame from 'STEAMBOAT' to 'STEAMPUNK'. Keep everything else exactly the same.\", thinking_level=\"high\")\n\n🟢 Image successfully saved!\n• Saved to: /home/xbill/nb2lite/edit_1789323124_176d08c8.jpg\n• Interaction ID: v1_ChdXdWVtYXNMTkw5aW5fUFVQOXUtRHFRURIXYy1lbWF1MzBDLXViX3VNUC1QdUh5UTg\nEnter fullscreen mode\nExit fullscreen mode\nOnly the label changed. The prompt kept everything important in a central band, so cropping the 16:9 output to the box dev.to displays removed nothing but background. No retouching.\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# stdio smoke test: hold stdin open\n{\nprintf\n'%s\\n'\n'{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2025-06-18\",\"capabilities\":{},\"clientInfo\":{\"name\":\"p\",\"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| python3 server.py 2>/dev/null\n# register\nclaude plugin marketplace add xbill9/nb2lite\n&&\nclaude plugin\ninstall\nnb2lite@nb2lite\ncodex mcp add nb2lite\n--\nbash\n-c\n'GEMINI_API_KEY=$(cat ~/gemini.key) exec python3 /path/to/nb2lite/server.py'\nagy mcp add nb2lite\n--\nbash\n-c\n'GEMINI_API_KEY=$(cat ~/gemini.key) exec python3 /path/to/nb2lite/server.py'\n# codex exec: [mcp_servers.nb2lite] default_tools_approval_mode = \"approve\"\n# agy skills: ln -s /path/to/nb2lite/skills/verify-live ~/.gemini/config/skills/verify-live\nEnter fullscreen mode\nExit fullscreen mode\nSummary\nThe goal of this article was to bring the Nano Banana 2 Lite MCP server from July back to a working state on current dependencies, and to run it from more than one agent CLI. The key to the solution was reading the two error messages, which named both fixes, and then proving the live API path instead of trusting mocked tests. The update results were:\n❌ google-genai 1.x now 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⚠️ Mocked unit tests passed throughout the break; a steps-schema test and the\nverify-live\nskill now cover it\n🟢 One server, one launch command: Claude Code, Codex and Antigravity CLI all called the tools\n⚠️\ncodex exec\nneeds\ndefault_tools_approval_mode = \"approve\"\n, and agy needs the skill linked globally\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 from a scratch install as the failing reference. Claude Code 2.1.270 and Codex 0.153.4; agy was 1.1.27 for the tool tests and had updated itself to 1.2.2 by the time versions were recorded. Every 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 across Claude Code, Codex and Antigravity CLI was validated with an incremental step by step approach.\nReferences\nnb2lite | GitHub\nNano Banana 2 Lite with Claude Code\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 (mcp-types 2.2.0), google-genai 2.22.0, Python 3.14.7, ruff 0.16.7, mypy 2.3.1, Claude Code 2.1.270, Codex 0.153.4, Antigravity CLI 1.1.27 / 1.2.2,\ngemini-3.1-flash-lite-image\n.",
  "metadata": {
    "title": "Nano Banana 2 Lite, Revisited: MCP 2.0, the New Interactions API, and Three Agent CLIs - DEV Community",
    "description": "The Nano Banana 2 Lite MCP server from July, updated: FastMCP is now MCPServer, google-genai 1.x gets a 400 from the Interactions API, and one server now runs in Claude Code, Codex and Antigravity CLI. Tagged with mcp, python, gemini, claudecode.",
    "keywords": "mcp, python, gemini, claudecode, software, coding, development, engineering, inclusive, community",
    "author": null,
    "og:type": "article",
    "og:url": "https://dev.to/gde/nano-banana-2-lite-revisited-mcp-20-the-new-interactions-api-and-three-agent-clis-37g5",
    "og:title": "Nano Banana 2 Lite, Revisited: MCP 2.0, the New Interactions API, and Three Agent CLIs",
    "og:description": "The Nano Banana 2 Lite MCP server from July, updated: FastMCP is now MCPServer, google-genai 1.x gets a 400 from the Interactions API, and one server now runs in Claude Code, Codex and Antigravity CLI.",
    "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%2Fmain%2Fdocs%2Fdevto-cover.57272bb7.jpg",
    "twitter:site": "@thepracticaldev",
    "twitter:creator": "@",
    "twitter:title": "Nano Banana 2 Lite, Revisited: MCP 2.0, the New Interactions API, and Three Agent CLIs",
    "twitter:description": "The Nano Banana 2 Lite MCP server from July, updated: FastMCP is now MCPServer, google-genai 1.x gets a 400 from the Interactions API, and one server now runs in Claude Code, Codex and Antigravity CLI.",
    "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%2Fmain%2Fdocs%2Fdevto-cover.57272bb7.jpg"
  },
  "paywall": {
    "listed_paid": false,
    "detected": false,
    "marker": "",
    "public_only": false,
    "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
  },
  "crawl": {
    "success": true,
    "status_code": 200,
    "error": ""
  },
  "code_blocks": [
    {
      "file": "attachments/0650e8ceb5d9/code/body-000.txt",
      "chars": 251,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-001.txt",
      "chars": 418,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-002.txt",
      "chars": 201,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-003.txt",
      "chars": 392,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-004.txt",
      "chars": 243,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-005.txt",
      "chars": 131,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-006.txt",
      "chars": 50,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-007.txt",
      "chars": 73,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-008.txt",
      "chars": 18,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-009.txt",
      "chars": 65,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-010.txt",
      "chars": 60,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-011.txt",
      "chars": 10,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-012.txt",
      "chars": 130,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-013.txt",
      "chars": 10,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-014.txt",
      "chars": 98,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-015.txt",
      "chars": 347,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-016.txt",
      "chars": 174,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-017.txt",
      "chars": 83,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-018.txt",
      "chars": 124,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-019.txt",
      "chars": 110,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-020.txt",
      "chars": 123,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-021.txt",
      "chars": 171,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-022.txt",
      "chars": 105,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-023.txt",
      "chars": 121,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-024.txt",
      "chars": 183,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-025.txt",
      "chars": 182,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-026.txt",
      "chars": 172,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-027.txt",
      "chars": 111,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-028.txt",
      "chars": 360,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-029.txt",
      "chars": 398,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-030.txt",
      "chars": 273,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-031.txt",
      "chars": 319,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-032.txt",
      "chars": 522,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-033.txt",
      "chars": 443,
      "language": "text"
    },
    {
      "file": "attachments/0650e8ceb5d9/code/body-034.txt",
      "chars": 1071,
      "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%2F6gvtqpwlzc3norzmnx1i.jpg",
      "bytes": 55736,
      "reused": true,
      "local_path": "attachments/0650e8ceb5d9/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%2F6gvtqpwlzc3norzmnx1i.jpg",
      "alt": "A pixel-art ghost banana with big eyes floating on a starry indigo background",
      "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%2Fqvops7a4gf57zrl67o1c.jpg",
      "bytes": 76296,
      "reused": true,
      "local_path": "attachments/0650e8ceb5d9/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%2Fqvops7a4gf57zrl67o1c.jpg",
      "alt": "The same ghost banana, now with brass gears, rivets and goggles, in the same pose and background",
      "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%2F0l7jbifjo1e41hlimlda.jpg",
      "bytes": 340538,
      "reused": true,
      "local_path": "attachments/0650e8ceb5d9/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%2F0l7jbifjo1e41hlimlda.jpg",
      "alt": "A ukiyo-e style woodblock print of a great wave with boats and a distant mountain",
      "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%2Fel0enk4n3ww5lpd4qspx.jpg",
      "bytes": 338956,
      "reused": true,
      "local_path": "attachments/0650e8ceb5d9/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%2Fel0enk4n3ww5lpd4qspx.jpg",
      "alt": "The ghost banana character rendered as a woodblock print",
      "downloaded": true
    }
  ],
  "audio": [],
  "videos": [],
  "links": [
    {
      "href": "https://github.com/xbill9/nb2lite",
      "label": "https://github.com/xbill9/nb2lite",
      "type": "a"
    },
    {
      "href": "https://dev.to/gde/nano-banana-2-lite-with-claude-code-4n6l",
      "label": "Nano Banana 2 Lite with Claude Code",
      "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%2F6gvtqpwlzc3norzmnx1i.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%2Fqvops7a4gf57zrl67o1c.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%2F0l7jbifjo1e41hlimlda.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%2Fel0enk4n3ww5lpd4qspx.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:31Z",
  "source_url": "https://dev.to/gde/nano-banana-2-lite-revisited-mcp-20-the-new-interactions-api-and-three-agent-clis-37g5",
  "papers": [],
  "actual_video_files": [],
  "body_chars": 19912,
  "expected_body_images": 4,
  "discovery_status": "ok",
  "delivery_status": "ok",
  "missing_reason": "",
  "raw_html": "attachments/0650e8ceb5d9/pages/source.html",
  "local_html": "attachments/0650e8ceb5d9/pages/article.html",
  "body_base_path": "attachments/0650e8ceb5d9/pages/",
  "body_markdown_path": "attachments/0650e8ceb5d9/pages/article.md"
}