Every widget has a manifest — the metadata the hub stores alongside its HTML. You don’t write it directly; the hub builds it when you publish. But knowing the fields helps when you list widgets or debug versioning.
Manifest fields
| Field | Type | Meaning |
|---|---|---|
id | string | Stable widget id (returned by publish_widget). |
name | string | Human-readable name (switcher + Mac list). |
refreshMs | int | Native poll interval for this widget’s feed. |
htmlHash | string | SHA-256 (hex) of the HTML, for integrity. |
version | int | Bumped on every update so the phone knows to refetch. |
publishedAt | double? | First-published time (Unix seconds). Optional. |
icon | WidgetIcon? | Switcher / Mac list / Lock Screen icon. Optional. |
builtInSlug | string? | If installed from a shipped template, its stable slug (e.g. "soundbar"). nil for custom widgets. |
builtInVersion | int? | The built-in template version it was installed from. |
templateHash | string? | SHA-256 of the pristine shipped template it last installed (built-ins only). htmlHash != templateHash means the widget was customized since; the Mac offers an update whenever the shipped template’s hash differs from this. |
list_widgets returns an array of these plus the activeWidgetId.
Icons
A WidgetIcon has a kind and a value:
{ "kind": "sfSymbol", "value": "thermometer" }
{ "kind": "emoji", "value": "🎵" }
{ "kind": "png", "value": "<base64-encoded PNG bytes>" }
| Kind | value | Notes |
|---|---|---|
sfSymbol | SF Symbol name | Best default — crisp, tint-safe, desaturates cleanly on the Lock Screen. |
emoji | one emoji | Colorful in-app; flattens to a tinted silhouette on the Lock Screen. |
png | base64 PNG on input | ~256px, transparent background, monochrome silhouette, ≤256 KiB. |
For a png, the hub stores the bytes, computes their SHA-256, and rewrites
value to that hash (a cache key); the raw bytes are served at
GET /widget/:id/icon. So a manifest you read back will show the hash, not the
base64 you sent.
Set or change an icon without touching the HTML via set_widget_icon:
{ "id": "wgt_abc123", "icon": { "kind": "sfSymbol", "value": "thermometer.sun" } }
Formal shapes
The typed shapes behind the tables above, plus the values MCP tools return.
WidgetManifest
interface WidgetManifest {
id: string;
name: string;
refreshMs: number;
htmlHash: string; // SHA-256 (hex) of the HTML
version: number;
publishedAt?: number; // Unix seconds
icon?: WidgetIcon;
builtInSlug?: string; // set if installed from a shipped template
builtInVersion?: number;
templateHash?: string; // SHA-256 of the pristine template last installed
}
WidgetIcon
interface WidgetIcon {
kind: "sfSymbol" | "emoji" | "png";
// sfSymbol: symbol name · emoji: the character ·
// png: base64 PNG on input, rewritten to the bytes' SHA-256 once stored
value: string;
}
WidgetVersion
One entry in a widget’s bounded code history. list_versions returns these
newest-first; set_widget_version selects one as the live version (no new
entry is appended — isCurrent moves to it and history stays intact).
interface WidgetVersion {
version: number;
htmlHash: string; // SHA-256 (hex) of that snapshot's HTML
updatedAt: number; // Unix seconds
note?: string;
isCurrent: boolean; // the version currently live (selection moves this)
builtInVersion?: number; // set when this cut is a pristine copy of a shipped
// built-in template (labels stock cuts vs your edits)
}
interface ListVersionsResult { versions: WidgetVersion[]; }
MCP tool results
// pair_status
interface PairStatus { paired: boolean; connected: boolean; deviceName?: string; }
// publish_widget
interface PublishWidgetResult { id: string; }
// list_widgets
interface ListWidgetsResult { widgets: WidgetManifest[]; activeWidgetId?: string; }
// list_versions → ListVersionsResult (see WidgetVersion above)
// get_data_endpoint
interface DataEndpoint { url: string; token: string; }
Tool arguments at a glance
| Tool | Required | Optional |
|---|---|---|
publish_widget | name, html | refreshMs, icon, actions |
update_widget | id, html | icon, refreshMs, note |
set_widget_icon | id, icon | — |
set_active_widget | id | — |
delete_widget | id | — |
list_versions | id | — |
set_widget_version | id, version | — |
push_data | id, data | — |
get_data_endpoint | id | — |
register_action | widgetId, actionId, capability | description, argKeys, requiresConfirmation |