google_search
Search the web in real-time with precise results and source citations. Use this tool to retrieve accurate information based on specific queries for AI models or research purposes.
Instructions
Performs a web search using Google Search (via the Gemini API) and returns the results. This tool is useful for finding information on the internet based on a query.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | The search query to find information on the web. |
Input Schema (JSON Schema)
{
"properties": {
"query": {
"description": "The search query to find information on the web.",
"type": "string"
}
},
"required": [
"query"
],
"type": "object"
}
Implementation Reference
- src/tools/google-search.ts:55-143 (handler)Core implementation of the google_search tool: calls Gemini API with googleSearch retrieval tool enabled, extracts response, processes grounding metadata to insert citations and append sources.export async function searchGoogle(ai: GoogleGenAI, params: GoogleSearchParams): Promise<GoogleSearchResult> { try { if (!params.query || params.query.trim() === '') { throw new Error("Search query cannot be empty"); } const model = process.env.GEMINI_MODEL || "gemini-2.5-flash"; const response = await ai.models.generateContent({ model, contents: [ { role: "user", parts: [{ text: params.query }] } ], config: { tools: [{ googleSearch: {} }] } }); // Extract response text using the same method as web-search.ts const responseText = getResponseText(response); if (!responseText || responseText.trim() === '') { throw new Error("No response from Gemini model"); } // Extract grounding metadata from the first candidate const groundingMetadata = response?.candidates?.[0]?.groundingMetadata; let finalText = responseText; if (groundingMetadata) { const sources = groundingMetadata.groundingChunks || []; const supports = groundingMetadata.groundingSupports || []; // Create source list const sourceList: string[] = []; sources.forEach((source: any, index: number) => { if (source.web) { sourceList.push(`[${index + 1}] ${source.web.title} (${source.web.uri})`); } }); // Insert citation markers based on grounding supports if (supports.length > 0 && sources.length > 0) { const insertions: Array<{ index: number; text: string }> = []; supports.forEach((support: any) => { if (support.segment && support.groundingChunkIndices) { const endIndex = support.segment.endIndex || 0; const sourceNumbers = support.groundingChunkIndices .map((idx: number) => idx + 1) .sort((a: number, b: number) => a - b); const citationText = `[${sourceNumbers.join(',')}]`; insertions.push({ index: endIndex, text: citationText }); } }); // Sort insertions by index in descending order to avoid index shifting insertions.sort((a, b) => b.index - a.index); // Apply insertions to the text let modifiedText = finalText; insertions.forEach(insertion => { modifiedText = modifiedText.slice(0, insertion.index) + insertion.text + modifiedText.slice(insertion.index); }); finalText = modifiedText; } // Append source list if available if (sourceList.length > 0) { finalText += '\n\nSources:\n' + sourceList.join('\n'); } } return { content: [{ type: "text", text: finalText }] }; } catch (error) { throw new Error(`Google search failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } }
- src/index.ts:27-46 (registration)MCP tool registration: defines the 'google_search' tool name, description, and input schema in ListTools response.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "google_search", description: "Performs a web search using Google Search (via the Gemini API) and returns the results. This tool is useful for finding information on the internet based on a query.", inputSchema: { type: "object", properties: { query: { type: "string", description: "The search query to find information on the web.", }, }, required: ["query"], }, }, ], }; });
- src/index.ts:48-85 (handler)MCP CallTool request handler for 'google_search': validates request parameters and delegates to the searchGoogle implementation.server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name !== "google_search") { throw new McpError( ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}` ); } if (!request.params.arguments) { throw new McpError(ErrorCode.InvalidParams, "Missing arguments"); } const args = request.params.arguments as Record<string, unknown>; if (typeof args.query !== "string") { throw new McpError( ErrorCode.InvalidParams, "Invalid arguments: query must be a string" ); } try { const searchParams: GoogleSearchParams = { query: args.query, }; const result = await searchGoogle(googleSearchAI, searchParams); return { content: result.content, }; } catch (error) { throw new McpError( ErrorCode.InternalError, `Search failed: ${error instanceof Error ? error.message : "Unknown error"}` ); } });
- src/tools/google-search.ts:3-5 (schema)TypeScript interface defining the input parameters for the google_search tool.export interface GoogleSearchParams { query: string; }
- src/tools/google-search.ts:14-38 (helper)Helper function to initialize the GoogleGenAI client based on environment variables (supports both Vertex AI and Google AI Studio).export function createGoogleSearchAI(): GoogleGenAI { const provider = process.env.GEMINI_PROVIDER; if (provider === 'vertex') { const projectId = process.env.VERTEX_PROJECT_ID; const location = process.env.VERTEX_LOCATION || 'us-central1'; if (!projectId) { throw new Error('VERTEX_PROJECT_ID environment variable is required when using Vertex AI'); } return new GoogleGenAI({ vertexai: true, project: projectId, location }); } const apiKey = process.env.GEMINI_API_KEY; if (!apiKey) { throw new Error('GEMINI_API_KEY environment variable is required when using Google AI Studio'); } return new GoogleGenAI({ apiKey }); }