Live Editing & the MCP Authoring Loop

Beyond running layouts, CAR-TER supports authoring them live: push a layout to a paired device, see it render instantly, read back what's on screen, and iterate. Two front-ends drive the same mechanism — the web editor (editor/) and the MCP server (carter-mcp), which lets an LLM build and push layouts. This is distinct from a data server (Anatomy of a CAR-TER Server); it's about editing the UI.

How a live-edit session works

  1. The editor connects to a relay and shows a pairing QR (Connection & Pairing).
  2. The phone scans it and starts a live-edit session (role viewer/editor), rendering an editor-pushed layout and re-rendering on every push.
  3. The editor pushes layouts and reads device state over MeshSocket.

During a live-edit session the device arms read-back responders so the editor isn't flying blind. They are routed-request handlers (answered via route_msg):

Verb Returns
get-current-layout The layout currently live (summary or full JSON)
get-control-state Current control values ({ id: value })
get-connection-status Connected?/phase/channel/role/which events it's listening on
apply-layout Applies a pushed layout and echoes exactly what rendered (or an error)
list-layouts / save-layout List/persist layout files on the device

The apply-layout echo is the important one: a push reports back the structure the device actually rendered (a control dropped on decode won't appear), so the editor never assumes a blind "success."

The MCP server (carter-mcp)

carter-mcp exposes these as tools an LLM (e.g. Claude) can call:

  • Docs: list_controls, get_control_doc, get_layout_schema, list_sample_layouts, get_sample_layout.
  • Pairing: connect, show_qr, wait_for_device, disconnect.
  • Authoring: push_layout (truthful apply-layout echo), save_device_layout, list_device_layouts.
  • Read-back: get_device_layout, get_control_state, get_connection_status.

Hassle-free transport

connect() defaults to target="local": it spins up an in-process, auth-free MeshSocket relay on your machine and builds the QR with your LAN IP — no gateway, no token, no cloud. Put the phone on the same Wi-Fi and scan. For remote authoring, connect(target="relay") uses the Connect+ gateway and auto-mints a token from the dev validator, so you still don't hand-paste credentials.

A typical loop

connect()                         # zero-config local relay + QR
show_qr()                         # (or scan the QR connect() returned)
wait_for_device()                 # polls the roster until the phone joins
push_layout(<json>)               # device renders it; returns the structural echo
get_device_layout(full=true)      # confirm what's live
get_control_state()               # read values off the device
save_device_layout(<json>)        # persist it on the device
disconnect()

Roster note: wait_for_device polls get_nodes rather than waiting on the membership push, because the relay's identify-time roster broadcast can miss a peer that joins after the editor — see Message Reference.

When to use which front-end

  • Web editor (editor/) — visual, drag-and-drop authoring; good for humans.
  • MCP (carter-mcp) — programmatic/LLM authoring; good for "describe the dashboard and watch it appear," and for scripted layout generation.

Both speak the same protocol and produce the same layout JSON — so a layout authored either way runs against any data server you build.