Skip to content

A2UI (Agent-to-User Interface): Google's Open Protocol for Agents to Ship UI as Data

May 23, 2026 1 min
TL;DR A2UI is an agent generative UI protocol open-sourced by Google on 2025-12-15: agents send declarative JSON describing UI intent, and clients render it natively using their own component catalog whitelist, layered on top of A2A. It launched at format v0.8 and iterated to v0.9 within three months.

🌏 中文版

When an AI agent encounters a structured task like “book me a table,” plain-text chat degenerates into tedious back-and-forth Q&A. A better experience is for the agent to directly generate a form with a date picker, a time dropdown, and a submit button. The problem is: in the era of multi-agent collaboration, the agent actually doing the work is often remote, cross-organization, and has no access to your DOM — so how does it safely deliver an “interface” to your frontend? That is exactly what Google set out to solve with A2UI (Agent-to-User Interface), open-sourced on 2025-12-15. This post breaks down its design philosophy, message format, and how it relates to MCP Apps, AG-UI, and ChatKit.

The Problem A2UI Solves: “UI Can’t Cross the Wire” in a Multi-Agent Mesh

A2UI’s starting point is not “making AI draw prettier screens” but rather UI transport across trust boundaries. According to the Google Developers Blog, we are entering the era of the “multi-agent mesh” — Google’s agents talk to agents from Cisco, IBM, SAP, and Salesforce, which is why the A2A (Agent-to-Agent) protocol was created and donated to the Linux Foundation.

But decentralization introduces a UI problem: if the agent lives inside your app, it can directly manipulate the view layer (e.g., the DOM); but in a multi-agent world, the agent doing the work often runs on another server, belongs to another organization — “it can’t touch your UI, it can only send messages.”

Historically, rendering UI from a remote, untrusted source meant sending HTML/JavaScript and isolating it in an iframe sandbox. Google calls out the cost of that approach: “heavy, visually inconsistent with your app’s native styling, and introduces security boundary complexity.” A2UI aims for something different — a transport format that is “safe like data, but expressive like code.”

Core Design: Treat UI as Data, Not Code

A2UI’s entire design boils down to one sentence: what the agent sends is declarative JSON describing “which components, how to arrange them, and what data to bind” — not executable code. Three key decisions revolve around this:

  • Security first (catalog whitelist): Running arbitrary code generated by an LLM is high-risk, so A2UI is a declarative data format. The client maintains a “catalog” — a set of trusted, pre-approved components (Card, Button, TextField…), and the agent can only “request rendering of components that are in the catalog.” In Google’s own words, this “help[s] you to reduce the risk of UI injection and other vulnerabilities.”
  • Structure and implementation are decoupled: A2UI only describes a component tree plus a data model; “how it looks” is up to the client. The same JSON payload can render on Lit, Angular, Flutter, and (in the future) React or SwiftUI, automatically inheriting the host app’s brand styling and accessibility features.
  • LLM-friendly, incrementally updatable: The UI is represented as “a flat list of components with ID references,” making it easy for LLMs to progressively render; as the conversation continues, the agent only sends partial updates instead of redrawing the whole thing.

The trade-off is stated plainly: A2UI “gives the client more control, at the expense of the agent” — in other words, the agent gives up pixel-level arbitrary style control in exchange for cross-platform consistency and security.

How Messages Flow

A2UI is transport-agnostic — any mechanism that can send JSON works. It currently supports A2A and AG-UI as transport layers, with REST / WebSocket / SSE planned. The protocol has four main message types (per a2ui.org Core Concepts and Google Developer Advocate Mete Atamel’s writeup):

  • createSurface: Create a surface and specify which catalog it uses
  • updateComponents: Add or update components within a surface
  • updateDataModel: Update application state
  • deleteSurface: Remove a surface

Using a restaurant booking as an example, the agent first creates a surface, then defines the UI structure, and finally populates data:

{
  "version": "v0.9",
  "updateComponents": {
    "surfaceId": "booking",
    "components": [
      { "id": "root", "component": "Column",
        "children": ["header", "guests-field", "submit-btn"] },
      { "id": "header", "component": "Text",
        "text": "Confirm Reservation", "variant": "h1" },
      { "id": "guests-field", "component": "TextField",
        "label": "Guests", "value": { "path": "/reservation/guests" } },
      { "id": "submit-btn", "component": "Button", "variant": "primary",
        "action": { "event": { "name": "confirm",
          "context": { "details": { "path": "/reservation" } } } } }
    ]
  }
}

The user changes guests to 3 and hits Confirm; the client sends an action event with context back to the agent. The agent then decides whether to update the UI or deleteSurface to dismiss it. Throughout this loop, UI structure and data are transmitted separately — which is the key to enabling incremental updates.

A2UI vs MCP Apps vs AG-UI vs ChatKit

In the second half of 2025, “how should agents render UI” saw multiple competing standards emerge simultaneously. Google devoted an entire section of their announcement to mapping the landscape. Here are the highlights:

vs MCP Apps (MCP-UI + OpenAI merger): MCP (Model Context Protocol) introduced MCP Apps in 2025-11, merging MCP-UI with OpenAI’s efforts. Its model is “UI as a resource” — a tool returns a ui:// URI, and the client fetches a pre-built HTML bundle and drops it into a sandbox iframe for isolation. A2UI takes a native-first approach: it sends blueprints of native components rather than opaque HTML payloads, so the UI perfectly inherits the host’s styling and accessibility. In multi-agent scenarios, an orchestrator agent can “read” the lightweight A2UI message from a sub-agent and modify it. In one sentence: MCP Apps fetches pre-built UI as a resource to display in isolation; A2UI transmits UI intent as data and lets you render it.

vs AG-UI (confusingly similar name, different and complementary role): These two are the easiest to mix up. Per Mete Atamel’s breakdown — AG-UI connects “your frontend app to an agentic backend” (handling state sync, chat history, input — the “plumbing”); A2UI is “the declarative format for UI widgets within an agent’s response.” The two stack together: AG-UI serves as transport and scaffolding, A2UI serves as the data format. CopilotKit / AG-UI founder Atai Barkai confirmed they achieved day-0 compatibility: “AG-UI fully supports the A2UI spec… We’re excited to provide day-0 compatibility between AG-UI and A2UI.”

vs OpenAI ChatKit: ChatKit is a highly integrated, optimized deployment experience within the OpenAI ecosystem. A2UI’s positioning targets building custom agentic surfaces “across Web / Flutter / native mobile,” as well as enterprise A2A mesh scenarios that cross trust boundaries.

When to Use A2UI

Good fit:

  1. Multi-agent / cross-organization mesh — you need remote agents you don’t fully trust to render inside your app.
  2. One agent, consistent multi-platform UI — Web, mobile, and desktop sharing a single UI declaration.
  3. Enterprise workflow agents — form filling, approval dashboards, guided workflows. This is exactly the scenario Gemini Enterprise highlights with its A2UI integration; Flutter’s GenUI SDK already uses A2UI under the hood as the server-to-app UI declaration format.

Not necessary (for now):

  • Your agent lives in a single frontend you control, same trust domain — using generative UI directly (e.g., Vercel AI SDK) is simpler.
  • You’re deeply tied to the OpenAI ecosystem — ChatKit is a smoother path.
  • You need highly customized, pixel-level visual control — the catalog whitelist model will feel restrictive.

Limitations and Unsettled Areas

A2UI is worth tracking, but as of H1 2026 it remains an early-stage public preview (Apache 2.0 license). Before putting it into production, accept a few realities:

  • The format is still moving: It launched at format v0.8, and the team explicitly said “expect changes”; by the official DevRel articles in 2026-03, examples already use v0.9. One minor version bump every three months — not a slow cadence.
  • Documentation examples don’t quite match the actual wire format: The simplified docs use message names like createSurface / updateComponents, but ADK sample logs in the same article show beginRendering / surfaceUpdate, with components nested as {"Column": {...}}. In other words, wire-level details aren’t fully settled — don’t treat any single field name as authoritative; refer to a2ui.org/specification as the source of truth.
  • The age-old skepticism about “cross-platform UI languages”: A2UI garnered 164 points and 75 comments on Hacker News. One commenter (codethief) pushed back directly: “An agent can suddenly do what developers have failed to do for decades — platform-agnostic UI? Works for simple cases, but anything more complex is questionable.” Another (rockwotj) cut to the essence: “It’s really just server-side rendering, except you let an LLM write the markup language.”
  • Catalog does not equal immunity: The whitelist reduces risk, but security comes from “a capability-limited component catalog” itself, not from “using JSON instead of HTML.” If the protocol were to allow arbitrary behavior/styling, injection issues would persist.
  • Standards fragmentation: MCP-UI, ChatKit widgets, and A2UI all tackling the same problem simultaneously. Hacker News inevitably had “yet another variant, wasted effort” complaints. Who will win is undetermined; one comment from the thread rings true: “The winner won’t be the one with the flashiest demo, but the one boring enough that product teams are willing to use it for 5–10 years.”

Overall Architecture

[ Remote A2A subagent ] ─┐
                         │   A2UI JSON
                         │   (createSurface / updateComponents /
                         │    updateDataModel / deleteSurface)
[ orchestrator agent ] ──┼──► transport: A2A or AG-UI ──► [ Client app ]
                         │                                     │
   Sends only            │                                     ├─ catalog whitelist (Card/Button/TextField…)
   "UI intent", ────────┘                                     ├─ native framework render (Lit / Angular / Flutter)
   not executable code                                        └─ user action → action event sent back to agent

Placed in the larger protocol map: MCP handles “agent to tools/resources,” A2A handles “agent to agent,” AG-UI handles “frontend to agentic backend,” and A2UI fills the “agent to user interface” gap.

Bottom Line

A2UI is betting on the “UI as data” approach: using a constrained declarative format plus a client-side catalog whitelist to achieve cross-framework portability, cross-trust-boundary security, and lightweight messages that orchestrators can read — at the cost of agents losing pixel-level freedom and being bound to the premise that “the client has implemented the corresponding components.” If you’re building enterprise-grade, multi-agent, multi-platform agentic products, it’s well worth experimenting with now (CopilotKit has the A2UI Composer, Flutter has the GenUI SDK to play with). But if your agent lives in a single frontend you control, existing generative UI solutions are still simpler. Remember — it’s still a preview, and the spec will change.

References