Skip to content
Blog

A2UI with Google ADK: Serving Generative UI from a Python Agent

How Google's Agent Development Kit renders A2UI natively, and how an ADK agent ends up driving a Flutter GenUI client.

Published on • October 20, 2026

AI Assistant

A2UI is an open protocol for agents to exchange user interfaces, not just text, with clients. On the Flutter side, the GenUI SDK uses A2UI as its underlying wire protocol. On the server side, one of the most complete implementations lives inside Google’s Agent Development Kit (ADK). This post covers what the A2UI ecosystem page documents about the ADK integration and how the pieces fit together.

What A2UI actually standardizes

An A2UI message instructs a client to perform actions like createSurface, surface updates, data-model updates, or deleteSurface. Components are described declaratively with data bindings, and a catalog constrains which widgets a client knows how to render. Because the protocol is declarative and client-agnostic, one agent can drive a Flutter app, a web frontend, and a dev UI without per-platform rendering code.

That’s exactly the pitch Flutter’s team made for it. Vijay Menon, Engineering Director for Dart & Flutter, is quoted on the ecosystem page: “A2UI was a great fit for Flutter’s GenUI SDK because it ensures that every user, on every platform, gets a high quality native feeling experience.”

ADK’s native A2UI support

Per the ecosystem page, ADK integrated the A2UI v0.8 basic catalog so that spec-compliant agent parts render as native UI components directly in ADK Web, the built-in developer UI. Three capabilities matter for production work:

  • Built-in rendering — ADK Web renders A2UI components natively in chat, so you can iterate on agent output without building a client first.
  • A2A integration — ADK handles A2UI↔A2A message conversion, translating between A2A DataPart metadata and ADK events. Agents built with ADK can send rich UI to any A2UI-capable client over the Agent-to-Agent protocol.
  • Agent SDK — the A2UI Python agent SDK ships an ADK extension for generating A2UI from agents.

ADK itself is Google’s open-source framework for building and deploying agents, available in Python, TypeScript, Go, Java, and Kotlin (the adk.dev homepage lists all five). A minimal agent is a few lines:

from google.adk import Agent
from google.adk.tools import google_search

agent = Agent(
    name="researcher",
    model="gemini-flash-latest",
    instruction="You help users research topics thoroughly.",
    tools=[google_search],
)

Installable with pip install google-adk, with the source on google/adk-python. ADK 2.0 adds graph workflows for deterministic orchestration alongside LLM reasoning.

The architecture: agent in Python, surface in Flutter

The flow looks like this:

  1. Your Flutter app’s Conversation.sendRequest() triggers onSend.
  2. Your onSend implementation calls the ADK agent — directly over its runtime API, or through an A2A endpoint.
  3. The agent (using the A2UI agent SDK extension) emits A2UI messages describing surfaces, components, and data bindings.
  4. Messages arrive at your Flutter client as a text stream, get parsed by A2uiTransportAdapter/A2uiParserTransformer, and the SurfaceController applies them.
  5. Surface widgets render from your catalog; user interaction flows back as a new message and the loop continues.

On the Flutter side the setup is the standard GenUI wiring — a SurfaceController with your catalogs, an A2uiTransportAdapter, and a Conversation:

final controller = SurfaceController(
  catalogs: [CoreCatalogItems.asCatalog()],
);
final transport = A2uiTransportAdapter(
  onSend: (message) async {
    // Call your ADK-backed endpoint and pipe the A2UI stream back.
    await for (final chunk in client.streamAgent(message)) {
      transport.addChunk(chunk);
    }
  },
);
final conversation = Conversation(controller: controller, transport: transport);

The important separation: the catalog on the client is the contract. The agent can only ask for widgets your catalog declares, so versioning your catalog alongside your app build is what keeps server-driven UI safe — the agent can never render something your shipped app can’t.

Where to start

The A2UI project maintains a restaurant-finder sample built on ADK (samples/agent/adk/restaurant_finder) — table reservation with dynamic forms, powered by Gemini, full source available — plus an agent development guide and a client setup guide. On the Flutter side, the Verdure example in flutter/genui is the client-server A2UI sample, and docs.flutter.dev/ai/genui covers the SDK.

One caveat from the ecosystem page worth knowing before you architect around it: in Gemini Enterprise, A2UI rendering currently requires self-serve agents registered via the A2A path (a2aAgentDefinition); managed agents on Vertex AI Agent Engine using adkAgentDefinition don’t support A2UI rendering yet. If you’re targeting enterprise deployment, that constraint shapes your registration path from day one.

Sources