search
Query multiple search engines simultaneously using searXNG to aggregate results from Google, Bing, DuckDuckGo, and more. Access comprehensive web information even offline, simplifying efficient research.
Instructions
search the web using searXNG. This will aggregate the results from google, bing, brave, duckduckgo and many others. Use this to find information on the web. Even if you do not have access to the internet, you can still use this tool to search the web.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes |
Input Schema (JSON Schema)
{
"properties": {
"query": {
"type": "string"
}
},
"required": [
"query"
],
"type": "object"
}
Implementation Reference
- src/mcp_searxng/tools.py:23-29 (handler)The specific handler function that executes the 'search' tool logic by parsing arguments and calling the core search function.async def search_tool( arguments: dict[str, str], ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: query: str = arguments["query"] result = await search(query) return [types.TextContent(type="text", text=result)]
- src/mcp_searxng/tools.py:6-20 (registration)Registers the 'search' tool with the MCP server, providing name, description, and input schema.@server.list_tools() async def list_tools() -> list[types.Tool]: return [ types.Tool( name="search", description="search the web using searXNG. This will aggregate the results from google, bing, brave, duckduckgo and many others. Use this to find information on the web. Even if you do not have access to the internet, you can still use this tool to search the web.", inputSchema={ "type": "object", "properties": { "query": {"type": "string"}, }, "required": ["query"], }, ) ]
- src/mcp_searxng/tools.py:32-47 (handler)The MCP @server.call_tool() handler that dispatches calls to the specific search_tool when name=='search'.@server.call_tool() async def get_tool( name: str, arguments: dict[str, str] | None ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: if arguments is None: arguments = {} try: if name == "search": return await search_tool(arguments) except Exception as e: text = f"Tool {name} failed with error: {e}" return [types.TextContent(type="text", text=text)] raise ValueError(f"Unknown tool: {name}")
- src/mcp_searxng/search.py:40-49 (schema)Pydantic model for parsing the searXNG search API response.class Response(BaseModel): query: str number_of_results: int results: list[SearchResult] # answers: list[str] # corrections: list[str] infoboxes: list[Infobox] # suggestions: list[str] # unresponsive_engines: list[str]
- src/mcp_searxng/search.py:51-81 (helper)Core helper function that queries searXNG API, parses response, and formats results as text.async def search(query: str, limit: int = 3) -> str: client = AsyncClient(base_url=str(getenv("SEARXNG_URL", "http://localhost:8080"))) params: dict[str, str] = {"q": query, "format": "json"} response = await client.get("/search", params=params) response.raise_for_status() data = Response.model_validate_json(response.text) text = "" for index, infobox in enumerate(data.infoboxes): text += f"Infobox: {infobox.infobox}\n" text += f"ID: {infobox.id}\n" text += f"Content: {infobox.content}\n" text += "\n" if len(data.results) == 0: text += "No results found\n" for index, result in enumerate(data.results): text += f"Title: {result.title}\n" text += f"URL: {result.url}\n" text += f"Content: {result.content}\n" text += "\n" if index == limit - 1: break return str(text)