Skip to content

Conversation

@idosal
Copy link
Collaborator

@idosal idosal commented Dec 15, 2025

Proposal to tackle #58 -

  1. Add frameDomains and baseUriDomains overrides to Resource Metadata's ui/csp attribute
  2. Add a permissions attribute(ui/permissions) to the Resource Metadata. Currently, it supports camera, microphone, and geolocation. There are many other permissions, but I think we should only add fields as they're needed. @alexi-openai could you please share what OpenAI allows?
  3. Add csp to Host<>App capability negotiation (since it's non-trivial for the app to detect at runtime)

If it's acceptable, I'll add an E2E test before merging.

Thoughts?

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 15, 2025

Open in StackBlitz

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

commit: e038020

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enhances the MCP Apps sandbox capability negotiation by adding support for additional CSP directives and permissions policies. The changes enable apps to request nested iframe support, custom base URI configuration, and browser permissions (camera, microphone, geolocation) through resource metadata.

Key changes:

  • Added frameDomains and baseUriDomains fields to CSP configuration for controlling nested iframes and base URI directives
  • Introduced permissions metadata for requesting camera, microphone, and geolocation access via Permission Policy
  • Extended host capability negotiation to include CSP support indicators (frameDomains and baseUriDomains)

Reviewed changes

Copilot reviewed 6 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/types.ts Added exports for new McpUiResourcePermissions type and schema
src/spec.types.ts Defined new interfaces for permissions and extended CSP configuration with frame/baseUri domains
src/generated/schema.ts Added Zod schemas for permissions and extended CSP schemas with new domain fields
src/generated/schema.test.ts Updated type inference tests to include new permissions schema
src/generated/schema.json Generated JSON schemas for new permissions and CSP extensions
specification/draft/apps.mdx Documented new CSP fields and permissions with examples and security guidance
examples/simple-host/sandbox.html Added new sandbox proxy HTML implementation (missing CSP/permissions handling)
examples/basic-host/src/sandbox.ts Implemented CSP meta tag building and iframe allow attribute for permissions
examples/basic-host/src/implementation.ts Extended resource data extraction to include new CSP and permissions metadata

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Collaborator

@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 Ido!

baseUriDomains?: string[];
};
permissions?: {
camera?: boolean;
Copy link
Collaborator

Choose a reason for hiding this comment

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

let's make these objects (as in capabilities) for future extensions?
e.g. what if one day there's fine-grained vers. coarse geolocation, or front vs. back camera permission, etc.

Copy link
Collaborator Author

@idosal idosal Dec 18, 2025

Choose a reason for hiding this comment

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

Like CSP, Permissions are coupled to the browser spec (Permissions Policy). I don't think we should diverge at this point. WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

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

There are 40+ Permission Policies you can stuff in an iFrame. Consider keeping permissions very simple and flexible, just have it be a string[].

Benefits:

  1. Client can set all permission policies with a single string. Flexible for future extensions.
  2. Enforcing this on the client side is simple. We just stuff the string into an iFrame's allow. This is safe because invalid strings are silently ignored.
  3. Still easily parseable on the server side. Server developer only has to do permissions.contains("camera");.

Copy link
Contributor

@matteo8p matteo8p Dec 22, 2025

Choose a reason for hiding this comment

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

Alternatively create some interface and have permission be an array of that interface if type safety and enforcement is of high importance.

interface Permissions {
   camera: "camera", 
   ....
}

permissions?: Permissions[]

Copy link
Collaborator

@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.

We should tell app what permissions were granted (and potentially which domains were allowed)

@idosal idosal requested a review from ochafik December 18, 2025 20:31
@matteo8p
Copy link
Contributor

Is there an iFrame in the ext-apps project, or that out of the scope of this extension project? I'm wondering where the permissions are getting enforced into the iFrame.

@matteo8p
Copy link
Contributor

matteo8p commented Dec 22, 2025

I can see this being useful if the MCP server needs to know what the browser capabilities / permissions are. However, I'm pretty sure you can also fetch the browser capability within the widget too using document.featurePolicy.allowedFeatures().

https://developer.mozilla.org/en-US/docs/Web/API/FeaturePolicy/allowedFeatures

I perhaps React widgets should be using this instead as a source of truth.

@matteo8p
Copy link
Contributor

@idosal I think OpenAI currently allows local-network-access *; microphone *; midi *

Screenshot 2025-12-22 at 3 57 47 PM

I have no clue why midi is on there. That's for music instruments haha

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.

4 participants