Skip to main content
Glama
garylab
by garylab

google_search_scholar

Perform Google searches to retrieve current web information using the Serper API, enabling access to up-to-date data for research and queries.

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
autocorrectNoAutomatically correct (boolean value as string: 'true' or 'false')true

Implementation Reference

  • Maps the SerperTools.GOOGLE_SEARCH_SCHOLAR enum to its input schema (AutocorrectRequest), used for 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, }
  • Pydantic input schema for the google_search_scholar tool, inheriting from BaseRequest (q, gl, etc.).
    class AutocorrectRequest(BaseRequest): autocorrect: Optional[str] = Field( "true", pattern=r"^(true|false)$", description="Automatically correct (boolean value as string: 'true' or 'false')", )
  • Registers the google_search_scholar tool with the MCP server, using name from enum and schema from the 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
  • Main tool handler that validates arguments with the mapped schema, constructs SerperTools enum, and calls the core google handler for google_search_scholar.
    @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_scholar, POSTs to https://google.serper.dev/scholar with the validated request payload.
    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()

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