- CLAUDE.md: Server instructions and service reference - docs/: Persistent documentation (architecture, guides) - .artifacts/: Session-generated notes - playwriter-browser/: Remote browser container config Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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
- Create a new Docker Compose service in Coolify
- Paste the contents of
docker-compose.yml - Deploy
Option 2: Direct Docker Compose
# 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
- Access noVNC at
http://192.168.1.3:6081/vnc.html - Install Playwriter extension from Chrome Web Store: https://chromewebstore.google.com/detail/playwriter-mcp/jfeammnjpkecdekppnclgkkffahnhfhe
- Navigate to any website (e.g., google.com)
- Click the Playwriter extension icon to activate (turns green)
- 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.
# 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:
{
"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:
{
"playwriter-local": {
"command": "npx",
"args": ["playwriter"]
}
}
Chrome DevTools MCP (Alternative)
For performance analysis and debugging:
{
"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
- Access noVNC:
http://192.168.1.3:6081/vnc.html - Navigate to website and log in normally
- Allow Chrome to save password when prompted
- Sessions persist across container restarts
Usage Examples
Via Playwriter MCP
// 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
docker logs playwriter-browser
docker exec playwriter-browser pgrep -la chrome
Reset Chrome profile (lose all logins)
docker compose down
docker volume rm playwriter-chrome-profile playwriter-browser-keyring playwriter-browser-sessions
docker compose up -d
Backup browser profile
# 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)