Browsers cannot launch inside nono.sh sandboxes on macOS. The Seatbelt
kernel sandbox blocks Mach IPC (bootstrap_check_in) and xattr syscalls that browsers
require for multi-process communication.
What we tested:
| Browser | Failure | Root Cause |
|---|---|---|
| Firefox (Playwright bundled) | Hangs forever | bootstrap_check_in Mach IPC blocked |
Chrome (system /Applications) |
SIGSEGV | xattr on ~/Library/Application Support/Google/Chrome/Crashpad blocked |
| Chromium (Playwright bundled) | Version mismatch / would crash | Same Mach IPC issues |
Disabling the browser's internal sandbox (--no-sandbox, security.sandbox.content.level=0,
MOZ_DISABLE_*_SANDBOX=1) does not help — the outer nono Seatbelt sandbox is what blocks
the operations.
Run the Playwright MCP server outside the sandbox and connect to it over SSE.
npx playwright install chromium
# or: npx playwright install chrome firefoxBrowsers cache to ~/Library/Caches/ms-playwright/.
In a regular terminal (not inside nono):
npx @playwright/mcp@latest --headless --isolated --browser chrome --port 8931--headless: no visible browser window--isolated: fresh session per connection (no shared cookies/state)--browser chrome: use system Chrome (orfirefox,chromium,webkit)--port 8931: serve over HTTP/SSE instead of stdio
claude mcp add --transport sse playwright http://localhost:8931/ssenono run --allow ~/Library/Caches/ms-playwright -- claudeThe --allow flag gives read access to browser caches (may not be strictly necessary since
the MCP server runs outside the sandbox, but doesn't hurt).
Inside Claude Code, the Playwright tools should appear automatically. Test with:
navigate to https://example.com and take a snapshot
- The MCP server spawns browser processes outside the sandbox — no Seatbelt restrictions
- Claude Code communicates with the MCP server over HTTP/SSE on localhost — just network I/O, which nono allows
- All browser automation tools (navigate, click, fill, screenshot, snapshot, etc.) work transparently
# This does NOT work:
claude mcp add playwright -- npx @playwright/mcp@latest --browser chromeWith stdio transport, Claude Code spawns the MCP server as a child process. Since Claude Code runs inside nono, the MCP server inherits the sandbox — and the browser fails to launch with the same errors. The SSE transport avoids this because the MCP server is a separate, unsandboxed process.
Any tool that spawns browsers (Playwright, Puppeteer, Selenium) will fail inside Seatbelt sandboxes. The pattern of running the browser-spawning server outside the sandbox and connecting over a network protocol applies generally.