SurfAgent — Real Chrome Browser Control
Give your AI agent a real, persistent Chrome browser. No headless browsers, no cloud, no bot detection issues.
When to Use
- You need to browse, scrape, or interact with a website
- You need to fill forms, click buttons, or navigate pages
- You need to extract structured data from web pages
- You need to take screenshots of websites
- You need persistent login sessions (already logged into sites)
- You need to bypass bot detection (Cloudflare, hCaptcha, etc.)
- You need to crawl/map a website
Prerequisites
- SurfAgent installed and running — download from surfagent.app
- MCP server connected —
hermes mcp add surfagent --command npx --args -y surfagent-mcp - Or use the HTTP API directly at
http://localhost:7201
Quick Reference — MCP Tools (24)
| Tool | What it does |
|---|---|
browser_navigate |
Open a URL |
browser_back |
Go back in history |
browser_forward |
Go forward in history |
browser_click |
Click an element (selector, text, or coordinates) |
browser_type |
Type text into an element |
browser_fill_form |
Fill multiple form fields at once |
browser_select |
Select dropdown option |
browser_scroll |
Scroll page or to element |
browser_screenshot |
Capture page screenshot (PNG) |
browser_get_text |
Get visible text content |
browser_get_html |
Get page HTML |
browser_get_url |
Get current URL |
browser_get_title |
Get page title |
browser_find_elements |
Find elements by CSS selector |
browser_evaluate |
Run JavaScript in page |
browser_wait |
Wait for element to appear |
browser_cookies |
Get or set cookies |
browser_list_tabs |
List open tabs |
browser_new_tab |
Open new tab |
browser_switch_tab |
Switch to tab by id/title |
browser_close_tab |
Close a tab |
browser_extract |
Extract structured data (markdown, JSON, links) |
browser_crawl |
BFS crawl a domain |
browser_map |
Discover all URLs on a site |
Procedure
Basic Navigation
- Use
browser_navigateto open a URL - Use
browser_screenshotto see the page - Use
browser_clickorbrowser_typeto interact - Use
browser_get_textto read content
Data Extraction
- Use
browser_extractwith a URL to get markdown + links - Add
promptandschemafields for LLM-powered structured extraction - Use
browser_crawlfor multi-page extraction - Use
browser_mapfor quick URL discovery
Form Filling
- Use
browser_navigateto go to the form page - Use
browser_fill_formwith field label/name → value mappings - Or use
browser_click+browser_typefor individual fields - Use
browser_selectfor dropdowns
Tab Management
- Use
browser_list_tabsto see what's open - Use
browser_new_tabto open a new tab - Use
browser_switch_tabto change focus - Use
browser_close_tabwhen done — always clean up tabs
Direct HTTP API (fallback)
If MCP isn't available, call the daemon directly:
# Navigate
curl -X POST http://localhost:7201/browser/navigate \
-H 'Content-Type: application/json' \
-d '{"url": "https://example.com"}'
# Screenshot
curl -s http://localhost:7201/browser/screenshot --output screenshot.png
# List tabs
curl -s http://localhost:7201/browser/tabs
# Extract page data
curl -X POST http://localhost:7201/browser/extract \
-H 'Content-Type: application/json' \
-d '{"url": "https://example.com", "formats": ["markdown", "links"]}'
Key Advantages
- Real Chrome — not headless, passes all bot detection
- Persistent sessions — log in once, stay logged in forever
- Real fingerprint — your actual Chrome installation, real cookies
- 100% local — no data leaves your machine
- 24 MCP tools — comprehensive browser control
- Extract + Crawl — Firecrawl-equivalent features, zero cloud cost
Pitfalls
- Always close tabs when done — leaving tabs open wastes resources
- Wait for dynamic content — SPAs need
browser_waitor a short delay after navigation - One operation at a time — don't fire multiple browser commands in parallel
- Screenshots are viewport-only by default — use the fullPage option for long pages
- Cookie consent banners — the daemon can auto-resolve them via
/browser/resolve-blocker
Verification
browser_get_urlreturns the expected URL after navigationbrowser_screenshotshows the expected page contentbrowser_get_textcontains the expected text- Health check:
curl http://localhost:7201/healthreturns{"ok": true}