Serving data

The MCP server

perch-mcp — the tools Claude Code uses to publish widgets and drive the display.

perch-mcp is a Model Context Protocol server bundled inside the Mac app. The app registers it with Claude Code on first launch, so you can manage widgets in plain language. It talks to the hub’s admin surface over localhost only, with a write-scoped token — never the LAN.

Tools

ToolWhat it does
pair_statusIs an iPhone paired, and currently connected? Returns { paired, connected, deviceName? }.
publish_widgetCreate a widget from HTML and show it. Returns { id }.
update_widgetReplace a widget’s HTML (and optionally its icon).
set_widget_iconSet/replace a widget’s icon without re-sending HTML.
list_widgetsList widgets + which is active.
set_active_widgetChoose which widget shows fullscreen.
delete_widgetRemove a widget.
list_versionsA widget’s code history (newest first).
revert_widgetRe-apply an earlier version’s HTML as a new version.
push_dataSet the live JSON feed for a widget (details).
get_data_endpointGet a URL + token to POST data from a script (details).
register_actionMake a widget interactive (DEBUG builds only — see Actions).

Publishing

publish_widget takes the full HTML document and an optional poll interval and icon, and returns the new widget’s id:

// publish_widget
{
  "name": "Temperature",
  "html": "<!doctype html>…",
  "refreshMs": 1500,
  "icon": { "kind": "sfSymbol", "value": "thermometer" }
}
// → { "id": "wgt_abc123" }
  • name (required) — shown in the phone’s switcher and the Mac list.
  • html (required) — the complete self-contained document.
  • refreshMs (optional) — native poll interval; defaults to 1500 ms.
  • icon (optional) — see Manifest & icons.

Then point the phone at it:

// set_active_widget
{ "id": "wgt_abc123" }

Iterating safely

Every publish_widget and update_widget appends to a bounded, forward-only version history. Inspect it with list_versions and roll back with revert_widget (which re-applies that snapshot as a new current version):

// list_versions → { "versions": [ { "version": 3, "htmlHash": "…", "updatedAt": …, "note"? }, … ] }
// revert_widget
{ "id": "wgt_abc123", "version": 2 }

A note on scope

perch-mcp only reaches the hub on 127.0.0.1 with a role-3 write token. It can manage widgets and push data, but the LAN-facing display surface (what the phone talks to) is a separate, session-token-gated API.