TabPilot Banner

# 🧭 TabPilot

Drive the real Chrome you are already logged into β€” on macOS, Windows, and Headless Ubuntu 24/7.

PyPI Version PyPI Downloads CI Status tabpilot-mcp MCP server – quality and maintenance score on Glama MCP Compatible Python Versions License GitHub Stars

tabpilot-mcp MCP server – quality and maintenance score on Glama

--- 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 `` or Select2 dropdowns. - **`select_option_ui(control_selector, option_text)`**: Clicks trigger, waits for popup portal, and selects item. - **`wait_for(selector, state, text, timeout_ms)`**: Polls until condition holds (`visible`, `hidden`, `text`, `enabled`). ### πŸ“‹ Matrix Surveys & Evidence - **`scan_matrix(selector)`**: Discovers multi-row grid questions and flags unanswered rows. - **`fill_matrix(column_index, rows, delay_ms)`**: Answers matrix rows sequentially with task delays. - **`screenshot(full_page, selector, label)`**: Offscreen capture of any tab (local path or inline base64). - **`browser_status()`**: Reports active backend, capabilities, CDP endpoint, and open tab count. ### πŸ“¦ Live MCP Resources - `tab://active` β€” Markdown stream of the currently focused tab. - `tab://{tab_id}` β€” Markdown stream of any specific tab by ID. --- ## πŸ› οΈ CLI Reference ```bash tabpilot doctor # Run diagnostic suite (Chrome, CDP, fonts, permissions) tabpilot tabs # List open browser tabs in terminal tabpilot serve # Start MCP server on stdio # Linux Managed Stack Commands tabpilot install-stack # Install systemd user services tabpilot up / tabpilot down # Start or stop the headless stack tabpilot status # Check systemd stack status tabpilot logs chrome -f # Follow live Chrome logs ``` --- ## πŸ§ͺ Testing ```bash git clone https://github.com/hunglp97/tabpilot-mcp.git cd tabpilot-mcp python3 -m venv .venv source .venv/bin/activate pip install -e ".[dev]" # Unit tests (Zero browser needed) pytest -v # Live integration tests (against Chrome on port 9222) pytest -v -m live ``` --- ## πŸ“„ License Distributed under the **MIT License**. See [LICENSE](LICENSE) for details. ---

Built with ❀️ for AI Engineers, QA Automators, and Power Users who demand real browser agency.
Star ⭐ TabPilot on GitHub if it saved your agents from bot shields and token burn!