Skip to main content
Glama
garylab

Serper MCP Server

by garylab

google_search

Perform Google searches to retrieve current web information, enabling access to real-time data and answers through the Serper API.

Instructions

Search Google for results

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
qYesThe query to search for
glNoThe country to search in, e.g. us, uk, ca, au, etc.
locationNoThe location to search in, e.g. San Francisco, CA, USA
hlNoThe language to search in, e.g. en, es, fr, de, etc.
pageNoThe page number to return, first page is 1 (integer value as string)1
tbsNoThe time period to search in, e.g. d, w, m, y
numNoThe number of results to return, max is 100 (integer value as string)10

Implementation Reference

  • MCP server handler for calling tools. For 'google_search', instantiates SearchRequest from arguments, calls core.google(SerperTools.GOOGLE_SEARCH, request), formats result as JSON text content.
    @server.call_tool()
    async def call_tool(name: str, arguments: dict[str, Any]) -> Sequence[TextContent | ImageContent | EmbeddedResource]:
        if not SERPER_API_KEY:
            return [TextContent(text=f"SERPER_API_KEY is empty!", type="text")]
    
        try:
            if name == SerperTools.WEBPAGE_SCRAPE.value:
                request = WebpageRequest(**arguments)
                result = await scape(request)
                return [TextContent(text=json.dumps(result, indent=2), type="text")]
    
            if not SerperTools.has_value(name):
                raise ValueError(f"Tool {name} not found")
    
            tool = SerperTools(name)
            request = google_request_map[tool](**arguments)
            result = await google(tool, request)
            return [TextContent(text=json.dumps(result, indent=2), type="text")]
        except Exception as e:
            return [TextContent(text=f"Error: {str(e)}", type="text")]
  • Executes Google search tools including 'google_search' by constructing Serper API endpoint (/search for google_search) and delegating to fetch_json for HTTP POST.
    async def google(tool: SerperTools, request: BaseModel) -> Dict[str, Any]:
        uri_path = tool.value.split("_")[-1]
        url = f"https://google.serper.dev/{uri_path}"
        return await fetch_json(url, request)
  • Input schema (Pydantic model) for the 'google_search' tool, extending BaseRequest with num results and tbs time filter.
    class SearchRequest(BaseRequest):
        tbs: Optional[str] = Field(
            None, description="The time period to search in, e.g. d, w, m, y"
        )
        num: str = Field(
            "10",
            pattern=r"^([1-9]|[1-9]\d|100)$",
            description="The number of results to return, max is 100 (integer value as string)",
        )
  • Maps SerperTools enums (including GOOGLE_SEARCH='google_search') to input schema classes used in tool registration and call dispatching.
    google_request_map = {
        SerperTools.GOOGLE_SEARCH: SearchRequest,
        SerperTools.GOOGLE_SEARCH_IMAGES: SearchRequest,
        SerperTools.GOOGLE_SEARCH_VIDEOS: SearchRequest,
        SerperTools.GOOGLE_SEARCH_PLACES: AutocorrectRequest,
        SerperTools.GOOGLE_SEARCH_MAPS: MapsRequest,
        SerperTools.GOOGLE_SEARCH_REVIEWS: ReviewsRequest,
        SerperTools.GOOGLE_SEARCH_NEWS: SearchRequest,
        SerperTools.GOOGLE_SEARCH_SHOPPING: ShoppingRequest,
        SerperTools.GOOGLE_SEARCH_LENS: LensRequest,
        SerperTools.GOOGLE_SEARCH_SCHOLAR: AutocorrectRequest,
        SerperTools.GOOGLE_SEARCH_PATENTS: PatentsRequest,
        SerperTools.GOOGLE_SEARCH_AUTOCOMPLETE: AutocorrectRequest,
    }
  • Registers the 'google_search' tool (and others) with MCP server by generating Tool objects from the request map, including name, description, and JSON schema.
    @server.list_tools()
    async def list_tools() -> List[Tool]:
        tools = []
    
        for k, v in google_request_map.items():
            tools.append(
                Tool(
                    name=k.value,
                    description="Search Google for results",
                    inputSchema=v.model_json_schema(),
                ),
            )
    
        tools.append(Tool(
            name=SerperTools.WEBPAGE_SCRAPE,
            description="Scrape webpage by url",
            inputSchema=WebpageRequest.model_json_schema(),
        ))
    
        return tools
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. 'Search Google for results' implies a read-only operation, but it doesn't mention rate limits, authentication needs, response format, pagination behavior, or any constraints (e.g., max results). For a tool with 7 parameters and no output schema, this leaves critical behavioral aspects undocumented.

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

Conciseness4/5

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

The description is extremely concise ('Search Google for results')—just four words with zero waste. However, it's arguably too brief given the tool's complexity and sibling context, bordering on under-specification rather than optimal conciseness.

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 (7 parameters, no output schema, no annotations, and many specialized siblings), the description is incomplete. It doesn't clarify the type of results (web search), differentiate from siblings, or explain behavioral aspects like rate limits or response structure. The schema covers parameters well, but the description fails to address other contextual gaps.

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?

Schema description coverage is 100%, meaning all parameters are well-documented in the schema itself (e.g., 'q' for query, 'gl' for country). The description adds no additional parameter semantics beyond what the schema provides, so it meets the baseline of 3 where the schema does the heavy lifting.

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 results' states the basic action (search) and target (Google), but it's vague about what kind of results it returns (web search vs. other types). It doesn't distinguish this general web search tool from its many specialized siblings like google_search_images, google_search_news, etc., which is a significant gap given the context.

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 its many sibling tools (e.g., google_search_images for images, google_search_news for news). There's no mention of alternatives, prerequisites, or exclusions. The agent must infer usage from the tool name alone, which is insufficient given the specialized alternatives available.

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/garylab/serper-mcp-server'

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