Skip to content

Commit d07eb1f

Browse files
authored
Merge pull request #130 from modelcontextprotocol/styles-spec
docs: add styles to MCP Apps specification
2 parents f8c0ffa + 854fec2 commit d07eb1f

File tree

1 file changed

+73
-2
lines changed

1 file changed

+73
-2
lines changed

specification/draft/apps.mdx

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,8 @@ interface HostContext {
401401
};
402402
/** Current color theme preference */
403403
theme?: "light" | "dark";
404+
/** CSS variables for theming. See Theming section for standardized variable names. */
405+
styles?: Record<string, string>;
404406
/** How the UI is currently displayed */
405407
displayMode?: "inline" | "fullscreen" | "pip";
406408
/** Display modes the host supports */
@@ -435,8 +437,6 @@ interface HostContext {
435437
}
436438
```
437439

438-
All fields are optional. Hosts SHOULD provide relevant context. Guest UIs SHOULD handle missing fields gracefully.
439-
440440
Example:
441441

442442
```json
@@ -450,13 +450,66 @@ Example:
450450
"hostInfo": { "name": "claude-desktop", "version": "1.0.0" },
451451
"hostContext": {
452452
"theme": "dark",
453+
"styles": {
454+
"--color-background-primary": "light-dark(#ffffff, #171717)",
455+
"--color-text-primary": "light-dark(#171717, #fafafa)",
456+
"--font-family-sans": "system-ui, sans-serif",
457+
...
458+
},
453459
"displayMode": "inline",
454460
"viewport": { "width": 400, "height": 300 }
455461
}
456462
}
457463
}
458464
```
459465

466+
### Theming
467+
468+
Hosts can optionally pass CSS custom properties via `HostContext.styles` for visual cohesion with the host environment.
469+
470+
#### Current Standardized Variables
471+
472+
| Category | Variables |
473+
|----------|-----------|
474+
| Background | `--color-background-primary`, `--color-background-secondary`, `--color-background-tertiary`, `--color-background-inverted` |
475+
| Text | `--color-text-primary`, `--color-text-secondary`, `--color-text-tertiary`, `--color-text-inverted` |
476+
| Icons | `--color-icon-primary`, `--color-icon-secondary`, `--color-icon-tertiary`, `--color-icon-inverted` |
477+
| Borders | `--color-border-primary`, `--color-border-secondary` |
478+
| Accents | `--color-accent-info`, `--color-accent-danger`, `--color-accent-success`, `--color-accent-warning` |
479+
| Font Family | `--font-family-sans` |
480+
| Font Sizes | `--font-size-heading`, `--font-size-body`, `--font-size-caption` |
481+
| Font Weights | `--font-weight-regular`, `--font-weight-emphasized` |
482+
| Line Heights | `--font-leading-regular`, `--font-leading-tight` |
483+
| Composite Styles | `--font-style-heading`, `--font-style-body`, `--font-style-body-emphasized`, `--font-style-caption`, `--font-style-caption-emphasized` |
484+
| Border Radius | `--border-radius-small`, `--border-radius-medium`, `--border-radius-large`, `--border-radius-full` |
485+
| Border Width | `--border-width-regular` |
486+
487+
#### Host Behavior
488+
489+
- Hosts can provide any subset of standardized variables, or not pass `styles` at all. However, passing all of the standardized properties is recommended for cohesiveness
490+
- Hosts can use the CSS `light-dark()` function for theme-aware values
491+
492+
#### App Behavior
493+
494+
- Apps should set default fallback values for CSS variables, to account for hosts who don't pass some or all style variables. This ensures graceful degradation when hosts omit `styles` or specific variables:
495+
```
496+
:root {
497+
--colorTextPrimary: #171717;
498+
}
499+
```
500+
- Apps can use the `applyHostStyles` utility (or `useHostStyles` if they prefer a React hook) to easily populate the host-provided CSS variables into their style sheet
501+
- Apps can use the `applyDocumentTheme` utility (or `useDocumentTheme` if they prefer a React hook) to easily respond to Host Context `theme` changes in a way that is compatible with the host's light/dark color variables
502+
503+
Example usage of standardized CSS variables:
504+
505+
```css
506+
.container {
507+
background: var(--color-background-primary);
508+
color: var(--color-text-primary);
509+
font: var(--font-style-body);
510+
}
511+
```
512+
460513
### MCP Apps Specific Messages
461514

462515
MCP Apps introduces additional JSON-RPC methods for UI-specific functionality:
@@ -1046,6 +1099,24 @@ This proposal synthesizes feedback from the UI CWG and MCP-UI community, host im
10461099
- **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.
10471100
- **Support multiple content types:** Deferred to maintain a lean MVP.
10481101

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

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

0 commit comments

Comments
 (0)