modelcontextprotocol / modelcontextprotocol/ext-apps
autoResize: true default causes layout bugs — need height management guidance
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.9k
- Forks
- 387
- Avg merge
- 3h 21m
- Merged PRs (30d)
- 6
Description
Problem
autoResize: true is the default in the Apps SDK, and it is the #1 source of layout bugs for MCP App developers. We hit this issue four separate times during development of our Mermaid MCP App, each with a different root cause:
| # | Root Cause | Symptom |
|---|---|---|
| 1 | height: 100vh + autoResize: true |
Infinite growth feedback loop: height reported → host adjusts → taller → report again → ∞ |
| 2 | autoResize: true overriding explicit fixed height |
Set height: 500px in CSS, but autoResize kept reporting content height instead |
| 3 | Fullscreen exit with stale hostHeight |
After exiting fullscreen, height stayed at ~900px (the fullscreen value) |
| 4 | useApp() hook ignores autoResize: false |
useApp() internally creates App with autoResize: true always — the option is not exposed in UseAppOptions (removed in v1.0.1). Even @ts-expect-error workarounds don't work at runtime. |
Issue #4 is particularly painful
The recommended useApp() hook cannot be used by any App that needs height control. Developers must drop down to manual new App() construction:
// Cannot use useApp() — it forces autoResize: true
const app = new App(
{ name: "my-app", version: "0.1.0" },
{},
{ autoResize: false } // only available via manual construction
);
Proposals
1. Change autoResize default to false
Most MCP Apps with non-trivial UI (diagrams, editors, canvases) need to control their own height. autoResize: true is only appropriate for simple content-driven displays. Making it opt-in would prevent the most common class of layout bugs.
2. Expose autoResize in useApp() hook
// Currently impossible — useApp() doesn't accept autoResize option
const app = useApp({ autoResize: false });
3. Document the three height strategies
The SDK should document these patterns explicitly:
| Strategy | When to use | Implementation |
|---|---|---|
| Fixed height (recommended default) | Most Apps | autoResize: false + height: 500px + manual sendSizeChanged() |
| Content-driven with cap | Simple display Apps | autoResize: true + CSS max-height |
| Full viewport | Fullscreen only | requestDisplayMode("fullscreen") + height: 100vh |
With explicit warning: 100vh + autoResize: true = infinite growth loop.
4. Improve fullscreen ↔ inline transitions
When displayMode changes from fullscreen to inline, the host should re-send containerDimensions with inline-mode values. Currently the App must remember its pre-fullscreen height and manually reset — which is error-prone.
An onDisplayModeChanged callback that includes the new dimensions would solve this cleanly:
app.ondisplaymodechanged = ({ mode, containerDimensions }) => {
// mode: "inline" | "fullscreen"
// containerDimensions: the dimensions for the new mode
};
Recommended pattern (for docs)
const DEFAULT_HEIGHT = 500;
// Do NOT use useApp() — it forces autoResize: true
const app = new App(
{ name: "my-app", version: "0.1.0" },
{},
{ autoResize: false }
);
// Register handlers BEFORE connect
app.ontoolinput = (params) => { /* ... */ };
app.onhostcontextchanged = (ctx) => {
const dims = ctx.containerDimensions;
if (dims?.height) hostHeight = dims.height;
else if (dims?.maxHeight) hostHeight = Math.min(DEFAULT_HEIGHT, dims.maxHeight);
else hostHeight = DEFAULT_HEIGHT;
};
await app.connect(transport);
// Report initial size (host doesn't know without autoResize)
app.sendSizeChanged({
width: document.documentElement.scrollWidth,
height: DEFAULT_HEIGHT,
});
Context
From building 3 production MCP Apps (Mermaid, PlantUML, Music). Height management consumed more debugging time than any other single issue. Every MCP App developer will hit some variant of these bugs.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing useApp(), UseAppOptions, and App construction to see how autoResize is selected and how height and display-mode changes are handled. Review sendSizeChanged(), onhostcontextchanged, and fullscreen transitions. Done means the proposed option/default behavior, height-management guidance, and transition dimensions are addressed with appropriate coverage.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100