google_search
Perform web searches using Google Custom Search API to retrieve relevant information from the internet for research, data gathering, or content discovery.
Instructions
Search the web using Google Custom Search API. Requires google_search_config resource.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search query, including any operators like site:, filetype:, etc. | |
| num | No | Number of results to return (1-10, optional) | |
| start | No | Index of the first result to return (optional) |
Implementation Reference
- src/index.ts:421-506 (handler)Main handler for 'google_search' tool: validates input args, checks env vars for API key/CX, builds and fetches Google Custom Search API URL with timeout, formats results (title/link/snippet), handles errors.} else if (toolName === 'google_search') { // Validate google_search arguments const isValidGoogleSearchArgs = (a: any): boolean => typeof a === 'object' && a !== null && typeof a.query === 'string' && (a.num === undefined || (typeof a.num === 'number' && a.num >= 1 && a.num <= 10)) && (a.start === undefined || typeof a.start === 'number'); if (!isValidGoogleSearchArgs(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid google_search arguments' ); } // Accept advanced arguments; apiKey/cx from resource const { query, num, start } = args as { query: string; num?: number; start?: number; }; // Use config from resource const apiKey = process.env.APIKEY_GOOGLE_SEARCH; const cx = process.env.CX_GOOGLE_SEARCH; if (!apiKey || !cx) { throw new McpError(ErrorCode.InvalidParams, 'Google Search API key and cx not set. Please set APIKEY_GOOGLE_SEARCH and CX_GOOGLE_SEARCH in environment variable.'); } const url = new URL('https://www.googleapis.com/customsearch/v1'); url.searchParams.set('key', apiKey); url.searchParams.set('cx', cx); url.searchParams.set('q', query); if (num !== undefined) url.searchParams.set('num', String(num)); if (start !== undefined) url.searchParams.set('start', String(start)); try { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 20000); // Apply timeout manually const response = await fetch(url.toString(), { method: 'GET', headers: { 'Content-Type': 'application/json' }, signal: controller.signal // Use abort signal for timeout }); clearTimeout(timeoutId); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); // Parse JSON directly let formatted; if (data && Array.isArray(data.items)) { formatted = data.items.map((item: any) => ({ title: item.title, link: item.link, snippet: item.snippet, })); } else { formatted = data; // Fallback to full data if items not found } return { content: [ { type: 'text', text: JSON.stringify(formatted, null, 2), }, ], }; } catch (error: any) { console.error('Error calling google_search:', error); return { content: [ { type: 'text', text: `Error calling google_search: ${error.message}`, }, ], isError: true, }; }
- src/index.ts:215-234 (schema)JSON Schema definition for input arguments of the 'google_search' tool: requires 'query' string, optional 'num' (1-10), 'start' number.inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query, including any operators like site:, filetype:, etc.' }, num: { type: 'number', description: 'Number of results to return (1-10, optional)' }, start: { type: 'number', description: 'Index of the first result to return (optional)' } }, required: ['query'], additionalProperties: false, description: 'Search the web using Google Custom Search API.' },
- src/index.ts:212-235 (registration)Registration of 'google_search' tool in the tools list returned by listTools handler, including name, description, and inputSchema.{ name: 'google_search', description: 'Search the web using Google Custom Search API. Requires google_search_config resource.', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query, including any operators like site:, filetype:, etc.' }, num: { type: 'number', description: 'Number of results to return (1-10, optional)' }, start: { type: 'number', description: 'Index of the first result to return (optional)' } }, required: ['query'], additionalProperties: false, description: 'Search the web using Google Custom Search API.' }, },