# π§ TabPilot
Drive the real Chrome you are already logged into β on macOS, Windows, and Headless Ubuntu 24/7.
---
Most browser MCP servers launch a **fresh, blank browser instance**. That works for scraping static pages, but fails completely on tasks that matter:
- π« **Cloudflare & Bot Shields** immediately flag fresh automation browsers.
- π« **Corporate SSO, Okta, & 2FA** make authenticating from scratch painful or impossible.
- π« **Read-only tab viewers** can only *look* at DOM text, not click or fill forms.
**TabPilot bridges this gap.** It attaches directly to your **existing, logged-in Google Chrome**. Your AI agents (Claude, Cursor, Antigravity, Cline) can read pages with up to **99% token savings**, click elements with authentic mouse events (`isTrusted: true`), defeat React state caching traps, solve multi-row survey grids, and capture background screenshots without stealing window focus.
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β YOUR WORKSPACE TABPILOT MCP ENGINE REAL BROWSER β
β β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββ ββββββββββββββββ β
β β AI Agents β β TabPilot MCP Server β β Real Chrome β β
β β - Claude Desktop β stdio / β - Token Budget Slicerβ CDP β - Active SSO β β
β β - Cursor IDE β βββββββ> β - Native Form Settersβββββ> β - Cookies β β
β β - Antigravity/Gemini β SSH β - Matrix Grid Driver β<ββββ β - 2FA Saved β β
β β - Cline / Windsurf β β - Dual CDP/AppleScr. β β - Real Fingerβ β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββ ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
---
## β‘ Quick Start
### 1. Test your environment in one command
Run `tabpilot doctor` via `uvx` (no installation required):
```bash
uvx tabpilot-mcp doctor
```
*(Or install via pip: `pip install tabpilot-mcp`)*
### 2. Configure your MCP Client
Add to `claude_desktop_config.json` or `.cursor/mcp.json`:
```json
{
"mcpServers": {
"tabpilot": {
"command": "uvx",
"args": ["tabpilot-mcp"]
}
}
}
```
### 3. Launch Chrome with Remote Debugging
Quit Chrome completely, then start it pointing to your persistent automation profile:
```bash
# macOS
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--remote-debugging-port=9222 --user-data-dir="$HOME/tabpilot-chrome"
# Linux
google-chrome --remote-debugging-port=9222 --user-data-dir="$HOME/tabpilot-chrome"
# Windows
taskkill /F /IM chrome.exe
"C:\Program Files\Google\Chrome\Application\chrome.exe" ^
--remote-debugging-port=9222 --user-data-dir="%USERPROFILE%\tabpilot-chrome"
```
> [!IMPORTANT]
> **π macOS Zero-Config Fallback:**
> On macOS, if you do not launch Chrome with debugging flags, TabPilot automatically falls back to AppleScript to drive the Chrome you already have open.
> **Prerequisite:** In Google Chrome, go to **View β Developer β check "Allow JavaScript from Apple Events"**.
---
## π° How TabPilot Saves 90%+ Tokens
Naive browser automation dumps `document.body.innerText` or raw HTML, wasting 15,000β45,000 tokens on navigation bars, cookies banners, and tracking scripts.
TabPilot provides **Progressive Token Slicing**:
```
Raw Page Dump (eval_js body) ββββββββββββββββββββββββββββββββββββββ 18,000+ tokens
read_tab() (Link-Density) ββββββββββββββββββββββββββββββββββββββ ~1,200 tokens (93% saved)
read_tab(selector) ββββββββββββββββββββββββββββββββββββββ ~350 tokens (98% saved)
query_dom(selector) β ~18 tokens (99.9% saved)
```
| Method | Tokens | Savings | Best For |
| :--- | :---: | :---: | :--- |
| **`query_dom(selector)`** | **~15β30** | **99.9%** | Checking button states (`disabled`), inputs, badges, or alerts |
| **`read_tab(selector)`** | **~300β600** | **98.0%** | Reading isolated articles, ticket cards, or form sections |
| **`read_tab()`** *(Link-Density)* | **~1,200β1,800** | **93.0%** | Full-page reads with nav, ads, headers, and footers stripped |
| β *Naive `eval_js` innerText* | 15,000β35,000 | 0% | *Context budget incinerator* |
> π‘ **Enforced Character Budget:** Reads default to `--max-chars 20000`. If truncated, TabPilot alerts the model with exact cut sizes, prompting it to narrow down with `selector` instead of hallucinating.
---
## π₯ Driving Forms That Fight Back
Modern Single-Page Applications (React, Vue, Svelte) defeat standard automation scripts. TabPilot solves the 3 most infamous SPA traps:
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TRAP 1: React Synthetic Cache β
β Standard `.value = 'x'` is ignored by React's internal tracker. β
β β
TabPilot calls native property setters + fires both `input` and `change`. β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β TRAP 2: Multi-Row Survey Grid Batching β
β Clicking 25 matrix rows in one JS tick causes React to commit only the last row. β
β β
`fill_matrix` clicks row-by-row across microtasks with delays, then confirms. β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β TRAP 3: Virtual Portals (React-Select, Headless UI) β
β No `