Skip to main content
Glama
vendor.searchapi.site.service.ts5.63 kB
import { Logger } from '../utils/logger.util.js'; import { GoogleSearchRequestOptions, GoogleSearchResponse, GoogleImageSearchRequestOptions, GoogleImageSearchResponse, YouTubeSearchRequestOptions, YouTubeSearchResponse, SearchApiBaseResponse, } from './vendor.searchapi.site.types.js'; import { createApiError, createUnexpectedError, McpError, } from '../utils/error.util.js'; // Create a contextualized logger for this file const serviceLogger = Logger.forContext( 'services/vendor.searchapi.site.service.ts', ); // Log service initialization serviceLogger.debug('SearchAPI.site service initialized'); // Base URL for SearchAPI.site API const BASE_URL = 'https://searchapi.site'; /** * Makes a request to the SearchAPI.site API * @param endpoint - API endpoint path * @param body - Request body * @param apiKey - SearchAPI.site API key * @returns Response data */ async function makeRequest<T>( endpoint: string, body: Record<string, any>, apiKey: string, ): Promise<T> { const methodLogger = Logger.forContext( 'services/vendor.searchapi.site.service.ts', 'makeRequest', ); const url = `${BASE_URL}${endpoint}`; methodLogger.debug(`Making request to ${url}`); try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey, }, body: JSON.stringify(body), }); if (!response.ok) { const errorText = await response.text(); throw createApiError( `SearchAPI.site API error: ${response.status} ${response.statusText} - ${errorText}`, ); } const data = (await response.json()) as SearchApiBaseResponse; if (!data.success) { throw createApiError( `SearchAPI.site API error: ${data.message || 'Unknown error'}`, ); } methodLogger.debug( 'Received successful response from SearchAPI.site API', ); return data as T; } catch (error) { // Log the error caught at the service level methodLogger.error( `Service error making request to SearchAPI.site`, error, ); // Rethrow McpErrors if (error instanceof McpError) { throw error; } // Wrap any other unexpected errors throw createUnexpectedError( 'Unexpected service error while making request to SearchAPI.site', error, ); } } /** * Performs a Google search using SearchAPI.site * @param options - Google search options * @param apiKey - SearchAPI.site API key * @returns Google search results */ async function googleSearch( options: GoogleSearchRequestOptions, apiKey: string, ): Promise<GoogleSearchResponse> { const methodLogger = Logger.forContext( 'services/vendor.searchapi.site.service.ts', 'googleSearch', ); methodLogger.debug(`Performing Google search for query: ${options.query}`); const requestBody: Record<string, any> = { query: options.query, }; // Add optional parameters if provided if (options.limit !== undefined) { requestBody.limit = options.limit; } if (options.offset !== undefined) { requestBody.offset = options.offset; } if (options.sort) { requestBody.sort = options.sort; } if (options.from_date) { requestBody.from_date = options.from_date; } if (options.to_date) { requestBody.to_date = options.to_date; } return makeRequest<GoogleSearchResponse>( '/api/v1/google', requestBody, apiKey, ); } /** * Performs a Google image search using SearchAPI.site * @param options - Google image search options * @param apiKey - SearchAPI.site API key * @returns Google image search results */ async function googleImageSearch( options: GoogleImageSearchRequestOptions, apiKey: string, ): Promise<GoogleImageSearchResponse> { const methodLogger = Logger.forContext( 'services/vendor.searchapi.site.service.ts', 'googleImageSearch', ); methodLogger.debug( `Performing Google image search for query: ${options.query}`, ); const requestBody: Record<string, any> = { query: options.query, }; // Add optional parameters if provided if (options.limit !== undefined) { requestBody.limit = options.limit; } if (options.offset !== undefined) { requestBody.offset = options.offset; } if (options.sort) { requestBody.sort = options.sort; } if (options.from_date) { requestBody.from_date = options.from_date; } if (options.to_date) { requestBody.to_date = options.to_date; } return makeRequest<GoogleImageSearchResponse>( '/api/v1/google/images', requestBody, apiKey, ); } /** * Performs a YouTube search using SearchAPI.site * @param options - YouTube search options * @param apiKey - SearchAPI.site API key * @returns YouTube search results */ async function youtubeSearch( options: YouTubeSearchRequestOptions, apiKey: string, ): Promise<YouTubeSearchResponse> { const methodLogger = Logger.forContext( 'services/vendor.searchapi.site.service.ts', 'youtubeSearch', ); methodLogger.debug(`Performing YouTube search for query: ${options.query}`); const requestBody: Record<string, any> = { query: options.query, }; // Add optional parameters if provided if (options.maxResults !== undefined) { requestBody.maxResults = options.maxResults; } if (options.pageToken) { requestBody.pageToken = options.pageToken; } if (options.order) { requestBody.order = options.order; } if (options.publishedAfter !== undefined) { requestBody.publishedAfter = options.publishedAfter; } if (options.videoDuration) { requestBody.videoDuration = options.videoDuration; } return makeRequest<YouTubeSearchResponse>( '/api/v1/google/youtube', requestBody, apiKey, ); } export default { googleSearch, googleImageSearch, youtubeSearch, };

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/mrgoonie/searchapi-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server