Agent-First UI v0.1.0: Describe the Interface, Don't Ship It
The first release of Agent-First UI — a protocol where a tool describes its interface as data instead of shipping UI code. A trusted host you own renders the screens and actions, redacts secrets, and gates risky operations, so nothing the tool sends can run on your machine. v0.1.0 ships the wire protocol, a JSON schema, conformance fixtures, and a lightweight Rust SDK.
A command-line tool can print text. The moment it needs to show something richer — a sortable table, a form, a button that does something — the usual answer is to ship a user interface: a web page, a bundle of components, a desktop view. That interface is code, and it runs on your machine.
So you end up trusting the tool with more than the task. Its interface can read a file, call the network, or render a button that says one thing and quietly does something else. The interface belongs to the tool, not to you — and an agent driving that tool can’t tell what a control really does, because the meaning is buried in UI code instead of stated in the open.
Agent-First UI v0.1.0 splits those two halves apart.
The tool describes; your host renders
A producer — any tool — describes a surface as plain data: screens, views like tables and forms, and the actions available on them, each with a stated risk. A trusted host that you own reads that data and decides how to draw it, what to allow, and what to hide. When you act, the host sends a structured event back; the tool replies with more data, never code.
The document is JSON, and that is the whole safety story. An AFUI surface may not
carry JavaScript, CSS, HTML, WASM, build scripts, shell commands, callbacks, or
remote URLs — there is nothing in it to execute. An action like restart is a
declaration with a risk of destructive, not a function. The host shows it as
destructive and gates it behind your confirmation before anything happens.
Safety lives in the data
Because the surface is data, the things that matter for safety are fields a host
can act on, not prose it has to interpret. Actions declare their risk. Secrets
are suffixed _secret, so a conforming host redacts them by default. Locators
are suffixed _uri, so the host — not the producer — decides whether and how to
open them. Required inputs are declared, so the host collects them before an
action can fire. (Those suffix conventions come straight from Agent-First Data.)
The host owns all of it: rendering, redaction, risk gates, binding resolution, and applying updates. A producer can’t reach past the data to change what the host allows. And because ids stay stable across runs, the host can keep your focus, your local state, and an audit trail.
What v0.1.0 ships
This first release is the protocol itself:
- The wire format —
ui_snapshot,state/document/themepatches, anduser_actionevents — with a normative specification and a JSON schema. - Conformance fixtures — worked operation surfaces, not a widget checklist.
- A lightweight Rust SDK,
agent-first-ui, with the wire types, validation, binding resolution, JSON-Patch helpers, and action assembly. It carries no rendering code, so a tool can depend on it without pulling in a host, a browser, or a terminal.
cargo add agent-first-ui
A tool adopts it by emitting a complete snapshot first, then handling
user_action events. The protocol never asks a producer to know how it will be
drawn — only to describe, honestly, what it has and what can be done with it. How
it looks, and what’s allowed, stays with the host. The interface is yours.