Glance MCP
Public MCP lets ChatGPT, Claude, or Cursor create and update Glance widgets. The host is the intelligence layer. Glance is the Home Screen.
Install the connector on glance.cool/mcp. This page is how it works after you connect.
What each side does
- Your host — Jira, mail, the other apps already connected in ChatGPT or Claude. Glance does not need a Jira connector.
- Glance — the widget slot, the layout language, ingest, and pinning on iPhone.
That is different from Glance AI in the iOS app. In-app Chat can also wire Glance automations and device sources. Public MCP cannot create Glance automations — the host pushes with ingest instead. Free Glance accounts can connect. Custom ChatGPT connectors usually need Developer Mode on a paid ChatGPT plan. That is not a Glance plan.
Auth
- MCP — sign in on glance.cool and Allow. The host then calls tools with your OAuth token. Live updates use the
ingesttool. Do notcurlthe ingest URL from the host. - Write key HTTP — for Shortcuts, Zapier, Make, or your backend. Same XOR payload. The key is shown once when the widget is created. Dynamic Ingest.
Typical flow
get_plan— do not assume ChatGPT Plus or Claude Pro is Glance Pro.list_widgets— if any exist, ask whether to update one or create another.- Design a tree from Layout Language and
list_golden_examples. - Save a layout with
create_template, or skip that on Pro+ and sendinline_uion ingest. - If new:
create_dynamic_widget, theningest. - Pin on iPhone. Pin to Home Screen.
Ingest from the host
content keys are binding names inside {{ }}, not Jira or GitHub field IDs. Exactly one layout arm.
// Saved layout
{ "feed_id": "<feed uuid>", "template_id": "<template uuid>", "content": { "headline": "Standup in 10 min" } }
// UI on Demand (Pro+)
{ "feed_id": "<feed uuid>", "inline_ui": { "tree": { … }, "widget_size": "medium" }, "content": { "headline": "Standup in 10 min" } }Never send template_id with inline_ui or a top-level tree. If get_plan.capabilities.ui_on_demand is false, only template_id. Details and the HTTP shape are on Dynamic Ingest · UI on Demand.
Tools
Public MCP is a subset. Automations, integration OAuth, and device permissions stay in the iOS app / Glance AI.
| Tool | Role |
|---|---|
| get_plan | Live quotas and capabilities. Call before promising UI on Demand or extra layouts. |
| list_widgets | Existing widgets. Ask create vs update. Do not silently duplicate. |
| create_dynamic_widget | New widget + feed. Returns write_key once, for Shortcuts / HTTP only. |
| get_widget_status | Last ingest, live layout, uiMode. Never returns a write key. |
| list_templates / get_template | Saved layouts. get_template returns one tree. |
| validate_template | Optional. Structural errors block save. Design warnings do not. |
| create_template / update_template | Save or revise a layout. |
| list_golden_examples | Reference trees before designing a new one. |
| ingest | Push live content. OAuth only. XOR template_id or inline_ui. |
| delete_widget | Permanent. Confirm first. |
Plans
agent_messages_per_day counts in-app Glance AI only, not ChatGPT or Claude tokens. UI on Demand is Pro and Power. Call get_plan rather than guessing. The live numbers sit on Features.
Design skill
Same file the host can read at glance://skills/design. MCP is the tools. This skill is how the host should compose the widget. Install from glance.cool/mcp: SKILL.md, zip, or npx skills add https://glance.cool/skills/glance-design/SKILL.md.
Glance Widget Design Skill
You design iOS home screen widgets that feel native, calm, and glanceable — like Apple built them. This skill covers visual design and composition only. Workflow, tools, integrations, and sizing math live in the main agent skill.
Diversity over templates: Every widget should fit its data and the user's intent. These are principles and patterns — not a single layout to copy. Vary structure, density, and emphasis. Never force one recipe when another fits better.
Design north star
Widgets should feel like Apple system UI: clear hierarchy, generous whitespace, restrained color, SF typography. A user glancing at their home screen should read the widget in under two seconds.
| Trait | What it means in practice |
|---|---|
| Glanceable | One clear takeaway — a number, status, or headline |
| Native | System fonts, semantic colors, no "web app" density |
| Calm | Mostly neutral surfaces; color carries meaning, not decoration |
| Intentional | Every element earns its space — if it doesn't help, remove it |
Color — Apple-native default, user-guided override
Default (no user color preference)
Think Settings / Stocks / Weather — not marketing landing pages.
| Role | Guidance |
|---|---|
| Background | Omit background on root for system adaptive fill, or #FFFFFF / #F2F2F7 (light) — never loud gradients unless the user asks |
| Primary text | #000000 or omit color (system primary) |
| Secondary / labels | #8E8E93 (iOS secondary label) — captions, timestamps, units |
| Tertiary / hints | #AEAEB2 — de-emphasized metadata only |
| Accent | One semantic accent per widget — e.g. #007AFF (system blue) for links/active, #34C759 success, #FF9500 warning, #FF3B30 alert |
| Progress / fills | Muted track #E5E5EA, fill = single accent |
Rules: - Never use more than one accent hue unless the user requests a colorful or branded look. - Never fill large areas with saturated color — accents belong on small elements (badge, progress fill, status dot, one headline word). - Prefer opacity and weight over more colors to create hierarchy.
iOS color format (critical on device)
The iOS renderer only parses 6-digit hex (#RRGGBB). Values like #FFFFFFCC or #FFFFFF40 are ignored and fall back to system .primary (often black on light widgets).
- Use solid 6-digit hex for every
color,background,backgroundColor,trackColor,fillColor. - For muted/secondary text on dark or gradient backgrounds, pick a lighter solid tint (e.g.
#FFE8F5on purple gradients) — not alpha suffixes. - On colorful widgets, desaturated label colors still beat 8-char hex.
When the user gives color direction
Follow the user. If they say "dark purple theme", "brand pink #E91E8C", or "match my logo colors" — apply their palette to backgrounds, accents, and text while keeping hierarchy and readability. Still use muted variants for labels (#8E8E93 or a desaturated version of their accent).
If they share no preference, use the Apple-native defaults above.
Typography
Use SF Pro (sf-pro or omit fontFamily). Reserve sf-rounded for playful/countdown widgets; sf-mono for code/GitHub hashes only.
| Role | fontSize | fontWeight | color |
|---|---|---|---|
| Hero value | 24–32 | bold or heavy | primary |
| Section title | 15–17 | semibold | primary |
| Body / detail | 13–15 | regular or medium | primary or secondary |
| Caption / label | 10–12 | regular or medium | #8E8E93 |
| Unit / suffix | 11–13 | medium | secondary — on stat via suffix |
Limits: At most 3 distinct font sizes per widget. At most 2 weights in active use (e.g. semibold + regular).
Always set maxLines: 1 on titles and hero lines in small and medium widgets. Use maxLines: 2 sparingly on large only when content demands it.
Spacing rhythm
Pick one rhythm and stick to it for the whole tree:
| Token | Use |
|---|---|
| 8 pt | Tight gaps inside a row (icon + label) |
| 12 pt | Root padding, default spacing within sections |
| 16 pt | Between major sections on large widgets |
Root container: `padding: 12` minimum (16 for airy large layouts). Never mix 6 / 10 / 14 randomly.
Use spacer with flex: 1 to push footer elements (badge, timestamp) to the bottom on large — don't stack everything at the top.
Visual hierarchy — the one-hero rule
Every widget needs one focal point:
| Size | Typical hero |
|---|---|
small | One stat value, one large number text, or one avatar + short label |
medium | Hero left or top + supporting detail opposite/below |
large | Hero row + 2–4 supporting metrics or a content block |
Everything else is supporting — smaller, lighter color, fewer lines.
Do not give equal visual weight to five text lines. If everything is bold and 16 pt, nothing is important.
Static vs dynamic bindings
Only {{variable_name}} becomes a content field (upload form, automation ingest, bindings_required).
| Use case | Template syntax | In derived schema? |
|---|---|---|
| Live data (username, KPI value, event title) | "binding": "{{username}}" | Yes |
| Fixed section label ("Profile views today") | "binding": "Profile views today" | No |
| Fixed metric name under a ring ("Revenue") | "binding": "Revenue" | No |
| Decorative brand icon (design constant) | "binding": "https://…/icon.png" on image | No |
| SF Symbol | "binding": "bag.fill" on icon | No |
| Progress-dependent caption | "binding": "{{overall_goal_caption}}" | Yes |
Rule: If the copy or asset never changes per refresh, use a plain literal — not {{}}. This keeps the upload flow clean and matches how the goldens are authored.
Static images on device: use HTTPS PNG/JPEG URLs. Local paths like /brand-icons/… only work in React preview.
Golden reference library
Six device-approved examples live in packages/sdk/goldens/. They are the quality bar — adapt their structure to the user's data; never paste one verbatim with wrong bindings.
Before designing: call list_golden_examples (filter by widget_size or fetch one with example_id).
| ID | Size | Pattern | When to adapt |
|---|---|---|---|
| s1-glance-kpi | small | Gradient + username + 2 stacked KPI stats + static brand icon | Social/account KPIs, branded small metrics |
| s2-glance-media | small | White card: static section label → title → centered thumbnail → caption | Latest post/video/article thumbnails |
| m1-split-strip | medium | Left: static title stack · Right: hero stat | Single headline metric strips (monitoring, uptime) |
| m2-multi-source | medium | Left motion panel + right spend card + calendar event rows | Multi-integration dashboards (device + cloud) |
| l1-app-performance | large | Dark 2×2 KPI rings (z-stack + circular_progress) + quarterly progress_bar | Custom business metrics with goal progress |
| l2-outfit-of-the-day | large | Gradient + hero image + shoppable item rows (href + icon) | Creator commerce, product lists, playful layouts |
Golden techniques worth copying
- S1:
gradientroot; static caption literals above dynamicstatvalues; trailing brandimagewith static URL - S2: explicit
spacergaps between title/image/caption;maxLineson all text; white#FFFFFFroot background - M1: horizontal split with
flex: 1text column + trailing herostat(valueFontSize: 40) - M2: nested gray cards (
#F2F2F7); color accent bars beside calendar rows; formatted strings intextnotstat - L1: ring container 82×82 with
circular_progresssize 70, lineWidth 5 (prevents stroke clip); value text centered inz-stack;overall_goal_captionstays dynamic - L2:
gradientwithspacingas gap;fillContainerhero image;hrefon shop tap targets;sf-roundedfor playful headers
Size patterns (adapt — do not copy blindly)
Prefer picking a golden reference above, then adapt. These ASCII sketches are fallbacks when no golden fits:
Small (170×170) — "one glance"
Best for: single KPI, countdown, status, one image thumbnail.
vertical container, padding 12, spacing 8 → caption text (12pt, secondary, maxLines 1) // label → stat OR large text (hero, 26–30pt) // THE number/word → optional: badge OR relative_time (11pt) // context
Avoid: horizontal rows of 3+ items, multiple stats, long paragraphs.
Medium (364×170) — "headline strip"
Best for: integration dashboard, social snapshot, calendar next event.
Pattern A — split row:
vertical, padding 12
→ horizontal row, spacing 12, alignment center
→ left column (vertical): title + subtitle
→ right: stat OR circular_progress OR avatar/imagePattern B — title + detail row:
vertical, padding 12, spacing 8 → title text (15pt semibold, maxLines 1) → horizontal row: 2–3 compact stats OR image + text pair
Avoid: more than one horizontal band; cramming 4 columns.
Large (364×382) — "dashboard card"
Best for: multi-metric boards, feed digests, rich integration views.
vertical, padding 12–16, spacing 12 → header row (horizontal): title + optional badge → main content: 2–3 stats in a row OR 2×2 grid of images/metrics → spacer (flex 1) // optional → footer: progress_bar OR relative_time OR caption // optional
Use divider between header and body only when it clarifies — not by default.
Component combinations that look polished
| Combo | When to use |
|---|---|
stat + caption text above | KPI widgets (followers, revenue, streak) |
avatar + vertical text stack in horizontal row | Social / account identity |
image (cornerRadius 8) + text beside | Latest post, thumbnail + caption |
badge (subtle bg #E5E5EA, text primary) | Status chips — "Live", "3 new" |
progress_bar (height 6–8, muted track) | Goal completion — one per widget |
z-stack + full-bleed image + text with light color | Event spotlight — use sparingly |
status_dot + text | Health / server / pipeline status |
relative_time or date in caption style | "Updated 2m ago" footer |
`stat` tips: Use valueFontSize 26–32 for hero stats; labelFontSize 11; suffix for units (K, %, °). Prefer ig_followers_fmt style formatted strings in text when the integration provides them.
Layout polish
- Alignment:
leadingfor LTR text blocks;centerfor single hero in small;trailingfor meta (time, badge) in header rows — but see reload button rule below. - Reload button: Glance overlays a reload control in the top-right (~40×40 pt). Never put hero values or must-read text there; prefer leading clusters for top-band KPIs (label + value side-by-side).
- Images: Always set explicit
width/height;cornerRadius: 8–12for photos;contentMode: "fill"for thumbnails. - Nested cards: Inner
containerwithbackground: "#F2F2F7",cornerRadius: 10,padding: 10— sparingly, one level deep max. - Full bleed: Only
gradientroot for dramatic widgets — and only when user wants flair or data suits it (event poster, media highlight).
Anti-patterns — never ship these
| Anti-pattern | Why it fails |
|---|---|
5+ text nodes all 14 pt regular | No hierarchy — wallpaper of words |
| Rainbow hex on every element | Feels non-native, noisy |
Horizontal row of 4 images on small | Guaranteed clip / crush |
stat for currency ($1,234) or % strings | Type errors + ugly fallback |
Root padding: 0 or missing | Corner clip on home screen |
| Hero stat / spend in top-trailing corner | Hidden under reload button overlay |
gap, borderRadius, textAlign style keys | Silently ignored — use correct keys from main skill |
{{}} on fixed labels or decorative icons | Forces upload fields; use static literals instead |
8-char hex colors (#RRGGBBAA) | iOS ignores them — text falls back to black primary |
Design process (before you write JSON)
- Clarify intent — glance KPI? digest? status? media?
- Pick `widget_size` — smallest size that fits without clutter.
- Choose one hero — what is the single takeaway?
- `list_golden_examples` — pick the closest golden; call with
example_idto load its tree. - Adapt the pattern — swap bindings for real integration fields; static labels stay literal.
- Assign typography — hero / body / caption sizes from table.
- Apply color — native defaults unless user specified palette; 6-digit hex only.
- Run sizing math — main skill algorithm; shrink before dropping the hero.
- (Optional) `validate_template` — max 2 calls per design for early feedback; then
create_template. Structure must pass; design warnings do not block save. - Preview pause — describe what the user will see; invite tweaks.
Pre-submit checklist
Before create_template, confirm mentally (server structure is the save gate; padding/overflow are warnings):
- [ ] One clear hero element
- [ ] ≤ 3 font sizes, ≤ 2 active weights
- [ ] Root
padding≥ 12 (guideline —ROOT_PADDING_LOWwill not block save) - [ ] Labels use secondary color (
#8E8E93or user-muted variant) - [ ] At most one accent color (unless user asked for more)
- [ ]
maxLinesset on text that must not wrap - [ ] Top-trailing corner clear of hero values (reload button overlay)
- [ ] Static labels/icons use plain literals (no
{{}}unless value changes per refresh) - [ ] All colors are 6-digit
#RRGGBB(no alpha suffix) - [ ] Layout suits the data — not a generic placeholder grid
Talking to the user about design
- Describe the visual hierarchy in plain language: *"Large follower count up top, latest post caption below in gray."*
- Offer one alternative when useful: *"I can also do a side-by-side layout with your profile photo — prefer that?"*
- If the user says it looks plain, add structure (nested card, badge, progress) or typography contrast — not more random colors.