std/ui reference
std/ui is the typed application layer over MCP Apps.
It exports std/ui/contracts, std/ui/renderer, and std/ui/testing.
Import the module as a namespace. This keeps each call short without putting generic names into the file's top-level scope:
import * as ui from "std/ui"
const next = ui.update(ui.document("Decision Card", revision, elements))
Documents
ui.document(title, revision, elements) -> UiDocument checks an ordered list
of elements. A child names an earlier row or column through parent.
Supported element kinds are column, row, heading, text, button,
text_area, field, select, status, canvas, image, and divider.
variant selects a shared presentation role such as workspace, work,
panel, toolbar, canvas-area, primary, or grow. Set a heading's
level from 1 to 6; the default is 2.
Canvas strokes use coordinates from 0.0 to 1.0:
const stroke: UiStroke = {
id: "stroke-1",
points: [{x: 0.1, y: 0.2}, {x: 0.4, y: 0.5}],
color: "#486449",
width: 7.0,
}
Canvas width and height are each limited to 8,192 pixels. Each stroke contains
2–4,096 finite points, and one document may contain at most 65,536 stroke
points. ui.document applies these checks to reopened work before a browser
allocates the canvas.
Events
ui.event(raw) -> UiEvent accepts ready, click, input, canvas.stroke,
and canvas.snapshot. Strokes contain 2–4,096 points. Each coordinate must be
between 0.0 and 1.0.
Updates and effects
ui.update(document, effects?) -> UiUpdate is the event handler's return value.
| Effect | Purpose |
|---|---|
send_event | Send a typed event now or after after_ms |
capture_canvas | Capture one canvas as PNG and send a canvas.snapshot event |
download | Ask the browser to download base64 bytes |
Use a scheduled send_event with
model_job_step_result to show
progress and cancellation without a blocking polling loop.
Renderer resource
ui.renderer_html(tool_name) -> string returns the shared renderer.
ui.app_resource(uri, name, tool_name, options?) -> UiResource validates it
and packages it for harness.tools.mcp_resource.
ui.tool_metadata(resource, options?) returns the MCP tool metadata that opens
the app. ui.mcp_resource(resource, options?) returns the config accepted by
harness.tools.mcp_resource.
The renderer contains browser implementation code because the browser owns DOM and canvas APIs. Applications do not copy or modify that code. Their behavior remains Harn.
Event handler tests
ui.test.run(handle, events, options?) -> UiTestTrace drives a Harn event
handler in process. By default it follows send_event effects immediately and
ignores their delay. A polling or recovery flow therefore completes without
waiting for real time. Set max_steps to turn a repeating event loop into an
exact failure.
ui.test.element(document, id) finds a rendered element, and
ui.test.effect_count(trace, kind) counts effects across the trace. Canvas
rasterization remains a browser responsibility; pass a canvas.snapshot
fixture when testing the Harn behavior that consumes it.