streamboard
Generative-UI MCP

AI writes the dashboard. You push the data.

A versioned spec at a permanent URL — your code keeps the values live, no LLM in the loop.

No. 02  /  See it

An LLM authors. A streamboard renders. You theme it, version it, share it.

No. 03  /  The split

Authoring is paid in LLM tokens. Refreshing is paid in HTTP.

Author · once

An AI agent drafts the structure.

In your MCP client of choice, ask the model to build the dashboard. It calls create_streamboard with a json-render spec (components, layout, named slots), and you get back a permanent URL.

cost: one LLM call · paid in tokens to your model provider
Runtime · forever

Your code pushes the live values.

From a cron, a Worker, an agent loop, or a CI step: POST a state envelope to the data API. The viewer hydrates the spec's slots on every render. No model in the loop.

cost: one HTTP call per refresh · zero LLM tokens

The contract

The spec leaves named slots for live values. The model chooses which slots when it authors; your push fills them at runtime. Update the data, the dashboard updates. Update the spec, you get a new version.

No. 04  /  A real example, end-to-end

From an MCP prompt to a live URL, in three calls.

  1. 01

    Ask the LLM

    In Claude Code, Cursor, or any MCP client.

    # prompt
    > Build me an MRR dashboard — mrr, new signups,
    > a 14-day trend line, and a recent-orders table.
  2. 02

    The model authors the spec

    It calls create_streamboard with a json-render spec. Named $bind slots mark where live values land.

    {
      "kpis": {
        "mrr":     { "value": { $bind: "mrr" } },
        "signups": { "value": { $bind: "signups" } }
      },
      "trend":  { "series": { $bind: "trend" } },
      "orders": { "rows":   { $bind: "orders" } }
    }

    returns a permanent URL: usestreamboard.com/s/abc1f0

  3. 03

    Your code pushes the values

    From a cron, a Worker, or a CI step — anywhere your data already lives. No model in the loop.

    // every 5 minutes — cron, Worker, or CI step
    await board.push({
      kpis:   { mrr: { value: "$48.2k", delta: "+4%" } },
      trend:  { points: lastFourteenDays },
      orders: { rows: recentOrders },
    })
No. 05  /  Versioning, plainly

Two URLs per streamboard. One follows. One stays.

/s/abc1f0

The follow link

Always serves the latest version. Drop this in a Slack pin, a README, a Notion page. When the LLM publishes a new revision, the URL automatically advances. Recipients always see the current spec + the freshest push.

/s/abc1f0/2.1.0

The pinned link

Serves that exact version, forever. Append a semver to freeze a snapshot. Useful for incident reports, audit trails, "what did this look like last quarter". The frozen spec is immutable. Live data still hydrates.

Every spec edit appends a row to (id, version), so no URL you've shared ever breaks. Roll back by sharing the old version. Push-time data envelopes are last-write-wins and apply to whatever version is currently being served.

What about chat canvases?

Cursor canvases, ChatGPT artifacts, Claude canvases — they ship now as shareable URLs. None of them let your service push new values in after the chat ends.

Streamboards do. The spec leaves { $bind: "…" } slots; your cron, Worker, or CI step POSTs the state envelope; the page rehydrates on every load. No model in the loop after authoring.

No. 06  /  For your stack

MCP, CLI, TypeScript, Python. Pick your edge.

A · The MCP server

One command wires the hosted server into any MCP-aware client. The LLM gets create_streamboard, update_streamboard, and friends as tools.

claude mcp add streamboard --transport http \
  https://mcp.usestreamboard.com/mcp

B · The CLI

When MCP isn't an option: CI scripts, a quick push from a terminal, codegen for typed clients. Same auth as the web app.

npm i -g streamboard
streamboard login
streamboard streamboards ls
echo '{"kpis":{"mrr":{"value":"$48k"}}}' \
  | streamboard streamboards push abc1f0

C · The TypeScript SDK

Zero dependencies. Runs everywhere JavaScript runs — Node, Bun, Deno, Cloudflare Workers, the browser.

import { Streamboard } from "@streamboard/sdk"

const board = new Streamboard({
  token: process.env.STREAMBOARD_TOKEN!,
})

await board.push({ kpis: { mrr: { value: "$48.2k" } } })
const snap = await board.pull()  // read it back

D · The Python SDK

Same surface as the TS SDK. Sync client. Useful when the data lives in a Jupyter notebook, a Django cron, or an Airflow DAG.

from streamboard import Streamboard

board = Streamboard(token=os.environ["STREAMBOARD_TOKEN"])
board.push({"kpis": {"mrr": {"value": "$48.2k"} } })
No. 07  /  Beta

Free during beta. Pricing lands after validation.

Streamboard is in open beta. Sign up and use the full Pro feature set — comments, alarms, branding, team invites, everything — at no cost while we collect feedback.

Paid plans launch once we know what's worth paying for. We'll give every beta account a heads-up before that happens — no surprise charges, no auto-conversion to a paid plan you didn't choose.

Sign up — free during beta →