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
- BAP
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. Install dependencies
npm install @browserless.io/bap-ts
2. Connect and search
import Browserless from '@browserless.io/bap-ts';
const browser = Browserless.connect({
browserWSEndpoint: 'wss://production-sfo.browserless.io/chromium/bql',
token: 'YOUR_API_TOKEN_HERE',
});
try {
const page = await browser.newPage();
// BAP has no keyboard API, so navigate straight to the results URL.
await page.goto('https://www.google.com/search?q=Browserless+headless+browser');
// `wait: true` holds until the selector appears, so no separate wait call.
const results = await page.mapSelector('h3', { wait: true });
console.log(results.map((result) => result.innerText));
} finally {
// Always close to release the session even on error.
await browser.close();
}
3. Check the output
Run with node search.mjs. Each result carries the heading text from the search page.
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" }
]
}
}