Skip to main content
Glama
garylab

Serper MCP Server

by garylab

google_search_patents

Search Google for patent information to retrieve current web data, supporting queries with configurable result counts and pagination.

Instructions

Search Google for results

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
qYesThe query to search for
numNoThe number of results to return, max is 100 (integer value as string)10
pageNoThe page number to return, first page is 1 (integer value as string)1

Implementation Reference

  • MCP server handler for all tools, including google_search_patents. Parses arguments into PatentsRequest schema, calls core google(tool, request) which proxies to Serper Patents API, and returns JSON results.
    @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 the tool logic for google_search_patents by deriving the '/patents' endpoint from the tool name, serializing the request to JSON payload, authenticating with SERPER_API_KEY, and POSTing to https://google.serper.dev/patents via aiohttp.
    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)
    
    
    async def scape(request: WebpageRequest) -> Dict[str, Any]:
        url = "https://scrape.serper.dev"
        return await fetch_json(url, request)
    
    
    async def fetch_json(url: str, request: BaseModel) -> Dict[str, Any]:
        payload = request.model_dump(exclude_none=True)
        headers = {
            'X-API-KEY': SERPER_API_KEY,
            'Content-Type': 'application/json'
        }
    
        ssl_context = ssl.create_default_context(cafile=certifi.where())
        connector = aiohttp.TCPConnector(ssl=ssl_context)
    
        timeout = aiohttp.ClientTimeout(total=AIOHTTP_TIMEOUT)
        async with aiohttp.ClientSession(connector=connector, timeout=timeout) as session:
            async with session.post(url, headers=headers, json=payload) as response:
                response.raise_for_status()
                return await response.json()
  • Pydantic input schema/validation for google_search_patents tool parameters: query (required), num results (default 10, max 100), page (default 1).
    class PatentsRequest(BaseModel):
        q: str = Field(..., description="The query to search for")
        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)",
        )
        page: Optional[str] = Field(
            "1",
            pattern=r"^[1-9]\d*$",
            description="The page number to return, first page is 1 (integer value as string)",
        )
  • Registers the google_search_patents tool with the MCP server using @server.list_tools(), deriving name from enum value and inputSchema from PatentsRequest via google_request_map.
    @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
  • Maps SerperTools.GOOGLE_SEARCH_PATENTS enum to PatentsRequest schema for use in tool registration and 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,
    }
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 only states 'Search Google for results,' which implies a read-only operation but lacks details on rate limits, authentication needs, error handling, or what the search results entail (e.g., format, source). This is inadequate for a tool with no annotation coverage.

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 a single sentence with no wasted words, making it appropriately concise. However, it is under-specified rather than efficiently informative, which slightly reduces its effectiveness despite the brevity.

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 fails to explain the tool's specific domain (patents), how results are returned, or any behavioral traits, leaving significant gaps for an AI agent to understand and invoke the tool correctly.

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%, so the schema fully documents parameters (q, num, page). The description adds no additional meaning beyond what the schema provides, such as query examples or result types. With high schema coverage, the baseline score of 3 is appropriate as the description doesn't enhance parameter understanding.

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

Purpose2/5

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

The description 'Search Google for results' is tautological, essentially restating the tool name 'google_search_patents' without specifying what makes it distinct from sibling tools. It lacks a specific verb-resource combination and fails to differentiate this patent search from other Google search tools like 'google_search' or 'google_search_scholar'.

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

Usage Guidelines1/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. With multiple sibling tools (e.g., google_search, google_search_scholar, google_search_news), there is no indication that this is specifically for patent searches or when it should be preferred over other search tools, leading to potential misuse.

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