feat: add wasm-unsafe-eval CSP option#667
Conversation
📖 Docs Preview Deployed
Includes drafts and future-dated posts. All pages served with |
@modelcontextprotocol/ext-apps
@modelcontextprotocol/server-basic-preact
@modelcontextprotocol/server-basic-react
@modelcontextprotocol/server-basic-solid
@modelcontextprotocol/server-basic-svelte
@modelcontextprotocol/server-basic-vanillajs
@modelcontextprotocol/server-basic-vue
@modelcontextprotocol/server-budget-allocator
@modelcontextprotocol/server-cohort-heatmap
@modelcontextprotocol/server-customer-segmentation
@modelcontextprotocol/server-debug
@modelcontextprotocol/server-map
@modelcontextprotocol/server-pdf
@modelcontextprotocol/server-scenario-modeler
@modelcontextprotocol/server-shadertoy
@modelcontextprotocol/server-sheet-music
@modelcontextprotocol/server-system-monitor
@modelcontextprotocol/server-threejs
@modelcontextprotocol/server-transcript
@modelcontextprotocol/server-video-resource
@modelcontextprotocol/server-wiki-explorer
commit: |
There was a problem hiding this comment.
Pull request overview
This PR adds an explicit wasmUnsafeEval boolean to the UI CSP metadata (_meta.ui.csp / McpUiResourceCsp) so hosts can selectively allow WebAssembly compilation via the CSP script-src source expression 'wasm-unsafe-eval'. It also updates the published spec examples accordingly and refactors the examples/basic-host CSP logic into a reusable helper with basic unit tests.
Changes:
- Add
wasmUnsafeEval?: booleantoMcpUiResourceCspand regenerate the TypeScript/Zod/JSON schemas. - Update Apps specification examples to show mapping
wasmUnsafeEval→'wasm-unsafe-eval'inscript-src. - Extract
examples/basic-hostCSP building intosrc/csp.tsand add tests around the new option.
Reviewed changes
Copilot reviewed 6 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/spec.types.ts | Adds wasmUnsafeEval to the CSP metadata type and documents mapping to 'wasm-unsafe-eval'. |
| src/generated/schema.ts | Regenerates Zod schema to include optional wasmUnsafeEval. |
| src/generated/schema.json | Regenerates JSON schema to include optional wasmUnsafeEval. |
| specification/draft/apps.mdx | Updates draft spec CSP interface + reference CSP construction example to include wasmUnsafeEval. |
| specification/2026-01-26/apps.mdx | Updates versioned spec CSP interface + example to include wasmUnsafeEval. |
| examples/basic-host/src/csp.ts | New helper to build CSP headers (adds 'wasm-unsafe-eval' when requested). |
| examples/basic-host/test/csp.test.ts | Adds unit tests verifying 'wasm-unsafe-eval' is included/omitted based on wasmUnsafeEval. |
| examples/basic-host/serve.ts | Refactors server to import and use the extracted buildCspHeader helper. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| function sanitizeCspDomains(domains?: string[]): string[] { | ||
| if (!domains) return []; | ||
| return domains.filter((d) => typeof d === "string" && !/[;\r\n'" ]/.test(d)); | ||
| } |
| const scriptSources = [ | ||
| "'self'", | ||
| "'unsafe-inline'", | ||
| "'unsafe-eval'", | ||
| ...(csp?.wasmUnsafeEval === true ? ["'wasm-unsafe-eval'"] : []), | ||
| "blob:", | ||
| "data:", | ||
| ].join(" "); |
| const wasmUnsafeEval = csp?.wasmUnsafeEval ? "'wasm-unsafe-eval'" : ""; | ||
|
|
||
| const cspValue = ` | ||
| default-src 'none'; | ||
| script-src 'self' 'unsafe-inline' ${csp?.resourceDomains?.join(' ') || ''}; | ||
| script-src 'self' 'unsafe-inline' ${wasmUnsafeEval} ${csp?.resourceDomains?.join(' ') || ''}; | ||
| style-src 'self' 'unsafe-inline' ${csp?.resourceDomains?.join(' ') || ''}; |
| const wasmUnsafeEval = csp?.wasmUnsafeEval ? "'wasm-unsafe-eval'" : ""; | ||
|
|
||
| const cspValue = ` | ||
| default-src 'none'; | ||
| script-src 'self' 'unsafe-inline' ${csp?.resourceDomains?.join(' ') || ''}; | ||
| script-src 'self' 'unsafe-inline' ${wasmUnsafeEval} ${csp?.resourceDomains?.join(' ') || ''}; | ||
| style-src 'self' 'unsafe-inline' ${csp?.resourceDomains?.join(' ') || ''}; |
| * @description Whether the UI requires WebAssembly compilation. | ||
| * | ||
| * - Maps to the CSP `script-src` source expression `'wasm-unsafe-eval'` | ||
| * - Empty or false → WebAssembly compilation remains blocked by default |
Summary
wasmUnsafeEvaloption to_meta.ui.csp/McpUiResourceCspand regenerates the protocol schemas.script-srcsource expression'wasm-unsafe-eval'.This PR implements the conservative declarative path. If Hosts agree that
wasm-unsafe-evalis safe enough to include by default, we can simplify the spec.Fixes #605.
Test Plan
npm run generate:schemasnpm run buildbun test examples/basic-host/test/csp.test.tsnpm run --workspace examples/basic-host buildnpm testnpm run build:all(pre-commit)tsx:wasmUnsafeEval: trueadds'wasm-unsafe-eval'; omission preserves the existingscript-src.