Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save statico/0a51e99b7af78a58cd56a1021882675b to your computer and use it in GitHub Desktop.

Select an option

Save statico/0a51e99b7af78a58cd56a1021882675b to your computer and use it in GitHub Desktop.
Playwright MCP + Claude Code + nono.sh Sandbox (macOS)

Playwright MCP + Claude Code + nono.sh Sandbox (macOS)

Problem

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.

Solution

Run the Playwright MCP server outside the sandbox and connect to it over SSE.

1. Install Playwright browsers (outside the sandbox)

npx playwright install chromium
# or: npx playwright install chrome firefox

Browsers cache to ~/Library/Caches/ms-playwright/.

2. Start the Playwright MCP server (outside the sandbox)

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 (or firefox, chromium, webkit)
  • --port 8931: serve over HTTP/SSE instead of stdio

3. Register the MCP server with Claude Code

claude mcp add --transport sse playwright http://localhost:8931/sse

4. Start Claude Code inside nono

nono run --allow ~/Library/Caches/ms-playwright -- claude

The --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).

5. Verify

Inside Claude Code, the Playwright tools should appear automatically. Test with:

navigate to https://example.com and take a snapshot

Why this works

  • 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

Why claude mcp add with stdio doesn't work

# This does NOT work:
claude mcp add playwright -- npx @playwright/mcp@latest --browser chrome

With 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.

Key takeaway

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.

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