“Refused to load the script”
The host built the iframe's CSP from the view's _meta.ui.csp, and the view asked for something from an origin that list does not allow; the browser blocked it. The three common causes: (1) The origin is not declared: resourceDomains for scripts, styles, images and fonts; connectDomains for fetch and WebSocket; frameDomains for iframes. With no _meta.ui.csp at all the host applies a default that allows nothing external. To tell: The doctor fails at resource-csp-undeclared (or warns at resource-csp-connect) and names the origin and the list it belongs in. (2) The CSP is declared where this host does not read it: only under _meta["openai/widgetCSP"] (ChatGPT's legacy key), or only on the resources/list entry and not on the resources/read content. To tell: The doctor warns at resource-legacy-csp or resource-meta-location. (3) The host does not apply a list you did declare: claude.ai's sandbox was seen dropping resourceDomains, so declared external images showed broken. To tell: The doctor passes, the origin is declared, and the block happens in one host only. One command shows which: npx --allow-git=root github:agentwares/mcp-apps-doctor https://your-server.example/mcp.
Check your server now
npx --allow-git=root github:agentwares/mcp-apps-doctor https://your-server.example/mcp
Discovery only: no credential, no tool called. It prints the first broken step, whose it is, and the fix with its source, and shows the view in a sandboxed preview.
Who prints it
The browser, in the view's iframe console: `Refused to load the script '…' because it violates the following Content Security Policy directive: "script-src …"`.
The three causes, and how to tell them apart
- Cause 1. The origin is not declared: resourceDomains for scripts, styles, images and fonts; connectDomains for fetch and WebSocket; frameDomains for iframes. With no _meta.ui.csp at all the host applies a default that allows nothing external.
The check flags it atresource-csp-undeclared. The doctor fails at resource-csp-undeclared (or warns at resource-csp-connect) and names the origin and the list it belongs in. - Cause 2. The CSP is declared where this host does not read it: only under _meta["openai/widgetCSP"] (ChatGPT's legacy key), or only on the resources/list entry and not on the resources/read content.
The check flags it atresource-legacy-csp. The doctor warns at resource-legacy-csp or resource-meta-location. - Cause 3. The host does not apply a list you did declare: claude.ai's sandbox was seen dropping resourceDomains, so declared external images showed broken.
The check cannot see this one from outside: it happens inside the host or the portal. The doctor passes, the origin is declared, and the block happens in one host only.
Sources and public reports
- hosts MUST construct the CSP from the declared domains, and MUST NOT allow undeclared ones [source: MCP Apps spec 2026-01-26, UI Resource Format, read 8 October 2026]
- by default the frame only runs scripts that are inline or from its own origin [source: Claude, Add an interactive UI to your MCP server, read 8 October 2026]
- claude.ai's sandbox proxy did not apply resourceDomains [observed in modelcontextprotocol/ext-apps#761, opened 28 August 2026]
Keep checking
Other messages
- “MCP App renders blank”
- “Resource not found: ui://”
- “Tool has no UI”
- “Invalid ui.domain format”
- “ui.domain mismatch”
- “annotations_required”
- “domain_verification_required”
- “frame_domain_explanation_required”
- “screenshots_not_allowed”
- “Failed to fetch template”
Written 8 October 2026 from the sources above. The MCP Apps check · MCP Liveness · Terms · Privacy