Skip to content

Relax double sandboxed iframe architecture requirements#717

Open
domfarolino wants to merge 2 commits into
modelcontextprotocol:mainfrom
domfarolino:iframe-architecture
Open

Relax double sandboxed iframe architecture requirements#717
domfarolino wants to merge 2 commits into
modelcontextprotocol:mainfrom
domfarolino:iframe-architecture

Conversation

@domfarolino

Copy link
Copy Markdown
Contributor

Motivation and Context

The spec requires Hosts to render MCP Apps in a double sandbox iframe architecture and use the reserved proxy messages as a set-up ritual, as evidenced by requirements in § Sandbox proxy and other sections.

While a double sandboxed iframe architecture is a valid approach, it is not required to render MCP Apps security, and is more complicated than a single sandboxed iframe approach that satisfies the same security requirements. It'd be best if the spec were generally unopinionated about the exact framing architecture, as it is effectively a Host implementation detail—it has no bearing on the communication and compatibility between Hosts and Views.

This PR relaxes the specification to allow arbitrary framing architectures that meet a set of general security criteria, thus satisfying #716. This PR closes #716, and probably is enough to close #603 too, since a compliant Host could stream the bytes of an MCP App resources from its own 1p server directly into a single sandboxed iframe as the document resource.

How Has This Been Tested?

Google Gemini will be using a single sandboxed iframe architecture for simplicity and performance. Also, a follow-up PR to this one will be made to migrate examples/basic-host to a single sandboxed iframe architecture, as to not give the impression that a double sandboxed iframe approach is necessary or "recommended".

Breaking Changes

Nope! It should be noted though that this change is theoretically observable. If a Host went from using a double sandboxed iframe approach to a single one, an MCP App View could observe this by counting the window.parent hops between it and window.top. However, it's unlikely any MCP App code relies on this.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
    • I think so!
  • New and existing tests pass locally
    • All PDF server tests fail locally for me, even on main. All screenshot tests fail for me before and after this change too, because the baseline screenshots checked into the repository seem to expect a very specific OS font package that playwright is not displaying on macOS by default. But this PR is spec-only, so it shouldn't have any actual impact on test execution.
  • I have added appropriate error handling
    • This feels N/A
  • I have added or updated documentation as needed
    • I added lots of non-normative documents describing various sandboxing strategies a host might employ, to give prospective hosts some guidance

Update UI initialization diagram
Comment thread specification/draft/apps.mdx Outdated
Hosts act as MCP servers (that can proxy the actual MCP server), receiving and handling requests from UI iframes.

### Sandbox proxy
### <span id=sandbox-proxy>Rendering the MCP App</span>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In web standards world, we have a policy where any standards link should effectively live ~forever. This header title change would ordinarly break links to this section, but the <span> preserves the old ID so old links keep working after this PR.

If this is too pedantic, lmk and I'll revert :)

- If `permissions` is declared in `UIResourceMeta`, the Host MAY set the iframe's `allow` attribute accordingly

> [!WARNING]
> The document in the iframe that will host the MCP App view content MUST be served by a server the Host controls, in order to guarantee that the security properties specified by the tool definition (e.g., CSP) are set via HTTP headers properly. Relying on a third-party MCP server to serve the document in this iframe is not permitted by this specification, as Hosts would forfeit control over the app's most sensitive security properties.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is not a new requirement; it just backs up and elaborates on the one in https://github.com/modelcontextprotocol/ext-apps/blob/main/specification/draft/apps.mdx#4-content-security-policy-enforcement, which is that the Host, not the third-party MCP server, must serve the document that bears CSP headers, because that's the only way the Host can enforce the headers.

@domfarolino

Copy link
Copy Markdown
Contributor Author

Also /cc @fredericbarthelet who may be interested in this change!

@pkg-pr-new

pkg-pr-new Bot commented Jul 17, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/ext-apps

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

@modelcontextprotocol/server-basic-preact

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

@modelcontextprotocol/server-basic-react

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

@modelcontextprotocol/server-basic-solid

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

@modelcontextprotocol/server-basic-svelte

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

@modelcontextprotocol/server-basic-vanillajs

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

@modelcontextprotocol/server-basic-vue

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

@modelcontextprotocol/server-budget-allocator

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

@modelcontextprotocol/server-cohort-heatmap

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

@modelcontextprotocol/server-customer-segmentation

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

@modelcontextprotocol/server-debug

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

@modelcontextprotocol/server-lazy-auth

npm i https://pkg.pr.new/@modelcontextprotocol/server-lazy-auth@717

@modelcontextprotocol/server-map

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

@modelcontextprotocol/server-pdf

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

@modelcontextprotocol/server-scenario-modeler

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

@modelcontextprotocol/server-shadertoy

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

@modelcontextprotocol/server-sheet-music

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

@modelcontextprotocol/server-system-monitor

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

@modelcontextprotocol/server-threejs

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

@modelcontextprotocol/server-transcript

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

@modelcontextprotocol/server-video-resource

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

@modelcontextprotocol/server-wiki-explorer

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

commit: 2f9abc8

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.

spec: decouple rendering requirements from the double-sandboxed iframe architecture Proposal: Stream HTML resources for MCP Apps

1 participant