modelcontextprotocol / modelcontextprotocol/ext-apps

autoResize: true default causes layout bugs — need height management guidance

Open
#502 1 comment 1 reaction 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.