Skip to content

fix(examples): improve mobile support for map, pdf, and threejs examples#555

Merged
ochafik merged 4 commits intomodelcontextprotocol:mainfrom
mel-anthropic:mel/fix-safe-area-maps
Mar 18, 2026
Merged

fix(examples): improve mobile support for map, pdf, and threejs examples#555
ochafik merged 4 commits intomodelcontextprotocol:mainfrom
mel-anthropic:mel/fix-safe-area-maps

Conversation

@mel-anthropic
Copy link
Contributor

@mel-anthropic mel-anthropic commented Mar 18, 2026

Improve mobile support across several example MCP apps. Includes changes from #554 (touch gesture fixes).

Touch gesture fixes

On touch devices, drag/pan gestures inside WebGL-based example apps were propagating to the parent scroll view. Added non-passive touchstart/touchmove handlers with preventDefault() on interactive canvas elements.

Affected examples: map-server, threejs-server, wiki-explorer-server, shadertoy-server

Safe area, fullscreen, and responsive fixes

map-server

  • Fullscreen button position respects safe area insets
  • Button uses hover/opacity pattern, always visible on touch devices

pdf-server

  • Compute fit-to-width scale for narrow viewports
  • Recompute scale when container dimensions change
  • Toolbar respects safe area in fullscreen via CSS custom properties
  • Responsive toolbar for narrow screens

threejs-server

  • Fullscreen button respects safe area insets, always visible on touch, state stays up to date when host exits full screen
  • ResizeObserver for responsive width, host containerDimensions for fullscreen height
  • No container padding in fullscreen (canvas edge-to-edge)
  • Replace useHostStyles with inline style application to avoid overwriting onhostcontextchanged (SDK bug workaround)

Closes #554

- map-server: fullscreen button respects safe area insets, hover/opacity
  pattern with always-visible on touch devices
- pdf-server: fit-to-width scale for narrow viewports, responsive toolbar
  with compact controls on mobile, safe area in fullscreen toolbar via
  CSS custom properties
- threejs-server: fullscreen button respects safe area and always visible
  on touch, ResizeObserver for responsive width, host containerDimensions
  for fullscreen height, no container padding in fullscreen, replace
  useHostStyles with inline style application to avoid overwriting
  onhostcontextchanged handler
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 18, 2026

Open in StackBlitz

@modelcontextprotocol/ext-apps

npm i https://pkg.pr.new/@modelcontextprotocol/ext-apps@555

@modelcontextprotocol/server-basic-preact

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-preact@555

@modelcontextprotocol/server-basic-react

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-react@555

@modelcontextprotocol/server-basic-solid

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-solid@555

@modelcontextprotocol/server-basic-svelte

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-svelte@555

@modelcontextprotocol/server-basic-vanillajs

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-vanillajs@555

@modelcontextprotocol/server-basic-vue

npm i https://pkg.pr.new/@modelcontextprotocol/server-basic-vue@555

@modelcontextprotocol/server-budget-allocator

npm i https://pkg.pr.new/@modelcontextprotocol/server-budget-allocator@555

@modelcontextprotocol/server-cohort-heatmap

npm i https://pkg.pr.new/@modelcontextprotocol/server-cohort-heatmap@555

@modelcontextprotocol/server-customer-segmentation

npm i https://pkg.pr.new/@modelcontextprotocol/server-customer-segmentation@555

@modelcontextprotocol/server-debug

npm i https://pkg.pr.new/@modelcontextprotocol/server-debug@555

@modelcontextprotocol/server-map

npm i https://pkg.pr.new/@modelcontextprotocol/server-map@555

@modelcontextprotocol/server-pdf

npm i https://pkg.pr.new/@modelcontextprotocol/server-pdf@555

@modelcontextprotocol/server-scenario-modeler

npm i https://pkg.pr.new/@modelcontextprotocol/server-scenario-modeler@555

@modelcontextprotocol/server-shadertoy

npm i https://pkg.pr.new/@modelcontextprotocol/server-shadertoy@555

@modelcontextprotocol/server-sheet-music

npm i https://pkg.pr.new/@modelcontextprotocol/server-sheet-music@555

@modelcontextprotocol/server-system-monitor

npm i https://pkg.pr.new/@modelcontextprotocol/server-system-monitor@555

@modelcontextprotocol/server-threejs

npm i https://pkg.pr.new/@modelcontextprotocol/server-threejs@555

@modelcontextprotocol/server-transcript

npm i https://pkg.pr.new/@modelcontextprotocol/server-transcript@555

@modelcontextprotocol/server-video-resource

npm i https://pkg.pr.new/@modelcontextprotocol/server-video-resource@555

@modelcontextprotocol/server-wiki-explorer

npm i https://pkg.pr.new/@modelcontextprotocol/server-wiki-explorer@555

commit: e31025a

…el/fix-safe-area-maps

# Conflicts:
#	examples/map-server/mcp-app.html
#	examples/threejs-server/src/threejs-app.tsx
Copy link
Contributor

@ochafik ochafik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mel-anthropic !

Comment on lines +72 to +81
const root = document.documentElement;
if (params.theme) {
root.setAttribute("data-theme", params.theme);
root.style.colorScheme = params.theme;
}
if (params.styles?.variables) {
for (const [k, v] of Object.entries(params.styles.variables)) {
if (v !== undefined) root.style.setProperty(k, v as string);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit/follow-up: let's extract an applyHostStyle(ctx: McpUiHostContext) helper

@ochafik ochafik merged commit 83d82a1 into modelcontextprotocol:main Mar 18, 2026
15 checks passed
ochafik pushed a commit that referenced this pull request Mar 18, 2026
Extract an applyHostStyle(ctx: McpUiHostContext) helper that wraps the
SDK's applyDocumentTheme and applyHostStyleVariables, eliminating
duplicated inline style-application logic between the onhostcontextchanged
handler and the initial useEffect.

Also consolidates two useEffect hooks (both depending on [app] and
calling getHostContext()) into one.

Follow-up to #555.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants