web_search
Perform targeted web searches using customizable parameters like query, language, site, and search engines. Retrieve precise results for enhanced local LLM tasks without requiring API keys.
Instructions
Alias of web.search
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| engines | No | ||
| k | No | ||
| lang | No | ||
| limit | No | ||
| max | No | ||
| q | Yes | ||
| site | No |
Implementation Reference
- src/tools/webSearch.ts:57-70 (handler)The core handler function `webSearch` that orchestrates searches across multiple engines (DuckDuckGo and SearXNG), handles promises, deduplicates, and ranks results.export async function webSearch(args: { q: string, max?: number, lang?: string, site?: string, engines?: string[] }): Promise<SearchResult[]> { const { q, max = 10, lang = CONFIG.langDefault, site, engines } = args; const order = (engines && engines.length ? engines : CONFIG.engineOrder).filter(Boolean); const tasks: Promise<SearchResult[]>[] = []; for (const eng of order) { if (eng === 'searxng') tasks.push(searchSearxng(q, lang, site, max)); if (eng === 'duckduckgo') tasks.push(searchDuckDuckGo(q, lang, site, max)); } const settled = await Promise.allSettled(tasks); const all: SearchResult[] = []; for (const s of settled) if (s.status === 'fulfilled') all.push(...s.value); if (!all.length) return []; return dedupeAndRank(all, max); }
- src/server.ts:39-48 (schema)Zod schema for input validation of the web_search tool parameters.const webSearchShape = { q: z.string(), max: z.number().int().optional(), lang: z.string().optional(), site: z.string().optional(), engines: z.array(z.string()).optional(), // extra names model may invent k: z.number().int().optional(), limit: z.number().int().optional() };
- src/server.ts:56-62 (registration)MCP server registration of the 'web_search' tool, invoking the webSearch handler with input schema.server.tool('web_search', 'Alias of web.search', webSearchShape, OPEN, async ({ q, max, lang, site, engines, k, limit }) => { const res = await webSearch({ q, max: max ?? k ?? limit, lang, site, engines }); return { content: [{ type: 'text', text: JSON.stringify(res) }] }; } );
- src/tools/webSearch.ts:5-7 (schema)TypeScript interface defining the structure of search results returned by the tool.export interface SearchResult { title: string; url: string; snippet: string; source: string; rank: number; }
- src/tools/webSearch.ts:9-17 (helper)Helper function to deduplicate search results based on normalized URL and assign ranks.function dedupeAndRank(all: SearchResult[], max: number): SearchResult[] { const seen = new Set<string>(); const out: SearchResult[] = []; for (const item of all) { const key = item.url.replace(/^https?:\/\//,'').replace(/^www\./,'').replace(/\/$/,'').toLowerCase(); if (seen.has(key)) continue; seen.add(key); out.push(item); if (out.length >= max) break; } return out.map((it, i) => ({ ...it, rank: i+1 })); }