# Playwriter Browser Container A persistent browser container running on the NUC for AI-driven browser automation via Playwriter MCP. ## Purpose Provides an always-available browser for Claude/AI agents to: - Navigate websites and perform web tasks - Fill forms, click buttons, extract data - Debug web applications - Access services that require browser interaction - Eliminate need for local browser resources ## Architecture ``` ┌─────────────────────────────────────────────────────────┐ │ NUC Server │ │ ┌─────────────────────────────────────────────────┐ │ │ │ playwriter-browser container │ │ │ │ │ │ │ │ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │ │ │ │ │ Xvfb │ │ Chrome │ │ Playwriter │ │ │ │ │ │ :99 │ │ +ext │ │ Relay │ │ │ │ │ └──────────┘ └──────────┘ └───────────────┘ │ │ │ │ │ │ │ │ │ │ │ ┌──────────┐ │ ws://19988 │ │ │ │ │ x11vnc │ │ │ │ │ │ │ :5901 │ CDP://9222 │ │ │ │ └──────────┘ │ │ │ │ │ │ │ │ │ ┌──────────┐ │ │ │ │ │ noVNC │ │ │ │ │ │ :6081 │ │ │ │ │ └──────────┘ │ │ │ └─────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ │ │ │ ▼ ▼ ▼ Web Browser DevTools MCP Playwriter MCP (manual) (AI agent) (AI agent) ``` ## Ports | Port | Service | Purpose | |------|---------|---------| | 5901 | VNC | Direct VNC client access | | 6081 | noVNC | Web-based browser view | | 19988 | Playwriter | MCP WebSocket relay | | 9222 | CDP | Chrome DevTools Protocol | ## Deployment to NUC ### Option 1: Via Coolify 1. Create a new Docker Compose service in Coolify 2. Paste the contents of `docker-compose.yml` 3. Deploy ### Option 2: Direct Docker Compose ```bash # Copy files to NUC scp -r playwriter-browser nuc:/opt/ # SSH to NUC and deploy ssh nuc cd /opt/playwriter-browser docker compose up -d ``` ## First-Time Setup 1. Access noVNC at `http://192.168.1.3:6081/vnc.html` 2. Install Playwriter extension from Chrome Web Store: https://chromewebstore.google.com/detail/playwriter-mcp/jfeammnjpkecdekppnclgkkffahnhfhe 3. Navigate to any website (e.g., google.com) 4. Click the Playwriter extension icon to activate (turns green) 5. The extension stays active until container restart ## Auto-Activation Attempt The container includes an auto-activation script that tries to click the extension icon using xdotool. However, due to security design, this may not always work. Manual activation via noVNC is the reliable method. ```bash # Run auto-activation manually docker exec playwriter-browser /app/auto-activate.sh ``` ## MCP Configuration ### Remote Connection (Recommended) Configure Claude Code to use NUC's browser remotely: ```json { "playwriter": { "command": "npx", "args": ["playwriter", "--host", "ws://192.168.1.3:19988", "--token", "nuc-browser-token"] } } ``` This connects to the NUC browser container, eliminating local resource usage. ### Keep Local Browser Option If you also want local browser control: ```json { "playwriter-local": { "command": "npx", "args": ["playwriter"] } } ``` ### Chrome DevTools MCP (Alternative) For performance analysis and debugging: ```json { "chrome-devtools": { "command": "npx", "args": ["chrome-devtools-mcp@latest"] } } ``` ## Environment Variables | Variable | Default | Description | |----------|---------|-------------| | `PLAYWRITER_TOKEN` | `nuc-browser-token` | Auth token for remote connections | ## Session Persistence The container persists browser state across restarts using Docker volumes: | Volume | Path | Purpose | |--------|------|---------| | `playwriter-chrome-profile` | `/root/.config/google-chrome` | Full Chrome profile (cookies, localStorage, passwords, bookmarks) | | `playwriter-browser-keyring` | `/root/.local/share/keyrings` | Encrypted credentials via gnome-keyring | | `playwriter-browser-sessions` | `/root/.config/google-chrome/Default/Sessions` | Browser session tabs | ### What's Persisted - **Login sessions**: Stay logged into websites (Google, GitHub, etc.) - **Cookies**: Session cookies, preferences - **Passwords**: Chrome password manager entries (encrypted via gnome-keyring) - **localStorage/IndexedDB**: Web app data - **Extensions**: Installed extensions including Playwriter - **Bookmarks**: Any saved bookmarks ### First Login via noVNC 1. Access noVNC: `http://192.168.1.3:6081/vnc.html` 2. Navigate to website and log in normally 3. Allow Chrome to save password when prompted 4. Sessions persist across container restarts ## Usage Examples ### Via Playwriter MCP ```javascript // Navigate to a page await page.goto('https://example.com'); // Get page state console.log(await accessibilitySnapshot({ page })); // Interact with elements await page.locator('aria-ref=e5').click(); // Take screenshot await page.screenshot({ path: '/tmp/shot.png', scale: 'css' }); ``` ### Via Chrome DevTools MCP ``` "Check the LCP of https://example.com" "Analyze network requests on this page" "Find console errors" ``` ## Troubleshooting ### Extension not activated Access noVNC and click the Playwriter extension icon manually. ### Container unhealthy ```bash docker logs playwriter-browser docker exec playwriter-browser pgrep -la chrome ``` ### Reset Chrome profile (lose all logins) ```bash docker compose down docker volume rm playwriter-chrome-profile playwriter-browser-keyring playwriter-browser-sessions docker compose up -d ``` ### Backup browser profile ```bash # Create backup of logged-in sessions docker run --rm -v playwriter-chrome-profile:/data -v $(pwd):/backup alpine tar czf /backup/chrome-profile-backup.tar.gz -C /data . ``` ## Security Notes - Playwriter requires explicit activation per tab (security by design) - Only tabs where extension is activated can be controlled - WebSocket relay only accepts localhost connections - VNC has no password (internal network only)