Skip to main content
Glama

searxng_web_search

Perform web searches to gather diverse online information, including news, articles, and general queries. Customize results by language, time range, and safe search settings for precise data retrieval.

Instructions

Performs a web search using the SearXNG API, ideal for general queries, news, articles, and online content. Use this for broad information gathering, recent events, or when you need diverse web sources.

Input Schema

NameRequiredDescriptionDefault
languageNoLanguage code for search results (e.g., 'en', 'fr', 'de'). Default is instance-dependent.all
pagenoNoSearch page number (starts at 1)
queryYesThe search query. This is the main input for the web search
safesearchNoSafe search filter level (0: None, 1: Moderate, 2: Strict)0
time_rangeNoTime range of search (day, month, year)

Input Schema (JSON Schema)

{ "properties": { "language": { "default": "all", "description": "Language code for search results (e.g., 'en', 'fr', 'de'). Default is instance-dependent.", "type": "string" }, "pageno": { "default": 1, "description": "Search page number (starts at 1)", "type": "number" }, "query": { "description": "The search query. This is the main input for the web search", "type": "string" }, "safesearch": { "default": "0", "description": "Safe search filter level (0: None, 1: Moderate, 2: Strict)", "enum": [ "0", "1", "2" ], "type": "string" }, "time_range": { "description": "Time range of search (day, month, year)", "enum": [ "day", "month", "year" ], "type": "string" } }, "required": [ "query" ], "type": "object" }

Implementation Reference

  • The primary handler function that executes the searxng_web_search tool logic: constructs SearXNG API request, fetches results, handles errors comprehensively, formats output as text with titles, descriptions, URLs, and scores.
    export async function performWebSearch( server: Server, query: string, pageno: number = 1, time_range?: string, language: string = "all", safesearch?: string ) { const startTime = Date.now(); // Build detailed log message with all parameters const searchParams = [ `page ${pageno}`, `lang: ${language}`, time_range ? `time: ${time_range}` : null, safesearch ? `safesearch: ${safesearch}` : null ].filter(Boolean).join(", "); logMessage(server, "info", `Starting web search: "${query}" (${searchParams})`); const searxngUrl = process.env.SEARXNG_URL; if (!searxngUrl) { logMessage(server, "error", "SEARXNG_URL not configured"); throw createConfigurationError( "SEARXNG_URL not set. Set it to your SearXNG instance (e.g., http://localhost:8080 or https://search.example.com)" ); } // Validate that searxngUrl is a valid URL let parsedUrl: URL; try { parsedUrl = new URL(searxngUrl); } catch (error) { throw createConfigurationError( `Invalid SEARXNG_URL format: ${searxngUrl}. Use format: http://localhost:8080` ); } const url = new URL('/search', parsedUrl); url.searchParams.set("q", query); url.searchParams.set("format", "json"); url.searchParams.set("pageno", pageno.toString()); if ( time_range !== undefined && ["day", "month", "year"].includes(time_range) ) { url.searchParams.set("time_range", time_range); } if (language && language !== "all") { url.searchParams.set("language", language); } if (safesearch !== undefined && ["0", "1", "2"].includes(safesearch)) { url.searchParams.set("safesearch", safesearch); } // Prepare request options with headers const requestOptions: RequestInit = { method: "GET" }; // Add proxy dispatcher if proxy is configured // Node.js fetch uses 'dispatcher' option for proxy, not 'agent' const proxyAgent = createProxyAgent(url.toString()); if (proxyAgent) { (requestOptions as any).dispatcher = proxyAgent; } // Add basic authentication if credentials are provided const username = process.env.AUTH_USERNAME; const password = process.env.AUTH_PASSWORD; if (username && password) { const base64Auth = Buffer.from(`${username}:${password}`).toString('base64'); requestOptions.headers = { ...requestOptions.headers, 'Authorization': `Basic ${base64Auth}` }; } // Add User-Agent header if configured const userAgent = process.env.USER_AGENT; if (userAgent) { requestOptions.headers = { ...requestOptions.headers, 'User-Agent': userAgent }; } // Fetch with enhanced error handling let response: Response; try { logMessage(server, "info", `Making request to: ${url.toString()}`); response = await fetch(url.toString(), requestOptions); } catch (error: any) { logMessage(server, "error", `Network error during search request: ${error.message}`, { query, url: url.toString() }); const context: ErrorContext = { url: url.toString(), searxngUrl, proxyAgent: !!proxyAgent, username }; throw createNetworkError(error, context); } if (!response.ok) { let responseBody: string; try { responseBody = await response.text(); } catch { responseBody = '[Could not read response body]'; } const context: ErrorContext = { url: url.toString(), searxngUrl }; throw createServerError(response.status, response.statusText, responseBody, context); } // Parse JSON response let data: SearXNGWeb; try { data = (await response.json()) as SearXNGWeb; } catch (error: any) { let responseText: string; try { responseText = await response.text(); } catch { responseText = '[Could not read response text]'; } const context: ErrorContext = { url: url.toString() }; throw createJSONError(responseText, context); } if (!data.results) { const context: ErrorContext = { url: url.toString(), query }; throw createDataError(data, context); } const results = data.results.map((result) => ({ title: result.title || "", content: result.content || "", url: result.url || "", score: result.score || 0, })); if (results.length === 0) { logMessage(server, "info", `No results found for query: "${query}"`); return createNoResultsMessage(query); } const duration = Date.now() - startTime; logMessage(server, "info", `Search completed: "${query}" (${searchParams}) - ${results.length} results in ${duration}ms`); return results .map((r) => `Title: ${r.title}\nDescription: ${r.content}\nURL: ${r.url}\nRelevance Score: ${r.score.toFixed(3)}`) .join("\n\n"); }
  • Defines the tool's metadata: name, description, and detailed input schema for parameters like query, page, time_range, language, safesearch.
    export const WEB_SEARCH_TOOL: Tool = { name: "searxng_web_search", description: "Performs a web search using the SearXNG API, ideal for general queries, news, articles, and online content. " + "Use this for broad information gathering, recent events, or when you need diverse web sources.", inputSchema: { type: "object", properties: { query: { type: "string", description: "The search query. This is the main input for the web search", }, pageno: { type: "number", description: "Search page number (starts at 1)", default: 1, }, time_range: { type: "string", description: "Time range of search (day, month, year)", enum: ["day", "month", "year"], }, language: { type: "string", description: "Language code for search results (e.g., 'en', 'fr', 'de'). Default is instance-dependent.", default: "all", }, safesearch: { type: "string", description: "Safe search filter level (0: None, 1: Moderate, 2: Strict)", enum: ["0", "1", "2"], default: "0", }, }, required: ["query"], }, };
  • src/index.ts:87-90 (registration)
    Registers the tool in the MCP server capabilities under tools.searxng_web_search using the schema and description from WEB_SEARCH_TOOL.
    searxng_web_search: { description: WEB_SEARCH_TOOL.description, schema: WEB_SEARCH_TOOL.inputSchema, },
  • src/index.ts:103-104 (registration)
    ListTools handler returns the tool metadata including searxng_web_search.
    return { tools: [WEB_SEARCH_TOOL, READ_URL_TOOL],
  • Type guard function for validating input arguments to the searxng_web_search tool.
    export function isSearXNGWebSearchArgs(args: unknown): args is { query: string; pageno?: number; time_range?: string; language?: string; safesearch?: string; } { return ( typeof args === "object" && args !== null && "query" in args && typeof (args as { query: string }).query === "string" ); }

Other Tools

Related 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/ihor-sokoliuk/mcp-searxng'

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