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
    }));
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It states what the tool does but doesn't describe any behavioral traits such as rate limits, authentication needs, result format, pagination, or whether it's a read-only operation. This leaves significant gaps for an agent to understand how to interact with it effectively.

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 extremely concise with just four words, front-loaded with the core action, and contains zero wasted information. Every word earns its place by directly contributing to understanding the tool's 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 tool's complexity (a search operation with potential behavioral nuances) and the lack of annotations and output schema, the description is incomplete. It doesn't cover what the tool returns, how results are structured, or any operational constraints, making it insufficient for an agent to use the tool confidently without additional context.

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 schema description coverage is 100%, with the single parameter 'query' fully documented in the schema. The description doesn't add any meaning beyond what the schema provides (e.g., it doesn't explain query syntax, examples, or constraints), so it meets the baseline for adequate but unenhanced parameter documentation.

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

Purpose4/5

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

The description clearly states the verb ('Search') and resource ('Google') with the specific action ('for a query'), making the purpose immediately understandable. However, it doesn't differentiate from potential sibling tools like 'visit_page' or 'take_screenshot' that might also involve web interactions, so it doesn't reach the highest score.

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 like 'visit_page' or 'take_screenshot'. It doesn't mention any prerequisites, exclusions, or specific contexts where this search tool is preferred over direct page visits or other methods.

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

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