Skip to main content
Glama

web_search

Search the web for general queries, news, articles, and online content using multiple search engines combined, with filtering by categories, languages, time ranges, and safe search settings.

Instructions

Performs a web search using SearXNG, ideal for general queries, news, articles and online content. Supports multiple search categories, languages, time ranges and safe search filtering. Returns relevant results from multiple search engines combined.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query
pageNoPage number (default 1)
languageNoSearch language code (e.g. 'en', 'zh', 'jp', 'all')all
categoriesNo
time_rangeNoall_time
safesearchNo0: None, 1: Moderate, 2: Strict

Implementation Reference

  • src/index.ts:34-78 (registration)
    Tool registration object defining the 'web_search' tool including name, description, and comprehensive input schema for parameters like query, page, language, categories, time_range, and safesearch.
    const WEB_SEARCH_TOOL: Tool = { name: "web_search", description: "Performs a web search using SearXNG, ideal for general queries, news, articles and online content. " + "Supports multiple search categories, languages, time ranges and safe search filtering. " + "Returns relevant results from multiple search engines combined.", inputSchema: { type: "object", properties: { query: { type: "string", description: "Search query" }, page: { type: "number", description: "Page number (default 1)", default: 1 }, language: { type: "string", description: "Search language code (e.g. 'en', 'zh', 'jp', 'all')", default: "all" }, categories: { type: "array", items: { type: "string", enum: ["general", "news", "science", "files", "images", "videos", "music", "social media", "it"] }, default: ["general"] }, time_range: { type: "string", enum: ["all_time", "day", "week", "month", "year"], default: "all_time" }, safesearch: { type: "number", description: "0: None, 1: Moderate, 2: Strict", default: 1 } }, required: ["query"] } };
  • Primary handler function that performs the web search by constructing parameters, sending POST request to SearXNG instances with fallback logic, handling responses, and returning search results.
    async function searchWithFallback(params: any) { const searchParams = { q: params.query, pageno: params.page || 1, language: params.language || 'all', categories: params.categories?.join(',') || 'general', time_range: params.time_range === 'all_time' ? '' : (params.time_range || ''), safesearch: params.safesearch ?? 1, format: 'json' }; for (const instance of SEARXNG_INSTANCES) { try { const searchUrl = new URL('/search', instance); const response = await fetch(searchUrl.toString(), { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': USER_AGENT }, agent: searchUrl.protocol === 'https:' ? httpsAgent : httpAgent, body: new URLSearchParams(searchParams).toString() }); if (!response.ok) { logError(`${instance} returned ${response.status}. Please check if SearXNG is running.`); continue; } const data = await response.json(); if (!data.results?.length) { logError(`${instance} returned no results`); continue; } return data; } catch (error) { logError(`Failed to connect to ${instance}. Please check if SearXNG is running.`, error); continue; } } throw new Error("All SearXNG instances failed. Please ensure SearXNG is running on one of these instances: " + SEARXNG_INSTANCES.join(', ')); }
  • Helper function to format a single search result into a readable multi-line string with title, URL, content, and source.
    function formatSearchResult(result: SearchResult) { const parts = [ `Title: ${result.title}`, `URL: ${result.url}` ]; if (result.content) { parts.push(`Content: ${result.content}`); } if (result.engine) { parts.push(`Source: ${result.engine}`); } return parts.join('\n'); }
  • Schema validation type guard that checks if arguments match the expected web_search input structure, ensuring 'query' is present and a string.
    function isWebSearchArgs(args: unknown): args is { query: string; page?: number; language?: string; categories?: string[]; time_range?: string; safesearch?: number; } { return ( typeof args === "object" && args !== null && "query" in args && typeof (args as { query: string }).query === "string" ); }
  • src/index.ts:181-183 (registration)
    Registers the web_search tool for the listTools MCP request by including it in the tools array response.
    server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [WEB_SEARCH_TOOL] }));
  • MCP CallTool handler that specifically handles 'web_search' calls: validates tool name and args, invokes searchWithFallback, formats results into text response, and handles errors.
    server.setRequestHandler(CallToolRequestSchema, async (request) => { try { const { name, arguments: args } = request.params; if (name !== "web_search" || !args) { throw new Error("Invalid tool or arguments: expected 'web_search'"); } if (!isWebSearchArgs(args)) { throw new Error("Invalid arguments for web_search"); } const results = await searchWithFallback(args); return { content: [{ type: "text", text: results.results.map(formatSearchResult).join('\n\n') }], isError: false, }; } catch (error) { logError('Search failed', error); return { content: [{ type: "text", text: String(error) }], isError: true, }; } });

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/kevinwatt/mcp-server-searxng'

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