Skip to main content
Glama
jevy

MCP Web Research Server

by jevy

search_google

Search Google for information to answer questions, find resources, or gather data during conversations. This tool provides web research capabilities directly within chat interfaces.

Instructions

Search Google for a query

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query

Implementation Reference

  • Handler for the 'search_google' tool. Navigates to Google, inputs the query, submits the search, extracts top results (title, URL, snippet), stores in session, and returns JSON-formatted results.
    case "search_google": {
        // Extract search query from request parameters
        const { query } = request.params.arguments as { query: string };
    
        try {
            // Execute search with retry mechanism
            const results = await withRetry(async () => {
                // Step 1: Navigate to Google search page
                await safePageNavigation(page, 'https://www.google.com');
                await dismissGoogleConsent(page);
    
                // Step 2: Find and interact with search input
                await withRetry(async () => {
                    // Wait for any search input element to appear
                    await Promise.race([
                        // Try multiple possible selectors for search input
                        page.waitForSelector('input[name="q"]', { timeout: 5000 }),
                        page.waitForSelector('textarea[name="q"]', { timeout: 5000 }),
                        page.waitForSelector('input[type="text"]', { timeout: 5000 })
                    ]).catch(() => {
                        throw new Error('Search input not found - no matching selectors');
                    });
    
                    // Find the actual search input element
                    const searchInput = await page.$('input[name="q"]') ||
                        await page.$('textarea[name="q"]') ||
                        await page.$('input[type="text"]');
    
                    // Verify search input was found
                    if (!searchInput) {
                        throw new Error('Search input element not found after waiting');
                    }
    
                    // Step 3: Enter search query
                    await searchInput.click({ clickCount: 3 });  // Select all existing text
                    await searchInput.press('Backspace');        // Clear selected text
                    await searchInput.type(query);               // Type new query
                }, 3, 2000);  // Allow 3 retries with 2s delay
    
                // Step 4: Submit search and wait for results
                await withRetry(async () => {
                    await Promise.all([
                        page.keyboard.press('Enter'),
                        page.waitForLoadState('networkidle', { timeout: 15000 }),
                    ]);
                });
    
                // Step 5: Extract search results
                const searchResults = await withRetry(async () => {
                    const results = await page.evaluate(() => {
                        // Find all search result containers
                        const elements = document.querySelectorAll('div.g');
                        if (!elements || elements.length === 0) {
                            throw new Error('No search results found');
                        }
    
                        // Extract data from each result
                        return Array.from(elements).map((el) => {
                            // Find required elements within result container
                            const titleEl = el.querySelector('h3');            // Title element
                            const linkEl = el.querySelector('a');              // Link element
                            const snippetEl = el.querySelector('div.VwiC3b');  // Snippet element
    
                            // Skip results missing required elements
                            if (!titleEl || !linkEl || !snippetEl) {
                                return null;
                            }
    
                            // Return structured result data
                            return {
                                title: titleEl.textContent || '',        // Result title
                                url: linkEl.getAttribute('href') || '',  // Result URL
                                snippet: snippetEl.textContent || '',    // Result description
                            };
                        }).filter(result => result !== null);  // Remove invalid results
                    });
    
                    // Verify we found valid results
                    if (!results || results.length === 0) {
                        throw new Error('No valid search results found');
                    }
    
                    // Return compiled list of results
                    return results;
                });
    
                // Step 6: Store results in session
                searchResults.forEach((result) => {
                    addResult({
                        url: result.url,
                        title: result.title,
                        content: result.snippet,
                        timestamp: new Date().toISOString(),
                    });
                });
    
                // Return compiled list of results
                return searchResults;
            });
    
            // Step 7: Return formatted results
            return {
                content: [{
                    type: "text",
                    text: JSON.stringify(results, null, 2)  // Pretty-print JSON results
                }]
            };
        } catch (error) {
            // Handle and format search errors
            return {
                content: [{
                    type: "text",
                    text: `Failed to perform search: ${(error as Error).message}`
                }],
                isError: true
            };
        }
    }
  • Input schema definition for the 'search_google' tool, specifying a required 'query' string parameter.
    {
        name: "search_google",
        description: "Search Google for a query",
        inputSchema: {
            type: "object",
            properties: {
                query: { type: "string", description: "Search query" },
            },
            required: ["query"],
        },
    },
  • index.ts:580-582 (registration)
    Registration of the tool list handler that returns the TOOLS array including 'search_google'.
    server.setRequestHandler(ListToolsRequestSchema, async () => ({
        tools: TOOLS  // Return list of available research tools
    }));
Install Server

Other 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/jevy/mcp-webresearch'

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