Repository navigation
autoResize: true default causes layout bugs — need height management guidance #502
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.
Activity
ochafik commentedon Apr 21, 2026
v1.7.0 exposes
useApp({autoResize: false})(#622) so you can opt out and callapp.sendSizeChanged()yourself once content is ready. The default measurement behavior is unchanged for now (see #619 draft). Does the opt-out cover your case?