| Filename | Latest commit message | Latest commit date |
|---|---|---|
* fix: Move CSP to HTTP headers + add worker-src, frameDomains, baseUriDomains, permissions Security improvements: - CSP is now set via HTTP headers in serve.ts instead of meta tags (meta tag CSP can be tampered with by same-origin content) - CSP passed as query param to sandbox.html for header-based enforcement New CSP/permissions features (borrowed from PR #158): - frameDomains: control frame-src directive for nested iframes - baseUriDomains: control base-uri directive - permissions: camera, microphone, geolocation via iframe allow attribute WebGL fix: - Use document.write() instead of srcdoc for inner iframe content (srcdoc creates opaque origin that breaks WebGL canvas updates) - Add worker-src directive with blob: support (critical for WebGL apps like CesiumJS/Three.js that use workers for tile decoding, terrain processing, image processing) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * 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> * cleanup McpUiResourceCsp type usage / duplicate defs * fix: guard against CSP injection in domain parameters Validate CSP domain entries to reject characters that could: - Break out of CSP directives (semicolons, newlines) - Inject CSP keywords like 'unsafe-eval' (quotes) - Inject multiple sources in one entry (spaces) This prevents injection attacks where malicious domains could override the security policy. --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> |
||
| .. | ||
| src | ||
| index.html | ||
| package.json | ||
| README.md | ||
| sandbox.html | ||
| serve.ts | ||
| tsconfig.json | ||
| vite.config.ts | ||
Example: Basic Host
A reference implementation showing how to build an MCP host application that connects to MCP servers and renders tool UIs in a secure sandbox.
This basic host can also be used to test MCP Apps during local development.
Key Files
index.html/src/index.tsx- React UI host with tool selection, parameter input, and iframe managementsandbox.html/src/sandbox.ts- Outer iframe proxy with security validation and bidirectional message relaysrc/implementation.ts- Core logic: server connection, tool calling, and AppBridge setup
Getting Started
npm install
npm run start
# Open http://localhost:8080
By default, the host application will try to connect to an MCP server at http://localhost:3001/mcp. You can configure this behavior by setting the SERVERS environment variable with a JSON array of server URLs:
SERVERS='["http://localhost:1234/mcp", "http://localhost:5678/mcp"]' npm run start
Architecture
This example uses a double-iframe sandbox pattern for secure UI isolation:
Host (port 8080)
└── Outer iframe (port 8081) - sandbox proxy
└── Inner iframe (srcdoc) - untrusted tool UI
Why two iframes?
- The outer iframe runs on a separate origin (port 8081) preventing direct access to the host
- The inner iframe receives HTML via
srcdocand is restricted by sandbox attributes - Messages flow through the outer iframe which validates and relays them bidirectionally
This architecture ensures that even if tool UI code is malicious, it cannot access the host application's DOM, cookies, or JavaScript context.