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
    }));

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states the action ('Search Google') but doesn't reveal any behavioral traits such as whether it requires authentication, rate limits, what the output format is (since no output schema exists), or if it performs a live web search versus cached results. The description is minimal and lacks critical operational details.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with zero wasted words: 'Search Google for a query'. It is front-loaded and directly conveys the core action without unnecessary elaboration, making it highly concise and well-structured for its purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a search tool with no annotations and no output schema, the description is incomplete. It doesn't explain what the tool returns (e.g., search results, links, snippets), any limitations (e.g., number of results, pagination), or behavioral aspects like error handling. For a tool that likely involves external API calls or web interactions, more context is needed to guide effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, with the 'query' parameter documented as 'Search query'. The description adds no additional meaning beyond this, as it only repeats the concept of a 'query' without elaborating on syntax, examples, or constraints. Given the high schema coverage, the baseline score of 3 is appropriate, as the description doesn't compensate but also doesn't detract.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Search Google for a query' clearly states the verb ('Search') and resource ('Google'), making the purpose understandable. However, it lacks specificity about what kind of search this is (e.g., web search, image search, news search) and doesn't distinguish it from potential sibling tools like 'visit_page', which might also involve Google. The description is functional but vague in scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention sibling tools like 'take_screenshot' or 'visit_page', nor does it specify contexts where this search is appropriate (e.g., for general information retrieval vs. navigating to a specific page). Without any usage context or exclusions, the agent must infer when to apply it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools