Skip to content

Commit bcc0543

Browse files
antonpk1claude
authored andcommitted
docs: add styles field to MCP Apps specification
- Add styles field to HostContext interface with reference to Theming section - Add Theming section documenting 36 standardized CSS variables - Document Host/App behavior for theming including light-dark() usage - Add Design Decision #4 explaining CSS variables approach - Include JSON example showing light-dark() pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent f276ec6 commit bcc0543

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

specification/draft/apps.mdx

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,8 @@ interface HostContext {
404404
};
405405
/** Current color theme preference */
406406
theme?: "light" | "dark";
407+
/** CSS variables for theming. See Theming section for standardized variable names. */
408+
styles?: Record<string, string>;
407409
/** How the UI is currently displayed */
408410
displayMode?: "inline" | "fullscreen" | "pip";
409411
/** Display modes the host supports */
@@ -440,6 +442,8 @@ interface HostContext {
440442

441443
All fields are optional. Hosts SHOULD provide relevant context. Guest UIs SHOULD handle missing fields gracefully.
442444

445+
For `styles`, apps SHOULD provide CSS fallback values (e.g., `var(--color-text-primary, #171717)`) to handle hosts that don't supply styles.
446+
443447
Example:
444448

445449
```json
@@ -453,13 +457,64 @@ Example:
453457
"hostInfo": { "name": "claude-desktop", "version": "1.0.0" },
454458
"hostContext": {
455459
"theme": "dark",
460+
"styles": {
461+
"--color-background-primary": "light-dark(#ffffff, #171717)",
462+
"--color-text-primary": "light-dark(#171717, #fafafa)",
463+
"--font-family-sans": "system-ui, sans-serif"
464+
},
456465
"displayMode": "inline",
457466
"viewport": { "width": 400, "height": 300 }
458467
}
459468
}
460469
}
461470
```
462471

472+
### Theming
473+
474+
Hosts pass CSS custom properties via `HostContext.styles` for visual cohesion with the host environment.
475+
476+
#### Standardized Variables
477+
478+
| Category | Variables |
479+
|----------|-----------|
480+
| Background | `--color-background-primary`, `--color-background-secondary`, `--color-background-tertiary`, `--color-background-inverted` |
481+
| Text | `--color-text-primary`, `--color-text-secondary`, `--color-text-tertiary`, `--color-text-inverted` |
482+
| Icons | `--color-icon-primary`, `--color-icon-secondary`, `--color-icon-tertiary`, `--color-icon-inverted` |
483+
| Borders | `--color-border-primary`, `--color-border-secondary` |
484+
| Accents | `--color-accent-info`, `--color-accent-danger`, `--color-accent-success`, `--color-accent-warning` |
485+
| Font Family | `--font-family-sans` |
486+
| Font Sizes | `--font-size-heading`, `--font-size-body`, `--font-size-caption` |
487+
| Font Weights | `--font-weight-regular`, `--font-weight-emphasized` |
488+
| Line Heights | `--font-leading-regular`, `--font-leading-tight` |
489+
| Composite Styles | `--font-style-heading`, `--font-style-body`, `--font-style-body-emphasized`, `--font-style-caption`, `--font-style-caption-emphasized` |
490+
| Border Radius | `--border-radius-small`, `--border-radius-medium`, `--border-radius-large`, `--border-radius-full` |
491+
| Border Width | `--border-width-regular` |
492+
493+
#### Host Behavior
494+
495+
- Hosts MAY provide any subset of standardized variables
496+
- Hosts MAY use CSS `light-dark()` function for theme-aware values
497+
- `theme` indicates the active mode; `styles` provides the concrete CSS values
498+
499+
#### App Behavior
500+
501+
- Apps SHOULD use fallback values for CSS variables: `var(--color-text-primary, #171717)`
502+
- This ensures graceful degradation when hosts omit `styles` or specific variables
503+
- When the host uses `light-dark()` values, apps MUST set `color-scheme` on their document:
504+
```css
505+
:root { color-scheme: light dark; }
506+
```
507+
508+
Example CSS:
509+
510+
```css
511+
.container {
512+
background: var(--color-background-primary, #ffffff);
513+
color: var(--color-text-primary, #171717);
514+
font: var(--font-style-body, 400 16px/1.4 system-ui);
515+
}
516+
```
517+
463518
### MCP Apps Specific Messages
464519

465520
MCP Apps introduces additional JSON-RPC methods for UI-specific functionality:
@@ -1050,6 +1105,24 @@ This proposal synthesizes feedback from the UI CWG and MCP-UI community, host im
10501105
- **Include external URLs in MVP:** This is one of the easiest content types for servers to adopt, as it's possible to embed regular apps. However, it was deferred due to concerns around model visibility, inability to screenshot content, and review process.
10511106
- **Support multiple content types:** Deferred to maintain a lean MVP.
10521107

1108+
#### 4. Host Theming via CSS Variables
1109+
1110+
**Decision:** Provide a standardized set of CSS custom properties for visual cohesion.
1111+
1112+
**Rationale:**
1113+
1114+
- CSS variables are universal, framework-agnostic, and require no runtime
1115+
- Apps apply styles via `var(--name)` with fallbacks for graceful degradation
1116+
- Limited variable set (colors, typography, borders) ensures hosts can realistically provide all values
1117+
- Spacing intentionally excluded—layouts break when spacing varies from original design
1118+
- No UI component library—no single library works across all host environments
1119+
1120+
**Alternatives considered:**
1121+
1122+
- **Full design system:** Rejected as too prescriptive; hosts have different aesthetics
1123+
- **Inline styles in tool results:** Rejected; separating theming from data enables caching and updates
1124+
- **CSS-in-JS injection:** Rejected; framework-specific and security concerns with injected code
1125+
10531126
### Backward Compatibility
10541127

10551128
The proposal builds on the existing core protocol. There are no incompatibilities.

0 commit comments

Comments
 (0)