Automate Google search
Navigate to Google, submit a search query, and extract result titles and links.
- A Browserless API token from your account dashboard
Steps
- AI Agent
- REST API
- Frameworks
- BQL
Use the Browserless MCP server to automate a Google search from any MCP-compatible AI agent (Claude Desktop, Cursor, Windsurf, ChatGPT, etc.).
1. Connect the MCP server
Send this prompt to your AI agent to install the Browserless MCP server:
Go to https://github.com/browserless/browserless-mcp/blob/main/install.md
and follow the instructions to install the Browserless MCP server
for my client.
2. Search the web
Use browserless_search. The task starts with a search query rather than a known URL.
Use the browserless_search tool to search Google for
"best headless browser API" and return the top results
Send the BQL mutation over HTTP to the stealth endpoint. Google's bot detection blocks the /scrape endpoint, so use /stealth/bql instead.
- cURL
- JavaScript
- Python
- Java
- C#
1. Send the request
curl -X POST \
"https://production-sfo.browserless.io/stealth/bql?token=YOUR_API_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d "{\"query\": \"mutation GoogleSearch { goto(url: \\\"https://www.google.com/search?q=Browserless+headless+browser\\\") { status } results: mapSelector(selector: \\\"h3\\\", wait: true) { innerText } }\", \"variables\": {}}"
2. Check the output
{
"data": {
"goto": { "status": 200 },
"results": [
{ "innerText": "Browserless | Headless Browser Automation & Scraping" },
{ "innerText": "Getting Started | Browserless" }
]
}
}
1. Send the request
const query = `
mutation GoogleSearch {
goto(url: "https://www.google.com/search?q=Browserless+headless+browser") {
status
}
results: mapSelector(selector: "h3", wait: true) {
innerText
}
}
`;
const response = await fetch(
'https://production-sfo.browserless.io/stealth/bql?token=YOUR_API_TOKEN_HERE',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, variables: {} }),
}
);
const result = await response.json();
console.log(result.data.results);
2. Check the output
{
"data": {
"goto": { "status": 200 },
"results": [
{ "innerText": "Browserless | Headless Browser Automation & Scraping" },
{ "innerText": "Getting Started | Browserless" }
]
}
}
1. Install dependencies
pip install requests
2. Send the request
import requests
query = """
mutation GoogleSearch {
goto(url: "https://www.google.com/search?q=Browserless+headless+browser") {
status
}
results: mapSelector(selector: "h3", wait: true) {
innerText
}
}
"""
response = requests.post(
'https://production-sfo.browserless.io/stealth/bql?token=YOUR_API_TOKEN_HERE',
json={'query': query, 'variables': {}},
)
print(response.json())
3. Check the output
{
"data": {
"goto": { "status": 200 },
"results": [
{ "innerText": "Browserless | Headless Browser Automation & Scraping" },
{ "innerText": "Getting Started | Browserless" }
]
}
}
1. Send the request
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
String endpoint = "https://production-sfo.browserless.io/stealth/bql?token=YOUR_API_TOKEN_HERE";
String mutation = "mutation GoogleSearch { goto(url: \\\"https://www.google.com/search?q=Browserless+headless+browser\\\") { status } results: mapSelector(selector: \\\"h3\\\", wait: true) { innerText } }";
String payload = "{\"query\": \"" + mutation + "\", \"variables\": {}}";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(endpoint))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
2. Check the output
{
"data": {
"goto": { "status": 200 },
"results": [
{ "innerText": "Browserless | Headless Browser Automation & Scraping" },
{ "innerText": "Getting Started | Browserless" }
]
}
}
1. Send the request
using System.Net.Http;
using System.Text;
using System.Text.Json;
string endpoint = "https://production-sfo.browserless.io/stealth/bql?token=YOUR_API_TOKEN_HERE";
string mutation = "mutation GoogleSearch { goto(url: \"https://www.google.com/search?q=Browserless+headless+browser\") { status } results: mapSelector(selector: \"h3\", wait: true) { innerText } }";
var payload = new { query = mutation, variables = new { } };
using HttpClient httpClient = new HttpClient();
var jsonPayload = JsonSerializer.Serialize(payload);
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(endpoint, content);
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
2. Check the output
{
"data": {
"goto": { "status": 200 },
"results": [
{ "innerText": "Browserless | Headless Browser Automation & Scraping" },
{ "innerText": "Getting Started | Browserless" }
]
}
}
Use a browser connection to navigate to Google and extract results from the rendered DOM.
- Puppeteer
- Playwright
1. Install dependencies
npm install puppeteer-core
2. Connect and search
import puppeteer from 'puppeteer-core';
const browser = await puppeteer.connect({
browserWSEndpoint: 'wss://production-sfo.browserless.io?token=YOUR_API_TOKEN_HERE',
});
try {
const page = await browser.newPage();
await page.goto('https://www.google.com', { waitUntil: 'networkidle2' });
await page.type('textarea[name="q"]', 'Browserless headless browser');
await page.keyboard.press('Enter');
await page.waitForSelector('#search');
const results = await page.evaluate(() =>
Array.from(document.querySelectorAll('h3')).map((h) => ({
title: h.innerText,
url: h.closest('a')?.href ?? null,
}))
);
console.log(results);
} finally {
// Always close to release the session even on error.
await browser.close();
}
3. Check the output
Run with node search.mjs. Each object in the array has a title and url.
1. Install dependencies
npm install playwright-core
2. Connect and search
import { chromium } from 'playwright-core';
const browser = await chromium.connect(
'wss://production-sfo.browserless.io/chromium/playwright?token=YOUR_API_TOKEN_HERE'
);
try {
const page = await browser.newPage();
await page.goto('https://www.google.com', { waitUntil: 'networkidle' });
await page.fill('textarea[name="q"]', 'Browserless headless browser');
await page.keyboard.press('Enter');
await page.waitForSelector('#search');
const results = await page.evaluate(() =>
Array.from(document.querySelectorAll('h3')).map((h) => ({
title: h.innerText,
url: h.closest('a')?.href ?? null,
}))
);
console.log(results);
} finally {
// Always close to release the session even on error.
await browser.close();
}
3. Check the output
Run with node search.mjs. Each object in the array has a title and url.
1. Write the mutation
Pass the query in the URL to skip typing, then use mapSelector to extract all result headings:
mutation GoogleSearch {
goto(url: "https://www.google.com/search?q=Browserless+headless+browser") {
status
}
results: mapSelector(selector: "h3", wait: true) {
innerText
}
}
2. Run it
Paste into the BQL IDE and click Run.
3. Check the output
{
"data": {
"goto": { "status": 200 },
"results": [
{ "innerText": "Browserless | Headless Browser Automation & Scraping" },
{ "innerText": "Getting Started | Browserless" }
]
}
}
Next steps
- Scrape Structured Data — extract more complex data with CSS selectors
- Extract Content from a URL — retrieve the full rendered HTML of any page