Skip to content

Commit 65d9e31

Browse files
committed
docs: tighten prose and remove conversational tone
1 parent 7be4398 commit 65d9e31

4 files changed

Lines changed: 92 additions & 94 deletions

File tree

docs/design-guidelines.md

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,59 @@
11
---
22
title: Design Guidelines
33
group: Getting Started
4-
description: UX guidance for MCP Apps — what the host already provides, how to size your content, and how to stay visually consistent with the surrounding chat.
4+
description: UX guidance for MCP Apps, covering host-provided chrome, content sizing, and visual consistency with the surrounding chat.
55
---
66

77
# Design Guidelines
88

9-
MCP Apps live inside a conversation. They should feel like a natural part of the chat, not a separate application wedged into it.
9+
An MCP App is part of a conversation. It should read as a continuation of the chat, not as a separate application embedded inside it.
1010

11-
## The host provides the chrome
11+
## Host chrome
1212

13-
Hosts typically render a frame around your App that includes:
13+
Hosts render a frame around your App that typically includes:
1414

15-
- A **title bar** showing your App's name (from the tool or server metadata)
16-
- **Display-mode controls** (expand to fullscreen, collapse, close)
17-
- **Attribution** (which connector/server the App came from)
15+
- A title bar showing the App name (from tool or server metadata)
16+
- Display-mode controls (expand, collapse, close)
17+
- Attribution indicating which connector or server provided the App
1818

19-
**Don't duplicate these.** Your App doesn't need its own close button, title header, or "powered by" footer. Start your layout with the actual content.
19+
Do not duplicate these elements. Your App does not need its own close button, header bar, or "powered by" footer. Begin the layout with content.
2020

21-
If you need a title _inside_ your content (e.g., "Q3 Revenue by Region" above a chart), that's fine — just don't put your App's brand name there.
21+
A title inside the content area (for example, "Q3 Revenue by Region" above a chart) is acceptable. The App's brand name is not.
2222

23-
## Keep it focused
23+
## Scope
2424

25-
An MCP App answers one question or supports one task. Resist the urge to build a full dashboard with tabs, sidebars, and settings panels.
25+
An MCP App answers one question or supports one task. Avoid building a full dashboard with tabs, sidebars, and settings panels.
2626

27-
Good heuristics:
27+
- Inline mode should fit within roughly one viewport of scroll. Content that is significantly taller than the chat viewport belongs in fullscreen mode, or should be trimmed.
28+
- Limit inline mode to one primary action. A "Confirm" button is appropriate; a toolbar with eight icons is not.
29+
- Let the conversation handle navigation. Rather than adding a search box inside the App, let the user ask a follow-up question that re-invokes the tool with new arguments.
2830

29-
- **Inline mode should fit in roughly one screen of scroll.** If your content is much taller than the chat viewport, consider whether it belongs in fullscreen mode — or whether you're showing too much.
30-
- **One primary action at most.** A "Confirm" button is fine. A toolbar with eight icons is probably too much for inline mode.
31-
- **Let the conversation drive navigation.** Instead of building a search box inside your App, let the user ask a follow-up question and re-invoke the tool with new arguments.
31+
## Host UI imitation
3232

33-
## Don't replicate the host's UI
33+
Your App must not resemble the surrounding chat client. Do not render:
3434

35-
Your App must not look like the surrounding chat client. Specifically, avoid:
35+
- Chat bubbles or message threads
36+
- Anything that resembles the host's text input or send button
37+
- System notifications or permission dialogs
3638

37-
- Rendering fake chat bubbles or message threads
38-
- Mimicking the host's input box or send button
39-
- Showing fake system notifications or permission dialogs
39+
These patterns blur the line between host UI and App content, and most hosts prohibit them in their submission guidelines.
4040

41-
These patterns confuse users about what's real host UI versus App content, and most hosts prohibit them in their submission guidelines.
41+
## Host styling
4242

43-
## Use host styling where possible
43+
Hosts provide CSS custom properties for colors, fonts, spacing, and border radius (see [Adapting to host context](./patterns.md#adapting-to-host-context-theme-styling-fonts-and-safe-areas)). Using them keeps your App consistent across light mode, dark mode, and different host themes.
4444

45-
Hosts provide CSS custom properties for colors, fonts, spacing, and border radius (see [Adapting to host context](./patterns.md#adapting-to-host-context-theme-styling-fonts-and-safe-areas)). Using them makes your App feel native across light mode, dark mode, and different host themes.
45+
Brand colors are appropriate for content elements such as chart series or status badges. Backgrounds, text, and borders should use host variables. Always provide fallback values so the App renders correctly on hosts that omit some variables.
4646

47-
You can bring your own brand colors for content (chart series, status badges), but let the host's variables drive backgrounds, text, and borders. Always provide fallback values so your App still renders reasonably on hosts that don't supply every variable.
47+
## Display modes
4848

49-
## Inline vs fullscreen layout
49+
Design for inline mode first. It is the default, and it is narrow (often the width of a chat message) and height-constrained.
5050

51-
Design for **inline first**that's where your App appears by default. Inline mode is narrow (often the width of a chat message) and height-constrained.
51+
Treat fullscreen as a progressive enhancement for Apps that benefit from more space: editors, maps, large datasets. Check `hostContext.availableDisplayModes` before rendering a fullscreen toggle, since not every host supports it.
5252

53-
Treat **fullscreen** as a progressive enhancement for Apps that benefit from more space (editors, maps, large datasets). Check `hostContext.availableDisplayModes` before showing a fullscreen toggle — not every host supports it.
53+
When the display mode changes, update your layout: remove edge border radius, expand to fill the viewport, and re-read `containerDimensions` from the updated host context.
5454

55-
When switching modes, remember to adjust your layout: remove border radius at the edges, expand to fill the viewport, and re-read `containerDimensions` from the updated host context.
55+
## Loading and empty states
5656

57-
## Handle the empty and loading states
57+
The App mounts before the tool result arrives. Between `ui/initialize` and `ontoolresult`, render a loading indicator such as a skeleton, spinner, or neutral background. A blank rectangle looks broken.
5858

59-
Your App mounts before the tool result arrives. Between `ui/initialize` and `ontoolresult`, show something — a skeleton, a spinner, or at minimum a neutral background. A blank white rectangle looks broken.
60-
61-
Similarly, if your tool result can be empty (no search results, no items in cart), design a clear empty state rather than rendering nothing.
59+
If the tool result can be empty (no search results, empty cart), design an explicit empty state rather than rendering nothing.

docs/overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ Resources are declared upfront, during tool registration. This design enables:
110110
- **Separation of concerns** — Templates (presentation) are separate from tool results (data)
111111
- **Review** — Hosts can inspect UI templates during connection setup
112112

113-
**Versioning and caching.** Resource caching behavior is host-defined. A host may re-fetch your `ui://` resource each time it renders, cache it for the session, or persist it alongside the conversation. This means a user revisiting an old conversation may see either your _current_ template code running against the _original_ tool result, or a snapshot of both from when the tool first ran. Design your App to tolerate older `structuredContent` shapes — treat unknown fields gracefully and don't assume the template and the data were produced by the same code version.
113+
**Versioning and caching.** Resource caching behavior is host-defined. A host may re-fetch the `ui://` resource on each render, cache it for the session, or persist it alongside the conversation. When a user revisits an old conversation, the host may run the current template code against the original tool result, or it may replay a snapshot of both from the time of the original tool call. Design the App to tolerate older `structuredContent` shapes: handle unknown fields gracefully and do not assume the template and the data were produced by the same code version.
114114

115115
See the [UI Resource Format](https://github.com/modelcontextprotocol/ext-apps/blob/main/specification/2026-01-26/apps.mdx#ui-resource-format) section of the specification for the full schema.
116116

0 commit comments

Comments
 (0)