serper-search-scrape-mcp-server
Version:
Serper MCP Server supporting search and webpage scraping
109 lines (108 loc) • 3.6 kB
JavaScript
import fetch from "node-fetch";
/**
* Implementation of Serper API client.
*/
export class SerperClient {
apiKey;
baseUrl;
/**
* Initialize Serper API client.
* @param apiKey - Serper API key for authentication
* @param baseUrl - Base URL for Serper API (optional)
*/
constructor(apiKey, baseUrl = "https://google.serper.dev") {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
/**
* Perform a web search using Serper API.
* @param params - Search parameters
* @returns Promise resolving to search results
* @throws Error if API request fails
*/
async search(params) {
try {
const response = await fetch(`${this.baseUrl}/search`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": this.apiKey,
},
body: JSON.stringify(params),
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Serper API error: ${response.status} ${response.statusText} - ${errorText}`);
}
const data = (await response.json());
return data;
}
catch (error) {
console.error("Serper search failed:", error);
throw error;
}
}
/**
* Perform a web search using Serper API.
* @param batchParams - Search parameters
* @returns Promise resolving to search results
* @throws Error if API request fails
*/
async batchSearch(batchParams) {
if (!batchParams.length) {
throw new Error("Batch search requires at least one query");
}
try {
const response = await fetch(`${this.baseUrl}/search`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": this.apiKey,
},
body: JSON.stringify(batchParams),
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Serper API error: ${response.status} ${response.statusText} - ${errorText}`);
}
const data = (await response.json());
return data;
}
catch (error) {
console.error("Serper search failed:", error);
throw error;
}
}
/**
* Scrape a URL using Serper API.
* @param params - Scrape parameters
* @returns Promise resolving to scrape result
* @throws Error if API request fails
*/
async scrape(params) {
if (!params.url) {
throw new Error("URL is required for scraping");
}
try {
const response = await fetch("https://scrape.serper.dev", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": this.apiKey,
},
body: JSON.stringify(params),
redirect: "follow",
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Serper API error: ${response.status} ${response.statusText} - ${errorText}`);
}
const result = (await response.json());
return result;
}
catch (error) {
console.error(error);
throw error;
}
}
}