Skip to main content
Glama

web_search

Search the web privately using multiple engines, filter results by category, language, time range, and safe search settings. Ideal for finding general content, news, articles, and media efficiently.

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
categoriesNo
languageNoSearch language code (e.g. 'en', 'zh', 'jp', 'all')all
pageNoPage number (default 1)
queryYesSearch query
safesearchNo0: None, 1: Moderate, 2: Strict
time_rangeNoall_time

Implementation Reference

  • Main request handler for CallToolRequestSchema that executes the web_search tool: validates name and args, performs fallback search, formats and returns results.
    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, }; } });
  • Type guard function for validating web_search input arguments matching the inputSchema.
    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:34-78 (registration)
    Tool registration object defining name, description, and inputSchema for web_search.
    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"] } };
  • Core helper function that performs the actual SearXNG search with fallback across multiple instances.
    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 individual search results into readable text.
    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'); }

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

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