Summary
In Claude Desktop, clicking a control inside a fullscreen MCP App leaves the
conversation in a state where every subsequent message moves the chat composer up away
from the bottom of the window. The displacement accumulates and can carry the composer
out of the viewport.
The behavior is host-side, and it reproduces with the debug-server example in this
repository, copied without modification. Filed here because the
getting-started page
points to this repository for MCP Apps issues.
Three measured properties:
- Until the app is clicked, messages do not displace the composer at all, at any scroll
depth.
- After the app is clicked, each message adds displacement equal to about half the
scroll height that message adds.
- The click itself displaces nothing, and returning focus to the composer does not undo
the state.
Leaving fullscreen, or switching to another conversation, restores the composer.
Environment
- Claude Desktop 1.52386.6.0 (Microsoft Store package) on Windows 11
- Reproduced with
examples/debug-server, copied without modification and packaged as a
local .mcpb desktop extension
Steps to reproduce
- Package
examples/debug-server as a .mcpb and install it in Claude Desktop.
- In a new conversation, call its tool and put the app in fullscreen display mode.
- Send two or three messages without clicking anything inside the app. The composer
stays at the bottom of the window.
- Click any control inside the app. The composer does not move yet.
- Send another message. The composer moves up.
- Send further messages. The composer moves up again each time.
Measurements
Taken in the Claude Desktop DevTools console (Help > Troubleshooting > Enable Developer
Mode, then Ctrl+Shift+I), with the unmodified debug-server app fullscreen:
(() => {
const c = document.querySelector('[data-chat-input-container]');
const s = c?.closest('[data-autoscroll-container]');
return {
composerGap: Math.round(innerHeight - c.getBoundingClientRect().bottom),
scrollTop: Math.round(s?.scrollTop ?? -1),
scrollHeight: Math.round(s?.scrollHeight ?? -1),
clientHeight: Math.round(s?.clientHeight ?? -1),
};
})()
composerGap is the distance from the bottom of the window to the bottom of the
composer. When the composer is correctly placed, it is 0.
| Sample |
composerGap |
scrollTop |
scrollHeight |
clientHeight |
| Messages sent, app untouched |
0 |
837 |
2735 |
1522 |
| Messages sent, app untouched |
0 |
2580 |
4103 |
1522 |
| Messages sent, app untouched |
0 |
2984 |
4507 |
1522 |
| After clicking in the app, then sending |
941 |
4278 |
5912 |
1522 |
The first three samples show that scroll depth alone does not displace the composer:
scrollTop more than triples while composerGap stays at 0. The fourth sample differs
from them by one action, a click inside the app's iframe.
The accumulation, sampled every 500ms
Once the app has been clicked, a timer logging composerGap, scrollTop and
document.activeElement through two further sends gives this sequence, condensed to the
points where a value changes:
| Event |
composerGap |
scrollTop |
activeElement |
| Start of recording, app already clicked once |
1193 |
4666 |
DIV[chat-input] |
| Click inside the app, held for about 10s |
1193 |
4666 |
IFRAME |
| Focus returns to the composer |
1193 |
4666 |
DIV[chat-input] |
| Send a message |
1380 |
5041 |
DIV[chat-input] |
| Send a message |
1569 |
5418 |
DIV[chat-input] |
Two things follow from that sequence.
The displacement advances only when a message is sent, not when the app is clicked.
composerGap is unchanged across the whole period when activeElement is the app's
iframe, and both increases happen while focus is on the composer.
Each increase is close to half the scroll height the message adds. The first send adds
375 to scrollTop and 187 to composerGap, and the second adds 377 and 189.
Additional observations from a second app
A separate MCP App, which presents many controls and so is clicked on constantly, shows
the displacement throughout a fullscreen session. In that app composerGap grew to
3828 in a long conversation, and in a new conversation it tracked the scroller's
scrollTop closely, measuring 281 against a scrollTop of 273.
In every sample from both apps the composer reports position: sticky, so the
displacement is not the sticky positioning being dropped. The app container reports
position: fixed, and dismissing the app changed scrollHeight by 61px, so the app's
frame is not contributing to the conversation scroller's content height.
Impact
A fullscreen MCP App becomes hard to use alongside the conversation, because any use of
the app displaces the composer and every subsequent message displaces it further. An app
with controls cannot avoid the trigger.
Leaving and re-entering fullscreen restores the composer temporarily until the next message is sent, as does switching
conversations.
Summary
In Claude Desktop, clicking a control inside a fullscreen MCP App leaves the
conversation in a state where every subsequent message moves the chat composer up away
from the bottom of the window. The displacement accumulates and can carry the composer
out of the viewport.
The behavior is host-side, and it reproduces with the
debug-serverexample in thisrepository, copied without modification. Filed here because the
getting-started page
points to this repository for MCP Apps issues.
Three measured properties:
depth.
scroll height that message adds.
the state.
Leaving fullscreen, or switching to another conversation, restores the composer.
Environment
examples/debug-server, copied without modification and packaged as alocal
.mcpbdesktop extensionSteps to reproduce
examples/debug-serveras a.mcpband install it in Claude Desktop.stays at the bottom of the window.
Measurements
Taken in the Claude Desktop DevTools console (Help > Troubleshooting > Enable Developer
Mode, then Ctrl+Shift+I), with the unmodified
debug-serverapp fullscreen:composerGapis the distance from the bottom of the window to the bottom of thecomposer. When the composer is correctly placed, it is 0.
The first three samples show that scroll depth alone does not displace the composer:
scrollTopmore than triples whilecomposerGapstays at 0. The fourth sample differsfrom them by one action, a click inside the app's iframe.
The accumulation, sampled every 500ms
Once the app has been clicked, a timer logging
composerGap,scrollTopanddocument.activeElementthrough two further sends gives this sequence, condensed to thepoints where a value changes:
DIV[chat-input]IFRAMEDIV[chat-input]DIV[chat-input]DIV[chat-input]Two things follow from that sequence.
The displacement advances only when a message is sent, not when the app is clicked.
composerGapis unchanged across the whole period whenactiveElementis the app'siframe, and both increases happen while focus is on the composer.
Each increase is close to half the scroll height the message adds. The first send adds
375 to
scrollTopand 187 tocomposerGap, and the second adds 377 and 189.Additional observations from a second app
A separate MCP App, which presents many controls and so is clicked on constantly, shows
the displacement throughout a fullscreen session. In that app
composerGapgrew to3828 in a long conversation, and in a new conversation it tracked the scroller's
scrollTopclosely, measuring 281 against ascrollTopof 273.In every sample from both apps the composer reports
position: sticky, so thedisplacement is not the sticky positioning being dropped. The app container reports
position: fixed, and dismissing the app changedscrollHeightby 61px, so the app'sframe is not contributing to the conversation scroller's content height.
Impact
A fullscreen MCP App becomes hard to use alongside the conversation, because any use of
the app displaces the composer and every subsequent message displaces it further. An app
with controls cannot avoid the trigger.
Leaving and re-entering fullscreen restores the composer temporarily until the next message is sent, as does switching
conversations.