Vercel UI SDK

When an agent drives an interface built with Vercel's UI SDK, the controls you mark wait for a named person to decide in Deliverd.

UI SDK (@ui-sdk/*) is Vercel's component library for React, Vue, Svelte, Solid and web components. Its agent bridge, createAgent, lets an AI agent read your page and press buttons or fill fields, directly or through WebMCP in the browser. You mark the controls an agent must not use alone with data-agent-confirm, and the bridge asks its allow hook before it touches them. Deliverd answers that hook with a real person.

How it works

  1. The agent tries a control marked data-agent-confirm. UI SDK calls allow and waits.
  2. deliverdAllow sends the step to your own server route. The browser never holds your agent key.
  3. Your route, uiSdkApprovalRoute, asks Deliverd. The approver reads the mark's sentence, the control and the values, from the email, Slack or Teams.
  4. A yes lets the step run. A no, a wait that runs out or a route that fails all leave the control untouched, and UI SDK tells the agent the person said no.

Set it up

  1. 1

    Install the SDK

    Run npm install @deliverd/sdk and set DELIVERD_API_KEY on the server to an agent key (Agents → your agent → Keys). Use an agent key, not a personal one, so the person who started the agent can still approve.

  2. 2

    Mark what needs a person

    Put data-agent-confirm on each control an agent must not use alone, with a sentence written for the approver. For a confirm dialog, mark the button that confirms, not the trigger.

  3. 3

    Add the route

    Add a POST route that calls uiSdkApprovalRoute. It works as a Next.js route handler and in anything else that takes a fetch-style Request.

  4. 4

    Connect the bridge

    Pass deliverdAllow as allow when you create the bridge, in client code only. If you also register WebMCP tools, pass allow: () => true to registerTools, so the person is asked once, not twice.

The mark

<AlertDialogClose
  value="confirm"
  data-agent-confirm="Deletes the project and all its files"
>
  Delete forever
</AlertDialogClose>

The route

// app/api/deliverd/ui-approval/route.ts
import { Deliverd } from "@deliverd/sdk";
import { uiSdkApprovalRoute } from "@deliverd/sdk/adapters";

export const maxDuration = 800;

export const POST = uiSdkApprovalRoute({
  deliverd: new Deliverd(), // reads DELIVERD_API_KEY
  approvers: ["ops"],
  timeout: "13m",
});

The bridge

"use client";
import { createAgent } from "@ui-sdk/react/agent";
import { deliverdAllow } from "@deliverd/sdk/adapters";

export const agent = createAgent({
  allow: deliverdAllow({ endpoint: "/api/deliverd/ui-approval" }),
  // UI SDK gives up after 5 minutes unless you raise this.
  timeout: 15 * 60_000,
});

Timing

Three clocks have to agree: the route's timeout (four minutes by default), your platform's function limit (maxDuration on Vercel) and the bridge's own timeout (five minutes by default). Keep the route's the shortest, so it can answer no before it is cut off. The request expires when the route stops waiting, so nobody approves a step the agent has given up on, and each ask is its own request, so an approval never carries over to a later step.

Options

OptionWhereWhat it does
endpointdeliverdAllowYour route's address.
whenbothWhich steps go to a person. Default: steps on a data-agent-confirm mark. Change it in both places, since the route refuses any step outside its own when.
headersdeliverdAllowExtra headers for your route, such as a CSRF token.
onAnswerdeliverdAllowTold each answer, so the page can show a person's reason for a no.
approversuiSdkApprovalRouteWho decides: people, teams or groups. Your organisation's admins when omitted.
describeuiSdkApprovalRouteWhat the approver reads. Built from the mark's sentence and the step when omitted.
timeout, expiresInuiSdkApprovalRouteHow long to wait, and how long the request stays open. Both four minutes by default.
flowId, metadatauiSdkApprovalRoutePut each ask on a flow's timeline, or tag it for your own records.

More on the SDK itself is in SDKs.

Try it on your own agent.

Free to start, no card. Sign up with Google, Microsoft or GitHub, and the first page after hands you an API key.