feat(mcp-apps): fullscreen title bar for the App frame, header contrast, reachable consent#418
Merged
Merged
Conversation
…st, reachable consent In fullscreen the App frame now becomes a fixed flex-column overlay with the connected header promoted to a title bar that hosts the Exit control, instead of a floating chip overlaying the App. Three fixes to the frame's fullscreen surface ship together since they touch the same markup: - Fullscreen header: the container (not the bare iframe) is the fixed full-viewport overlay; the iframe absolute-fills its flex-1 host below the title bar. The Exit button moves into the title bar so it no longer overlaps the App's own top-corner chrome (e.g. Excalidraw's toolbar). Toggling mode stays pure CSS, so the running App never reloads. - Header contrast: the inline card now carries dark:bg-gray-900 so the header's translucent fill composites over the same surface as fullscreen — an inline card left bg-white turned the header a muddy mid-grey and dropped the tool name to ~1.5:1. The tool name, separator, details glyph, and running shimmer are bumped to clear WCAG AA for low vision. - App-initiated consent (ui/open-link) now renders inside the frame, below the title bar, instead of as a sibling above the card. In fullscreen the out-of-overlay prompt was painted over by the z-[9999] overlay and was unreachable, so "Open in Excalidraw" hung on "exporting…" — the host holds the JSON-RPC response open awaiting a consent the user could not grant. Build clean; 36 MCP-apps specs pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Three fixes to the MCP App frame's fullscreen experience, grouped into one commit because they're interleaved in the same component markup (
mcp-app-frame.component.ts).1. Fullscreen title bar (was: floating Exit chip overlapping the App)
Previously, fullscreen promoted the bare iframe to a
fixed inset-0 z-[9999]overlay and floated the "Exit fullscreen" button as az-[10000]chip in the top-right — which landed on top of the App's own top-corner chrome (e.g. Excalidraw's "Open" button).Now the container is the fixed full-viewport flex column, with the connected header promoted to a title bar that hosts the Exit control; the iframe absolute-fills its
flex-1host below the bar. No overlap, and a more discoverable labeled Exit button. Toggling display mode stays pure CSS on existing DOM, so the running App never reloads.2. Header dark-mode contrast / low-vision
The header background is translucent (
dark:bg-gray-800/60), so it composites over whatever's behind it. The inline card's container hadbg-whitewith no dark override, so in dark mode the header composited over white into a muddy mid-grey (~#797f87) and the tool name (text-gray-400on that) dropped to roughly 1.5:1 — the grey-on-grey you'd see oncreate_view.dark:bg-gray-900, so the header composites over the same surface as fullscreen (whose container was alreadydark:bg-gray-900). The fullscreen header's background is unchanged.text-gray-500 dark:text-gray-400→text-gray-600 dark:text-gray-300(≈7.4:1 / ≈11:1).3. "Open in Excalidraw" hung on "exporting…" (unreachable consent in fullscreen)
The App's export fires
ui/open-link; the host holds the JSON-RPC response open until the user answers its inline consent strip ("This app wants to open excalidraw.com — Allow"). That strip rendered as a sibling above the card — outside the fullscreen overlay — so thez-[9999]overlay painted over it. In fullscreen the user could never grant consent, the bridge never responded, and Excalidraw sat on "exporting…" forever.The consent strip now renders inside the frame, below the title bar and above the iframe, so it's within the overlay and reachable in both modes. (The bridge/consent/proxy logic is unchanged — this was purely a stacking/placement bug.)
Reviewer notes
Testing
ng buildclean.ng test— 36 MCP-apps specs pass (mcp-app-bridge31,mcp-app-consent.service5).mcp-sandboxstack serves an App that emits aui_resource. Manual check against a live App:create_viewclearly legible.🤖 Generated with Claude Code