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. The MCP server (carter-mcp) drives this loop, letting an LLM build and push layouts; you can also author programmatically with carterkit and push over the same mechanism. 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 authoring client (the MCP) 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 a pushed layout and re-rendering on every push.
  3. The client pushes layouts and reads device state over MeshSocket.

During a live-edit session the device arms read-back responders so the client 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 client 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 authoring client — see Message Reference.

Two ways to author

  • MCP (carter-mcp) — LLM authoring: "describe the dashboard and watch it appear," with live push + read-back. Best for conversational, exploratory design.
  • carterkit — programmatic authoring in Python (Layout, typed build.<control>, bind, validate) plus a CLI. Best for scripted, repeatable layout generation and CI.

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