
google-surf-mcp-search
Google search MCP server with academic PDF extraction, no API key required, CAPTCHA recovery, and parallel search capabilities
- Installs
- 212
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/reason-machines/mcp-skills --skill google-surf-mcp-search- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads google-surf-mcp-search automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
google-surf-mcp-search
Skill by ara.so — MCP Skills collection.
What It Does
google-surf-mcp is an MCP server that provides Google search functionality without requiring API keys. It combines three capabilities in one:
- Google search with ad/spam filtering
- URL content extraction (HTML + PDF)
- Academic paper extraction (arXiv, Nature, PubMed, etc.)
Key features:
- Works with actual Google search (not an API wrapper)
- Automatic CAPTCHA recovery with persistent browser profiles
- Parallel search and extraction
- Token-efficient abstract mode for triage
- Built-in rate limiting and caching
- Geometric verification to drop sponsored ads and knowledge panels
Installation
Quick Install (npx)
Add to your MCP client config (e.g., ~/.claude.json for Claude Code):
{
"mcpServers": {
"google-surf": {
"command": "npx",
"args": ["-y", "google-surf-mcp"]
}
}
}
Local Clone Installation
git clone https://github.com/HarimxChoi/google-surf-mcp
cd google-surf-mcp
npm install
npm run build
Config for local installation:
{
"mcpServers": {
"google-surf": {
"command": "node",
"args": ["/absolute/path/to/google-surf-mcp/build/index.js"]
}
}
}
Manual Bootstrap (if auto-bootstrap fails)
npm run bootstrap
With custom paths:
CHROME_PATH=/usr/bin/google-chrome SURF_TZ=America/New_York npm run bootstrap
Available Tools
1. search - Single Google Search
Performs a single Google search, returns filtered results (ads removed).
Parameters:
query(string, required): Search querylimit(number, optional): Max results, default 10
Returns:
results[]: Array of{ title, url, snippet }dropped: Count of filtered results (ads, knowledge panels)dropped_reasons[]: Why items were droppedcache_hit: Boolean indicating cache use
Example Usage:
// Via MCP tool call
{
"query": "typescript async patterns",
"limit": 5
}
Response:
{
"results": [
{
"title": "Async/Await in TypeScript",
"url": "https://example.com/typescript-async",
"snippet": "Learn how to use async/await patterns..."
}
],
"dropped": 2,
"dropped_reasons": ["sponsored", "knowledge_panel"],
"cache_hit": false
}
2. search_parallel - Parallel Multi-Query Search
Execute multiple searches in parallel using a worker pool (max 10 queries).
Parameters:
queries(string[], required): Array of search querieslimit(number, optional): Max results per query, default 10
Returns:
- Array of search results (same format as
search)
Example Usage:
{
"queries": [
"mcp server best practices",
"playwright stealth techniques",
"typescript pdf extraction",
"google search scraping 2026"
],
"limit": 3
}
3. extract - Fetch and Extract Content
Extract text content from a URL (HTML or PDF).
Parameters:
url(string, required): URL to extractmax_chars(number, optional): Character limit, default 100kmode(string, optional):"full"|"abstract"|"metadata"
Modes:
full: Complete article text (HTML via Readability, PDF via unpdf)abstract: ~1500 chars for triage (PDF page 1 or HTML meta description)metadata: PDF page count only
Returns:
content: Extracted text (markdown for HTML)title: Document titleexcerpt: Short summarylength: Character countis_pdf: Booleanpage_count: Number (PDFs only)extraction_quality:"high"|"medium"|"low"
Example Usage:
// Extract full academic paper
{
"url": "https://arxiv.org/pdf/2301.12345.pdf",
"mode": "full"
}
// Quick abstract for triage
{
"url": "https://nature.com/articles/s41586-023-12345-6",
"mode": "abstract",
"max_chars": 2000
}
Response:
{
"content": "# Paper Title\n\nAbstract: This paper presents...",
"title": "Novel Approach to AI Safety",
"excerpt": "This paper presents a novel approach...",
"length": 45678,
"is_pdf": true,
"page_count": 12,
"extraction_quality": "high"
}
4. search_extract - Combined Search + Extract
Search and extract content in one call. Efficiently parallelizes extraction.
Parameters:
query(string, required): Search querylimit(number, optional): Max results to extract, default 5max_chars(number, optional): Per-result char limitmode(string, optional):"abstract"(default) |"full"
Best Practices:
- Use
mode="abstract"(default) for cheap triage with ~1500-char summaries - Use
mode="full"only when you need complete article text (slower, more tokens)
Returns:
results[]: Search results enriched withextracted_content
Example Usage:
// Triage mode (default, token-efficient)
{
"query": "claude mcp server tutorials",
"limit": 5,
"mode": "abstract"
}
// Full extraction (when you need complete content)
{
"query": "machine learning interpretability survey",
"limit": 3,
"mode": "full",
"max_chars": 50000
}
Response:
{
"results": [
{
"title": "Building MCP Servers",
"url": "https://example.com/mcp-tutorial",
"snippet": "Complete guide to MCP servers...",
"extracted_content": {
"content": "# Building MCP Servers\n\nMCP (Model Context Protocol)...",
"title": "Building MCP Servers",
"length": 1523,
"is_pdf": false,
"extraction_quality": "high"
}
}
]
}
5. health - Server Status
Check server health and configuration.
Returns:
status:"healthy"|"degraded"cascade_mode: Current stealth moderate_limiter: Request counts and limitscache_stats: Cache size and hit ratesconfig: Active configuration values
Example Usage:
// No parameters
{}
Configuration
All configuration via environment variables:
Essential Variables
# Chrome binary path (auto-detected if not set)
CHROME_PATH=/usr/bin/google-chrome
# Profile storage (default: ~/.google-surf-mcp)
SURF_PROFILE_ROOT=/custom/path/profiles
# Browser locale and timezone
SURF_LOCALE=en-US
SURF_TZ=America/New_York
Headless & CAPTCHA Recovery
# Run Chrome visibly (for demos/debugging)
SURF_HEADLESS=false
# Remote debugging mode (headless servers)
SURF_REMOTE_DEBUG=true
# Cloud/serverless mode (fail-fast on CAPTCHA)
SURF_CLOUD_MODE=true
Performance Tuning
# Idle close timeout (ms), 0 disables
SURF_IDLE_CLOSE_MS=30000
# Rate limit (requests per minute)
SURF_RATE_LIMIT_PER_MIN=10
# Search cache TTL (ms), 0 disables
SURF_CACHE_TTL_SEARCH_MS=86400000
# Cache LRU size
SURF_CACHE_MAX_ENTRIES=1000
Security
# Allow private IPs in extract (default: false)
SURF_ALLOW_PRIVATE=true
# Ignore TLS errors (auto-on in cloud mode)
SURF_INSECURE_TLS=false
# Disable sandbox (auto-on in cloud mode)
SURF_NO_SANDBOX=false
Advanced
# Disable cascade fallback (pin single mode)
SURF_CASCADE_DISABLED=true
SURF_USE_STEALTH=true
# Humanlike browsing (off | background | inline)
SURF_HUMANLIKE_MODE=background
Common Patterns
Pattern 1: Research Assistant
Search academic papers and extract abstracts for quick review:
// Step 1: Search and triage with abstracts
const triage = await use_mcp_tool("google-surf", "search_extract", {
query: "transformer architecture improvements 2026",
limit: 10,
mode: "abstract"
});
// Step 2: Extract full text for promising papers
const topPapers = triage.results.slice(0, 3);
const fullTexts = await Promise.all(
topPapers.map(paper =>
use_mcp_tool("google-surf", "extract", {
url: paper.url,
mode: "full",
max_chars: 100000
})
)
);
Pattern 2: Parallel Research
Search multiple related topics simultaneously:
const relatedTopics = await use_mcp_tool("google-surf", "search_parallel", {
queries: [
"MCP server authentication patterns",
"MCP server error handling",
"MCP server rate limiting",
"MCP server caching strategies"
],
limit: 5
});
// Process results by topic
relatedTopics.forEach((topicResults, index) => {
console.log(`Topic ${index + 1}:`, topicResults.results.length, "results");
});
Pattern 3: Content Aggregation
Build a comprehensive knowledge base:
// 1. Find relevant sources
const sources = await use_mcp_tool("google-surf", "search", {
query: "typescript best practices 2026",
limit: 20
});
// 2. Extract abstracts to filter quality
const abstracts = await Promise.all(
sources.results.map(result =>
use_mcp_tool("google-surf", "extract", {
url: result.url,
mode: "abstract"
})
)
);
// 3. Full extraction for high-quality sources
const highQuality = abstracts
.filter(a => a.extraction_quality === "high")
.slice(0, 5);
const fullContent = await Promise.all(
highQuality.map(a =>
use_mcp_tool("google-surf", "extract", {
url: a.url,
mode: "full"
})
)
);
Pattern 4: Health Check Before Heavy Operations
// Check server health before batch operations
const health = await use_mcp_tool("google-surf", "health", {});
if (health.status !== "healthy") {
console.warn("Server degraded, reducing concurrency");
}
const rateLimit = health.rate_limiter.requests_per_minute;
if (rateLimit > 8) {
// Wait before starting batch
await sleep(60000);
}
CAPTCHA Recovery Modes
The server handles CAPTCHAs automatically based on environment:
Mode 1: Local Desktop (default)
# No config needed - default behavior
When CAPTCHA appears:
- OS notification fires
- Headed Chrome window opens
- Human solves CAPTCHA
- Call automatically retries
- Profile reputation preserved
Mode 2: Visible Chrome (demos/debugging)
SURF_HEADLESS=false
- Chrome runs visibly at all times
- CAPTCHA recovery skips notification (user is watching)
- Good for demos and debugging
Mode 3: Remote Debugging (headless servers)
SURF_HEADLESS=true
SURF_REMOTE_DEBUG=true
When CAPTCHA appears:
- DevTools port printed to logs
- Error thrown with instructions
- SSH port-forward from local machine
- Open
chrome://inspectlocally - Solve CAPTCHA remotely
- Retry the call
Example SSH forward:
ssh -L 9222:localhost:9222 your-server
Mode 4: Cloud/Serverless (fail-fast)
SURF_CLOUD_MODE=true
- No CAPTCHA recovery
- Throws
CAPTCHA_REQUIREDerror immediately - Worker pool disabled
- Sandbox disabled, TLS bypass enabled
Troubleshooting
Chrome Not Found
Error: Chrome binary not found
Solution:
# Find your Chrome installation
which google-chrome
which chromium
# Set explicitly
CHROME_PATH=/usr/bin/google-chrome npm run bootstrap
CAPTCHA Loops
Symptoms: Repeated CAPTCHA requests
Solutions:
- Run bootstrap to warm the profile:
npm run bootstrap
- Reduce request rate:
SURF_RATE_LIMIT_PER_MIN=5 npx google-surf-mcp
- Check cascade mode:
const health = await use_mcp_tool("google-surf", "health", {});
console.log(health.cascade_mode); // Should cycle: none → stealth → humanlike
Empty or No Results
Check health first:
const health = await use_mcp_tool("google-surf", "health", {});
// Check rate_limiter.requests_per_minute
// Check cache_stats for anomalies
Clear cache if stale:
SURF_CACHE_TTL_SEARCH_MS=0 npx google-surf-mcp
Check dropped reasons:
const results = await use_mcp_tool("google-surf", "search", {
query: "test query"
});
console.log(results.dropped_reasons);
// If all results dropped as "sponsored", selector may be stale
Extraction Failures
PDF extraction fails:
// Try metadata mode first
const meta = await use_mcp_tool("google-surf", "extract", {
url: "https://example.com/paper.pdf",
mode: "metadata"
});
console.log(meta.page_count); // If 0, PDF is inaccessible
SSRF blocked:
# Allow private IPs (only if you control the URLs)
SURF_ALLOW_PRIVATE=true npx google-surf-mcp
Low extraction quality:
const result = await use_mcp_tool("google-surf", "extract", {
url: "https://example.com/article"
});
if (result.extraction_quality === "low") {
// HTML was poorly structured or blocked
// Try fetching directly via other means
}
Performance Issues
Slow first call:
Normal. First call bootstraps the profile (~4s sequential, ~9s parallel). Subsequent calls are faster (~1.5s).
Idle timeout too aggressive:
# Keep contexts warm longer
SURF_IDLE_CLOSE_MS=120000 npx google-surf-mcp
Too many parallel queries:
Limit to 10 per search_parallel call. For more, batch them:
const queries = [...100queries];
const batches = chunk(queries, 10);
for (const batch of batches) {
const results = await use_mcp_tool("google-surf", "search_parallel", {
queries: batch
});
// Process batch
await sleep(5000); // Respect rate limits
}
Academic Sources Supported
Inline PDF extraction for:
- arXiv
- bioRxiv, medRxiv
- Nature, Science, Cell
- OpenReview
- NeurIPS, ICML, ICLR proceedings
- JMLR, PMLR
- Springer
- PubMed (via PMC)
- ACL Anthology
All extracted to markdown-formatted text.
Cache Management
# Disable search caching
SURF_CACHE_TTL_SEARCH_MS=0
# Increase cache size
SURF_CACHE_MAX_ENTRIES=5000
# Custom cache location
SURF_CACHE_ROOT=/tmp/google-surf-cache
Cache namespaces:
search: Google search results (24h TTL default)extract: URL content extractions (no TTL, LRU only)
Rate Limiting
Built-in rate limiter prevents Google blocks:
# Default: 10 requests/minute
SURF_RATE_LIMIT_PER_MIN=10
# Conservative for shared IPs
SURF_RATE_LIMIT_PER_MIN=5
# Aggressive (may trigger CAPTCHAs)
SURF_RATE_LIMIT_PER_MIN=20
Check current usage:
const health = await use_mcp_tool("google-surf", "health", {});
console.log(health.rate_limiter);
// { requests_per_minute: 7, limit: 10, window_start: "2026-05-17T..." }
Best Practices
-
Use abstract mode for triage: Default
search_extracttomode="abstract"to save tokens and time. Only requestmode="full"when needed. -
Batch related queries: Use
search_parallelinstead of sequentialsearchcalls. -
Check health before batch ops: Prevents hitting rate limits mid-batch.
-
Respect cache TTLs: Default 24h for search is sensible. Don't disable unless debugging.
-
Handle extraction failures gracefully: Always check
extraction_qualityand handle{ error }responses. -
Profile warmth: First call of the day may be slower. Acceptable for human-in-the-loop workflows.
-
CAPTCHA strategy: For long-running agents, use
SURF_CLOUD_MODE=falseand solve CAPTCHAs as they appear to preserve profile reputation.
FAQ
What does the google-surf-mcp-search skill do?
Google search MCP server with academic PDF extraction, no API key required, CAPTCHA recovery, and parallel search capabilities
How do I install google-surf-mcp-search?
Run npx skills add https://github.com/reason-machines/mcp-skills --skill google-surf-mcp-search in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/google-surf-mcp-search/ (personal) or .claude/skills/google-surf-mcp-search/ (project).
Which AI agents can use google-surf-mcp-search?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is google-surf-mcp-search safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains google-surf-mcp-search?
It is published by reason-machines in reason-machines/mcp-skills. It has 212 recorded installs.
More from reason-machines/mcp-skills
codebase-memory-mcp-intelligence
reason-machines/mcp-skills
High-performance code intelligence MCP server that indexes codebases into knowledge graphs for structural queries, call traces, and architecture analysis
playwright-mcp-server
reason-machines/mcp-skills
Browser automation MCP server using Playwright's accessibility tree for LLM-friendly web interaction
tradingview-mcp-assistant
reason-machines/mcp-skills
AI-assisted TradingView chart analysis and automation via Chrome DevTools Protocol for Claude Code
lanhu-mcp-collaboration
reason-machines/mcp-skills
AI-powered design collaboration server connecting Lanhu design platform with AI coding assistants for requirements analysis, UI design extraction, and team knowledge sharing
chrome-devtools-mcp-automation
reason-machines/mcp-skills
Expert guidance for Chrome DevTools MCP server - browser automation, debugging, and performance analysis for AI agents
github-mcp-server
reason-machines/mcp-skills
Open the skill to read its SKILL.md instructions.
Popular ai & agents skills
google-agents-cli-publish
google/agents-cli
This skill should be used when the user wants to "publish an agent", "publish my ADK agent", "register an agent with Gemini", "publish to Gemini" (formerly Gemini Enterprise), or needs guidance on the agents-cli publish gemini command. Also use when the user wants to "manage agents in Agent Registry", "list/update/delete registered agents", or "register an MCP server". Covers ADK vs A2A registration modes, programmatic and interactive usage, flag reference, auto-detection from deployment metadata, Agent Registry fleet management, and troubleshooting. Part of the agents-cli skills suite. Do NOT use for deployment (use google-agents-cli-deploy).
google-agents-cli-eval
google/agents-cli
This skill should be used when the user wants to "run an evaluation", "evaluate my agent", "evaluate my ADK agent", "write an eval dataset", "analyze eval failures", "compare eval results", "optimize agent", or needs guidance on the Gemini platform eval methodology and the Quality Flywheel. Covers eval metrics, dataset schema, LLM-as-judge scoring, and common failure causes. Applies to any agents-cli project, whatever framework the agent is written in. Do NOT use for agent API code patterns (ADK: use google-agents-cli-adk-code), deployment (use google-agents-cli-deploy), or project scaffolding (use google-agents-cli-scaffold).
skill-creator
anthropics/skills
Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.
codex-pet
prime-skills/runcomfy-agent-skills
Codex Pet generator on RunComfy. Build a Codex-compatible Codex Pet spritesheet.webp + pet.json from a single reference image, drop it into ${CODEXHOME:-$HOME/.codex}/pets/ / and Codex picks it up as a custom Codex Pet next to the 8 built-ins. This skill produces the exact Codex Pet atlas Codex expects (1536x1872 PNG/WebP, 8 cols x 9 rows, 192x208 cells, 9 animation states — idle, running-right, running-left, waving, jumping, failed, waiting, running, review). Calls OpenAI GPT Image 2 edit ONCE via the local RunComfy CLI as runcomfy run openai/gpt-image-2/edit to produce a canonical Codex Pet pose, then assembles all 9 animation rows programmatically with ImageMagick micro-transforms — no Codex Pro, no $imagegen, no OPENAIAPIKEY required, only RUNCOMFYTOKEN. Triggers on "codex pet", "create codex pet", "make codex pet", "hatch codex pet", "/hatch image", "desktop pet codex", "codex pets", "spritesheet.webp", or any explicit ask to build a custom pet for OpenAI Codex.
full-output-enforcement
leonxlnx/taste-skill
Overrides default LLM truncation behavior. Enforces complete code generation, bans placeholder patterns, and handles token-limit splits cleanly. Apply to any task requiring exhaustive, unabridged output.
executing-plans
obra/superpowers
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available