fovea-web
by lubdhak7414
README.md
# Fovea Web
Cross-browser **MCP server + Manifest V3 extension** for **mobile-first layout auditing** and browser automation. The only MCP that thinks like a responsive QA, not just a click-bot.
## Architecture
```
AI Harness <--(Stdio/MCP)--> MCP Server <--(WebSocket :8080)--> Extension Background Worker <--(CDP/DOM)--> Web Page
keeps login (extension) vs disposable profile (Playwright)
```
## Why Fovea Web vs Playwright / chrome-devtools-mcp / BrowserTools
| Feature | Fovea Web | Playwright MCP (52 tools) | chrome-devtools-mcp (57) | BrowserTools (16) |
|---|---|---|---|---|
| **Mobile audit** (overflow, viewport, tap targets) | ✅ `audit_responsive` + `screenshot_matrix` | ❌ only `resize` | ❌ only `emulate` | ❌ |
| Touch `swipe` | ✅ `swipe` | ❌ mouse only | ❌ | ❌ |
| VisualViewport + safe-area | ✅ `get_viewport_metrics` | ❌ | ❌ | ❌ |
| Media query introspection | ✅ `get_media_queries` | ❌ | ❌ | ❌ |
| Keeps logged-in session | ✅ extension | ❌ isolated profile | ❌ | ✅ read-only |
## 🚀 Quick Start
### 1. Build
```bash
npm install
npm run build
```
### 2. Load Extension
* **Chrome / Brave / Edge:** `chrome://extensions` → Developer Mode → **Load unpacked** → `dist/extension`
* **Firefox:** `about:debugging#/runtime/this-firefox` → Load Temporary Add-on → `dist/extension/manifest.firefox.json`
Popup shows **● Connected** / **○ Disconnected**, active tabs, and a one-click **Audit This Page** checker.
### 3. Connect to AI Harness
Add to `mcp.json`:
```json
{
"mcpServers": {
"fovea-web": {
"command": "node",
"args": ["/path/to/fovea-web/dist/server/index.js"],
"env": { "WS_PORT": "8080" }
}
}
}
```
Or use the included `.mcp.json`.
## Tools (16)
| Tool | Description |
|------|-------------|
| `capture_mobile_layout` | Emulate 8 presets (SE/14/Pro Max/Pixel/iPad/Desktop/HD/Custom) + DPR/touch/UA, full-page screenshot or `convertToText` |
| `get_accessibility_tree` | Chrome a11y tree via CDP |
| `click_element` | CSS/XPath click |
| `scroll_page` | up/down/top/bottom |
| **`navigate`** | Navigate active tab, wait for load |
| **`type_text`** | Real keystrokes into inputs (clear/submit/delay) |
| **`press_key`** | `Enter`/`Escape`/`Arrow*` + modifiers |
| **`hover_element`** | Hover to open menus |
| **`evaluate_js`** | Run JS in page, return JSON |
| **`get_console_logs`** | Buffered console (log/warn/error) |
| **`get_viewport_metrics`** | inner/outer/visualViewport/DPR/scrollWidth/safeArea/meta viewport |
| **`get_media_queries`** | List media queries + `matches` |
| **`audit_responsive`** | ⭐ Cycle 5 viewports, detect `HORIZONTAL_OVERFLOW`/`MISSING_VIEWPORT`/`FIXED_WIDTH_OVERFLOW`/`SMALL_TAP_TARGET`, markdown + JSON |
| **`screenshot_matrix`** | ⭐ One-call screenshots across `N` devices |
| `swipe` | Touch swipe (up/down/left/right) |
| `tabs` | list/create/close tabs |
### Example — responsive audit
Ask your LLM: *"audit responsive layout for this page, include screenshots"* → calls `audit_responsive{devices:[iPhone_SE, Pixel_7, Desktop], includeScreenshots:true}` → returns:
```markdown
# Responsive Audit — https://example.com
_2025-08-20_ — ❌ FAIL — 2 errors, 1 warnings
| Viewport | Overflow | Issues |
| iPhone_SE (375px) | ⚠️ YES | 2 |
## iPhone_SE — 2 issue(s)
- 🔴 HORIZONTAL_OVERFLOW document — scrollWidth 412px > viewport 375px
- 🔴 FIXED_WIDTH_OVERFLOW div.hero — width 400px > viewport 375px
```
## Project Structure
```
fovea-web/
├── src/
│ ├── protocol.ts # WS wire + 8 device presets + ViewportMetrics/AuditResult
│ ├── tools.ts # Zod schemas for 16 tools
│ ├── ws-bridge.ts # WS server :8080 with req_id timeout map
│ ├── layout-analyzer.ts # analyzeLayout + auditBreakpoint + formatAuditAsMarkdown
│ └── mcp-server.ts # 16 MCP tools via stdio
├── extension/
│ ├── manifest.json # MV3 + alarms keep-alive (Fovea Web)
│ ├── background.ts # CDP + scripting + audit orchestration + badge
│ ├── content.ts # console hook + viewport/media/audit snapshot
│ ├── popup.html/ts # status + tabs + quick audit
│ └── manifest.firefox.json
└── tests/
├── mcp-server.test.ts
└── layout-analyzer.test.ts
```
## Testing
```bash
npm test # vitest
npm run lint # tsc --noEmit
npm run build # esbuild -> dist/
```
## Env
See `.env.example`. `WS_PORT` defaults to `8080`. Extension uses `chrome.alarms` keep-alive to survive MV3 idle.
## Roadmap
- [x] Device matrix + touch + viewport + media introspection
- [x] Audit + matrix (differentiators)
- [ ] Network throttling (`slow4g`/`cpu4x`), Lighthouse-mobile
- [ ] Visual regression store + diff threshold
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues