Skip to content

threejs-server example cannot work within current spec due to unsafe-eval #199

Open

Description

@connor4312

Describe the bug

The three.js app uses this code:

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

- **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:

```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:

  1. Build a complient client with CSP policies
  2. Try to run the threejs example

You get an error:

Image

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

  1. changed the title [-]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)[/+] on Jan 4, 2026
  2. changed the title [-]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`[/+] on Jan 4, 2026
  3. connor4312 commented on Jan 7, 2026

    @connor4312
    Author

    Reposting from Discord findings:

    This demo only works in the basic-host because the basic-host's sandbox CSP is overly permissive

    const csp = [
    "default-src 'self'",
    "img-src * data: blob: 'unsafe-inline'",
    "style-src * blob: data: 'unsafe-inline'",
    "script-src * blob: data: 'unsafe-inline' 'unsafe-eval'",
    "connect-src *",
    "font-src * blob: data:",
    "media-src * blob: data:",
    "frame-src * blob: data:",
    ].join("; ");

    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

  4. ochafik commented on Jan 12, 2026

    @ochafik
    Contributor

    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?

  5. connor4312 commented on Jan 12, 2026

    @connor4312
    Author

    Trusted type policies are the best way to do this. We should allow the server to set those imo.

  6. idosal commented on Jan 12, 2026

    @idosal
    Contributor

    Trusted type policies are the best way to do this. We should allow the server to set those imo.

    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 !

  7. healthkowshik commented on Feb 17, 2026

    @healthkowshik

    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

    Image
  8. ochafik commented on Apr 21, 2026

    @ochafik
    Contributor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions