Repository navigation
Description
Describe the bug
The three.js app uses this code:
ext-apps/examples/threejs-server/src/threejs-app.tsx
Lines 122 to 137 in e514e6c
| async function executeThreeCode( | |
| code: string, | |
| canvas: HTMLCanvasElement, | |
| width: number, | |
| height: number, | |
| ): Promise<void> { | |
| const fn = new Function( | |
| "ctx", | |
| "canvas", | |
| "width", | |
| "height", | |
| `const { THREE, OrbitControls, EffectComposer, RenderPass, UnrealBloomPass } = ctx; | |
| return (async () => { ${code} })();`, | |
| ); | |
| await fn(threeContext, canvas, width, height); | |
| } |
This requires the unsafe-eval CSP policy. However, the server does not define a CSP policy and from my understanding of the spec it should not be provided by default
ext-apps/specification/draft/apps.mdx
Lines 202 to 211 in e514e6c
| - **Restrictive Default:** If `ui.csp` is omitted, Host MUST use: | |
| ``` | |
| default-src 'none'; | |
| script-src 'self' 'unsafe-inline'; | |
| style-src 'self' 'unsafe-inline'; | |
| img-src 'self' data:; | |
| media-src 'self' data:; | |
| connect-src 'none'; | |
| ``` |
Additionally, there is no way to make it work as the spec currently does not provide servers a way to request unsafe-eval:
ext-apps/specification/draft/apps.mdx
Lines 1411 to 1426 in e514e6c
| ```typescript | |
| const csp = resource._meta?.ui?.csp; | |
| const cspValue = ` | |
| default-src 'none'; | |
| script-src 'self' 'unsafe-inline'; | |
| style-src 'self' 'unsafe-inline'; | |
| connect-src 'self' ${csp?.connectDomains?.join(' ') || ''}; | |
| img-src 'self' data: ${csp?.resourceDomains?.join(' ') || ''}; | |
| font-src 'self' ${csp?.resourceDomains?.join(' ') || ''}; | |
| media-src 'self' data: ${csp?.resourceDomains?.join(' ') || ''}; | |
| frame-src 'none'; | |
| object-src 'none'; | |
| base-uri 'self'; | |
| `; | |
| ``` |
To Reproduce
Steps to reproduce the behavior:
- Build a complient client with CSP policies
- Try to run the threejs example
You get an error:
Expected behavior
I think the spec should be revised to support trusted types or let the UI request unsafe-eval
Logs
N/A
Additional context
N/A
Activity
[-]threejs-server example does not work with compliant CSP clients[/-][+]threejs-server example does not work with compliant CSP clients (and there is no way to make it work)[/+][-]threejs-server example does not work with compliant CSP clients (and there is no way to make it work)[/-][+]threejs-server example cannot work within current spec due to `unsafe-eval`[/+]connor4312 commentedon Jan 7, 2026
Reposting from Discord findings:
This demo only works in the
basic-hostbecause thebasic-host's sandbox CSP is overly permissiveext-apps/examples/basic-host/serve.ts
Lines 55 to 64 in e514e6c
If I update that actually match the spec https://github.com/modelcontextprotocol/ext-apps/blob/main/specification/draft/apps.mdx#4-content-security-policy-enforcement then I get the same failure there
ochafik commentedon Jan 12, 2026
Hey @connor4312, looks like an oversight, thanks for pointing it out!
I wonder if we should add a _meta.ui.csp.unsafeEval, or go deeper and introduce a way to inject nonces (e.g. from CallToolResult._meta)... @petery-ant, @idosal wdyt?
connor4312 commentedon Jan 12, 2026
Trusted type policies are the best way to do this. We should allow the server to set those imo.
idosal commentedon Jan 12, 2026
Sounds good. I think most people would automatically turn to unsafe-eval so we'd need to properly document this solution. I'll open a PR for it tomorrow and we can iterate over the proposal. Thanks @connor4312 !
healthkowshik commentedon Feb 17, 2026
Tried the newly available FastMCP support for apps and I am getting this error as well.
Ref: https://gofastmcp.com/apps/low-level#example-qr-code-server
feat(app): default Zod to jitless; add allowUnsafeEval opt-out
feat(app): default Zod to jitless; add allowUnsafeEval opt-out (#618)
ochafik commentedon Apr 21, 2026
v1.7.0 fixes the Zod half of this (#618 — jitless by default). The threejs example's own shader compiler still uses
new Function(); that needs trusted-types (#378) or the example-specific workaround in #432. Leaving open for the threejs-specific path.