google-surf-mcp
This server provides Google search and web content extraction without requiring an API key, using a persistent Chrome profile with stealth capabilities.
search(query, limit?)– Run a single Google search and get title, URL, and snippet for up to 20 results.search_parallel(queries[], limit?)– Execute up to 10 queries simultaneously using a pool of 4 concurrent workers, returning title/URL/snippet per result.extract(url, max_chars?)– Fetch a URL and return clean article content as Markdown (via Mozilla Readability), with optional truncation up to 50,000 characters.search_extract(query, limit?, max_chars?)– Combines search and extraction in one call: performs a Google search and extracts full article Markdown from each result page in parallel (up to 10 results, up to 20,000 chars each), replacing the typical two-step search + fetch workflow.
Key highlights:
No API key, proxies, or external solvers required
Automatic CAPTCHA recovery: opens a visible Chrome window for a human to solve, then retries automatically
Blocks images/media/fonts for faster performance
Designed for local use with a persistent, warm Chrome profile
Provides tools for searching Google and extracting web content without API keys, including search, parallel search, URL extraction, and combined search+extract.
google-surf-mcp
English | 한국어

Demo only. Actual searches run headless by default (no visible browser). Set
SURF_HEADLESS=falseto make Chrome visible like in the clip above.
Google search MCP. No API key. Just works.
One MCP replaces three: search + URL fetcher + academic-paper extractor.
✅ Actually works (tested 6 free Google search MCPs, all failed)
✅ Search + URL + academic PDF extract in one MCP (replaces the search MCP + fetch MCP + academic-search MCP combo)
✅ Academic PDFs extracted inline: arxiv, biorxiv, Nature, OpenReview, NeurIPS, JMLR, PMLR, Springer, PubMed (via PMC)
✅
search_extractdefaults to abstract mode (~1500 chars/result, token-cheap),mode="full"for whole bodies✅ Sponsored ads + knowledge panels dropped (geometric verification, not just text matching)
✅ CAPTCHA recovery in 4 modes: OS notification (default) /
SURF_HEADLESS=false/SURF_REMOTE_DEBUG/SURF_CLOUD_MODE(fail-fast)✅ No API key, no proxies, no solver
5 tools: search / search_parallel / extract / search_extract / health
What
Plug it into any MCP client and you get Google search as a tool.
No CAPTCHA solver. When CAPTCHA fires on any tool, a Chrome window opens for a human to solve. Each solve preserves the profile's reputation with Google.
First call auto-bootstraps the warm profile. Designed for local use. For headless / serverless environments set SURF_CLOUD_MODE=true (fail-fast on CAPTCHA, worker pool disabled).
Numbers
result | |
sequential | ~1.5s/query (first call ~4s, includes setup) |
parallel x4 | ~1.5s wall (first call ~9s, includes pool warm) |
parallel x10 | ~4.5s wall |
search_extract x5 (abstract, default) | ~3s wall |
search_extract x5 (full) | ~5s wall (search + 5 parallel extracts) |
Measured on a workstation with a 1Gb/s connection.
Stack
Playwright + persistent Chrome profile
playwright-extrastealth as a cascade fallback tierMulti-strategy SERP parser + geometric verification (drops sponsored / knowledge_panel / related)
unpdffor PDF text extraction; Mozilla Readability + Turndown for HTMLResource-blocked images / media / fonts for speed
Auto-bootstrap on first call; pool falls back to single-context after repeated warm failures
Install
Requires Node 18+ and Google Chrome (or Chromium) on the system.
npx google-surf-mcp # actual MCP - register in client configFirst tool call auto-bootstraps the warm profile (you may see Chrome open briefly).
Or local clone:
git clone https://github.com/HarimxChoi/google-surf-mcp
cd google-surf-mcp
npm installIf auto-bootstrap fails (rare), run it manually:
npm run bootstrapOverride paths if needed:
CHROME_PATH=/path/to/chrome SURF_TZ=America/New_York npm run bootstrapUse with Claude Code
Paste this into your ~/.claude.json:
{
"mcpServers": {
"google-surf": {
"command": "npx",
"args": ["-y", "google-surf-mcp"]
}
}
}Restart Claude Code. Done. search, search_parallel, extract, search_extract, health are now available.
For other MCP clients, use the same JSON shape in their config file.
Local clone variant:
{
"mcpServers": {
"google-surf": {
"command": "node",
"args": ["/abs/path/to/google-surf-mcp/build/index.js"]
}
}
}Tools
search(query, limit?)- single query, ~1.5s. Returns title / url / snippet. Sponsored ads + knowledge-panel dropped (response includesdroppedcount +dropped_reasons). Results cached 24h (SURF_CACHE_TTL_SEARCH_MS=0to bypass).search_parallel(queries[], limit?)- pool of 4, max 10 queries per call.extract(url, max_chars?, mode?)- fetch a URL, return article content.mode="full"(default): whole body. HTML via Readability, PDFs viaunpdf.mode="abstract": ~1500-char survey (PDF page 1 or HTML meta description). Triage relevance before paying for full text.mode="metadata": PDF page count only.Response:
content,title,excerpt,length,is_pdf,page_count,extraction_quality. Failures return{ error }, never throw.
search_extract(query, limit?, max_chars?, mode?)- search + parallel extract in one call. Defaultmode="abstract"returns SERP enriched with ~1500-char summaries (cheap triage). Usemode="full"when you actually need the article texts (slower, more tokens).health()- server status: cascade mode, rate-limiter usage, cache size, config. Call it if searches start failing or returning empty.
Env vars
var | default | notes |
| auto-detected | absolute path to Chrome binary |
|
| where the warm profile lives |
|
| browser locale |
| system tz | e.g. |
|
| set |
|
| set |
|
| idle ms before closing the sequential ctx and pool. |
|
| set |
|
| headless/serverless mode: TLS bypass + |
|
| pin a single stealth mode instead of the 3-tier cascade |
|
| initial stealth tier — only consulted when |
|
|
|
|
| internal cap on Google-facing requests per minute |
|
| search cache TTL (24h); |
|
| LRU cap per cache namespace |
|
| cache directory |
|
|
|
|
|
|
|
| set |
|
| directory for jsonl telemetry files. UTC-dated one file per day ( |
Troubleshooting
CAPTCHA in 4 modes (picked automatically from env):
default (local desktop): OS notification fires, headed Chrome opens, human solves, call retries
SURF_HEADLESS=false: headed Chrome opens, no notification (user is already watching)SURF_REMOTE_DEBUG=true: DevTools port + instructions printed, attachchrome://inspectlocally to solveSURF_CLOUD_MODE=true: fail-fast withCAPTCHA_REQUIREDerror
"Chrome not found": install Chrome or set
CHROME_PATH.Stale selectors: Google rotates classes. v0.4.5+ runs a multi-strategy parser and a daily self-healing workflow that opens draft PRs (human review required).
SSRF:
extractblockslocalhost, private IPs, AWS metadata by default. SetSURF_ALLOW_PRIVATE=trueto allow them.
Changelog
See CHANGELOG.md.
License
MIT
Maintenance
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/HarimxChoi/google-surf-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server