Skip to content

Commit 55750c5

Browse files
ochafikclaude
andcommitted
refactor: Remove permissions support (defer to PR #158)
Keep this PR focused on CSP security fixes only. Permissions (camera, microphone, geolocation) will be handled in #158. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 066531a commit 55750c5

8 files changed

Lines changed: 380 additions & 205 deletions

File tree

examples/basic-host/src/implementation.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,6 @@ interface UiResourceData {
4848
frameDomains?: string[];
4949
baseUriDomains?: string[];
5050
};
51-
permissions?: {
52-
camera?: boolean;
53-
microphone?: boolean;
54-
geolocation?: boolean;
55-
};
5651
}
5752

5853
export interface ToolCallInfo {
@@ -115,16 +110,15 @@ async function getUiResource(serverInfo: ServerInfo, uri: string): Promise<UiRes
115110

116111
const html = "blob" in content ? atob(content.blob) : content.text;
117112

118-
// Extract CSP and permissions metadata from resource content._meta.ui (or content.meta for Python SDK)
113+
// Extract CSP metadata from resource content._meta.ui.csp (or content.meta for Python SDK)
119114
log.info("Resource content keys:", Object.keys(content));
120115
log.info("Resource content._meta:", (content as any)._meta);
121116

122117
// Try both _meta (spec) and meta (Python SDK quirk)
123118
const contentMeta = (content as any)._meta || (content as any).meta;
124119
const csp = contentMeta?.ui?.csp;
125-
const permissions = contentMeta?.ui?.permissions;
126120

127-
return { html, csp, permissions };
121+
return { html, csp };
128122
}
129123

130124

@@ -179,10 +173,10 @@ export async function initializeApp(
179173
new PostMessageTransport(iframe.contentWindow!, iframe.contentWindow!),
180174
);
181175

182-
// Load inner iframe HTML with CSP and permissions metadata
183-
const { html, csp, permissions } = await appResourcePromise;
184-
log.info("Sending UI resource HTML to MCP App", csp ? `(CSP: ${JSON.stringify(csp)})` : "", permissions ? `(Permissions: ${JSON.stringify(permissions)})` : "");
185-
await appBridge.sendSandboxResourceReady({ html, csp, permissions });
176+
// Load inner iframe HTML with CSP metadata
177+
const { html, csp } = await appResourcePromise;
178+
log.info("Sending UI resource HTML to MCP App", csp ? `(CSP: ${JSON.stringify(csp)})` : "");
179+
await appBridge.sendSandboxResourceReady({ html, csp });
186180

187181
// Wait for inner iframe to be ready
188182
log.info("Waiting for MCP App to initialize...");

examples/basic-host/src/sandbox.ts

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -66,22 +66,6 @@ const PROXY_READY_NOTIFICATION: McpUiSandboxProxyReadyNotification["method"] =
6666
// Security: CSP is enforced via HTTP headers on sandbox.html (set by serve.ts
6767
// based on ?csp= query param). This is tamper-proof unlike meta tags.
6868

69-
// Build iframe allow attribute from permissions (camera, microphone, geolocation)
70-
function buildAllowAttribute(permissions?: {
71-
camera?: boolean;
72-
microphone?: boolean;
73-
geolocation?: boolean;
74-
}): string {
75-
if (!permissions) return "";
76-
77-
const allowList: string[] = [];
78-
if (permissions.camera) allowList.push("camera");
79-
if (permissions.microphone) allowList.push("microphone");
80-
if (permissions.geolocation) allowList.push("geolocation");
81-
82-
return allowList.join("; ");
83-
}
84-
8569
window.addEventListener("message", async (event) => {
8670
if (event.source === window.parent) {
8771
// Validate that messages from parent come from the expected host origin.
@@ -97,16 +81,10 @@ window.addEventListener("message", async (event) => {
9781
}
9882

9983
if (event.data && event.data.method === RESOURCE_READY_NOTIFICATION) {
100-
const { html, sandbox, permissions } = event.data.params;
84+
const { html, sandbox } = event.data.params;
10185
if (typeof sandbox === "string") {
10286
inner.setAttribute("sandbox", sandbox);
10387
}
104-
// Set Permission Policy allow attribute if permissions are requested
105-
const allowAttribute = buildAllowAttribute(permissions);
106-
if (allowAttribute) {
107-
console.log("[Sandbox] Setting allow attribute:", allowAttribute);
108-
inner.setAttribute("allow", allowAttribute);
109-
}
11088
if (typeof html === "string") {
11189
// Use document.write instead of srcdoc for WebGL compatibility.
11290
// srcdoc creates an opaque origin which prevents WebGL canvas updates

0 commit comments

Comments
 (0)