- 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>
220 lines
7.2 KiB
Markdown
220 lines
7.2 KiB
Markdown
# 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)
|