Skip to main content
Glama
yukukotani

MCP Gemini Google Search

by yukukotani

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

TableJSON Schema
NameRequiredDescriptionDefault
queryYesThe search query to find information on the web.

Implementation Reference

  • 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"],
            },
          },
        ],
      };
    });
  • 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"}`
        );
      }
    });
  • TypeScript interface defining the input parameters for the google_search tool.
    export interface GoogleSearchParams {
      query: string;
    }
  • 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 });
    }
Install Server

Other Tools

Related Tools

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/yukukotani/mcp-gemini-google-search'

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