fast-web-search-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/LICENSE +21 -0
- package/README.md +581 -0
- package/dist/index.js +2540 -0
- package/dist/index.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/defaults.ts","../src/config/environment.ts","../src/observability/logger.ts","../src/config/load-config.ts","../src/server/create-server.ts","../src/schemas/config.schema.ts","../src/http/headers.ts","../src/http/errors.ts","../src/http/client.ts","../src/providers/duckduckgo/duckduckgo.parser.ts","../src/providers/duckduckgo/duckduckgo.provider.ts","../src/providers/bing/bing.parser.ts","../src/providers/bing/bing.provider.ts","../src/cache/memory-cache.ts","../src/cache/cache-key.ts","../src/utils/domains.ts","../src/search/normalize.ts","../src/search/deduplicate.ts","../src/search/rank.ts","../src/search/filters.ts","../src/search/coalescer.ts","../src/search/rate-limiter.ts","../src/search/orchestrator.ts","../src/tools/web-search.tool.ts","../src/fetch/validate-url.ts","../src/fetch/content-types.ts","../src/fetch/extract-main-content.ts","../src/fetch/html-to-markdown.ts","../src/utils/text.ts","../src/fetch/fetch-page.ts","../src/tools/fetch-url.tool.ts","../src/tools/search-and-fetch.tool.ts","../src/tools/news-search.tool.ts","../src/tools/diagnostics.tool.ts","../src/server/register-tools.ts","../src/index.ts"],"names":["logger","detectChallenge","detectRateLimited","cheerio2","URL","providers","cache","result","z","cheerio3","truncated"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Configuration defaults for fast-web-search-mcp.\n *\n * All values here are safe, non-surprising defaults.\n * Environment variables and JSON config can override these.\n */\n\nexport const DEFAULTS = {\n // Server\n logLevel: \"warn\" as const,\n logFormat: \"text\" as const,\n redactQueries: true,\n\n // Search defaults\n defaultRegion: \"us-en\",\n defaultLanguage: \"en\",\n safeSearch: \"moderate\" as const,\n\n // Providers\n providers: [\"duckduckgo\", \"bing\", \"wikipedia\"] as string[],\n providerStrategy: \"fallback\" as const,\n\n // Timeouts (ms)\n searchTimeoutMs: 20_000,\n providerTimeoutMs: 10_000,\n fetchTimeoutMs: 15_000,\n researchTimeoutMs: 45_000,\n\n // Limits\n maxSearchResults: 25,\n maxFetchCharacters: 100_000,\n maxSearchBodyBytes: 3_145_728, // 3 MB\n maxPageBodyBytes: 8_388_608, // 8 MB\n\n // Concurrency\n maxConcurrentSearches: 2,\n maxConcurrentFetches: 3,\n maxOutboundRequests: 4,\n\n // Cache\n cacheEnabled: true,\n searchCacheTtlMs: 120_000, // 2 minutes\n newsCacheTtlMs: 60_000, // 1 minute\n pageCacheTtlMs: 1_800_000, // 30 minutes\n cacheMaxEntries: 250,\n\n // Privacy\n globalExcludeDomains: [] as string[],\n\n // Optional\n searxngUrl: \"\",\n diagnosticsEnabled: false,\n} as const;\n","/**\n * Parse environment variables into configuration values.\n * Handles type coercion from string env vars to typed config.\n */\n\nimport { DEFAULTS } from \"./defaults.js\";\n\ntype LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\ntype LogFormat = \"text\" | \"json\";\ntype SafeSearch = \"off\" | \"moderate\" | \"strict\";\ntype ProviderStrategy = \"fallback\" | \"merge\";\n\ninterface EnvironmentConfig {\n logLevel: LogLevel;\n logFormat: LogFormat;\n redactQueries: boolean;\n defaultRegion: string;\n defaultLanguage: string;\n safeSearch: SafeSearch;\n providers: string[];\n providerStrategy: ProviderStrategy;\n searchTimeoutMs: number;\n providerTimeoutMs: number;\n fetchTimeoutMs: number;\n researchTimeoutMs: number;\n maxSearchResults: number;\n maxFetchCharacters: number;\n maxSearchBodyBytes: number;\n maxPageBodyBytes: number;\n maxConcurrentSearches: number;\n maxConcurrentFetches: number;\n maxOutboundRequests: number;\n cacheEnabled: boolean;\n searchCacheTtlMs: number;\n newsCacheTtlMs: number;\n pageCacheTtlMs: number;\n cacheMaxEntries: number;\n globalExcludeDomains: string[];\n searxngUrl: string;\n diagnosticsEnabled: boolean;\n}\n\nfunction parseBool(value: string | undefined, fallback: boolean): boolean {\n if (value === undefined) return fallback;\n return value === \"true\" || value === \"1\";\n}\n\nfunction parseIntSafe(value: string | undefined, fallback: number): number {\n if (value === undefined) return fallback;\n const parsed = Number.parseInt(value, 10);\n if (Number.isNaN(parsed) || parsed < 0) return fallback;\n return parsed;\n}\n\nfunction parseStringList(value: string | undefined): string[] | undefined {\n if (!value) return undefined;\n const items = value\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n return items.length > 0 ? items : undefined;\n}\n\nexport function parseEnvironment(env: Record<string, string | undefined> = process.env): EnvironmentConfig {\n return {\n logLevel: (env.FWSMCP_LOG_LEVEL as LogLevel) || DEFAULTS.logLevel,\n logFormat: (env.FWSMCP_LOG_FORMAT as LogFormat) || DEFAULTS.logFormat,\n redactQueries: parseBool(env.FWSMCP_REDACT_QUERIES, DEFAULTS.redactQueries),\n defaultRegion: env.FWSMCP_DEFAULT_REGION || DEFAULTS.defaultRegion,\n defaultLanguage: env.FWSMCP_DEFAULT_LANGUAGE || DEFAULTS.defaultLanguage,\n safeSearch: (env.FWSMCP_SAFE_SEARCH as SafeSearch) || DEFAULTS.safeSearch,\n providers: parseStringList(env.FWSMCP_PROVIDERS) || [...DEFAULTS.providers],\n providerStrategy: (env.FWSMCP_PROVIDER_STRATEGY as ProviderStrategy) || DEFAULTS.providerStrategy,\n searchTimeoutMs: parseIntSafe(env.FWSMCP_SEARCH_TIMEOUT_MS, DEFAULTS.searchTimeoutMs),\n providerTimeoutMs: parseIntSafe(env.FWSMCP_PROVIDER_TIMEOUT_MS, DEFAULTS.providerTimeoutMs),\n fetchTimeoutMs: parseIntSafe(env.FWSMCP_FETCH_TIMEOUT_MS, DEFAULTS.fetchTimeoutMs),\n researchTimeoutMs: parseIntSafe(env.FWSMCP_RESEARCH_TIMEOUT_MS, DEFAULTS.researchTimeoutMs),\n maxSearchResults: parseIntSafe(env.FWSMCP_MAX_SEARCH_RESULTS, DEFAULTS.maxSearchResults),\n maxFetchCharacters: parseIntSafe(env.FWSMCP_MAX_FETCH_CHARACTERS, DEFAULTS.maxFetchCharacters),\n maxSearchBodyBytes: parseIntSafe(env.FWSMCP_MAX_SEARCH_BODY_BYTES, DEFAULTS.maxSearchBodyBytes),\n maxPageBodyBytes: parseIntSafe(env.FWSMCP_MAX_PAGE_BODY_BYTES, DEFAULTS.maxPageBodyBytes),\n maxConcurrentSearches: parseIntSafe(env.FWSMCP_MAX_CONCURRENT_SEARCHES, DEFAULTS.maxConcurrentSearches),\n maxConcurrentFetches: parseIntSafe(env.FWSMCP_MAX_CONCURRENT_FETCHES, DEFAULTS.maxConcurrentFetches),\n maxOutboundRequests: parseIntSafe(env.FWSMCP_MAX_OUTBOUND_REQUESTS, DEFAULTS.maxOutboundRequests),\n cacheEnabled: parseBool(env.FWSMCP_CACHE_ENABLED, DEFAULTS.cacheEnabled),\n searchCacheTtlMs: parseIntSafe(env.FWSMCP_SEARCH_CACHE_TTL_MS, DEFAULTS.searchCacheTtlMs),\n newsCacheTtlMs: parseIntSafe(env.FWSMCP_NEWS_CACHE_TTL_MS, DEFAULTS.newsCacheTtlMs),\n pageCacheTtlMs: parseIntSafe(env.FWSMCP_PAGE_CACHE_TTL_MS, DEFAULTS.pageCacheTtlMs),\n cacheMaxEntries: parseIntSafe(env.FWSMCP_CACHE_MAX_ENTRIES, DEFAULTS.cacheMaxEntries),\n globalExcludeDomains: parseStringList(env.FWSMCP_GLOBAL_EXCLUDE_DOMAINS) ?? [],\n searxngUrl: env.FWSMCP_SEARXNG_URL || DEFAULTS.searxngUrl,\n diagnosticsEnabled: parseBool(env.FWSMCP_DIAGNOSTICS_ENABLED, DEFAULTS.diagnosticsEnabled),\n };\n}\n","/**\n * Structured logger that writes to stderr.\n * Never writes to stdout — that's reserved for MCP protocol.\n */\n\ntype LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LOG_LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nexport interface LogEntry {\n level: LogLevel;\n message: string;\n timestamp: string;\n [key: string]: unknown;\n}\n\nexport class Logger {\n private minLevel: number;\n private format: \"text\" | \"json\";\n private redact: boolean;\n\n constructor(options: { level?: LogLevel; format?: \"text\" | \"json\"; redact?: boolean } = {}) {\n this.minLevel = LOG_LEVEL_ORDER[options.level ?? \"warn\"];\n this.format = options.format ?? \"text\";\n this.redact = options.redact ?? true;\n }\n\n private shouldLog(level: LogLevel): boolean {\n return LOG_LEVEL_ORDER[level] >= this.minLevel;\n }\n\n private redactValue(value: unknown): unknown {\n if (!this.redact) return value;\n if (typeof value === \"string\" && value.length > 0) {\n // Redact query-like strings but keep domain-level info\n if (value.length > 30 && !value.includes(\"://\")) {\n return \"[REDACTED]\";\n }\n }\n return value;\n }\n\n private formatText(entry: LogEntry): string {\n const parts = [`${entry.timestamp} [${entry.level.toUpperCase()}]`, entry.message];\n for (const [key, value] of Object.entries(entry)) {\n if (key === \"level\" || key === \"message\" || key === \"timestamp\") continue;\n parts.push(`${key}=${JSON.stringify(this.redactValue(value))}`);\n }\n return parts.join(\" \");\n }\n\n private formatJson(entry: LogEntry): string {\n const cleaned: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(entry)) {\n cleaned[key] = key === \"message\" || key === \"timestamp\" || key === \"level\" ? value : this.redactValue(value);\n }\n return JSON.stringify(cleaned);\n }\n\n private log(level: LogLevel, message: string, data?: Record<string, unknown>): void {\n if (!this.shouldLog(level)) return;\n\n const entry: LogEntry = {\n level,\n message,\n timestamp: new Date().toISOString(),\n ...data,\n };\n\n const formatted = this.format === \"json\" ? this.formatJson(entry) : this.formatText(entry);\n process.stderr.write(formatted + \"\\n\");\n }\n\n debug(message: string, data?: Record<string, unknown>): void {\n this.log(\"debug\", message, data);\n }\n\n info(message: string, data?: Record<string, unknown>): void {\n this.log(\"info\", message, data);\n }\n\n warn(message: string, data?: Record<string, unknown>): void {\n this.log(\"warn\", message, data);\n }\n\n error(message: string, data?: Record<string, unknown>): void {\n this.log(\"error\", message, data);\n }\n}\n\n// Singleton logger instance\nlet loggerInstance: Logger | null = null;\n\nexport function getLogger(options?: { level?: LogLevel; format?: \"text\" | \"json\"; redact?: boolean }): Logger {\n if (!loggerInstance) {\n loggerInstance = new Logger(options);\n }\n return loggerInstance;\n}\n\nexport function resetLogger(): void {\n loggerInstance = null;\n}\n","/**\n * Configuration loader — merges defaults, environment, and optional JSON file.\n */\n\nimport { parseEnvironment } from \"./environment.js\";\nimport { DEFAULTS } from \"./defaults.js\";\nimport { getLogger } from \"../observability/logger.js\";\n\nexport interface AppConfig {\n logLevel: string;\n logFormat: string;\n redactQueries: boolean;\n defaultRegion: string;\n defaultLanguage: string;\n safeSearch: string;\n providers: string[];\n providerStrategy: string;\n searchTimeoutMs: number;\n providerTimeoutMs: number;\n fetchTimeoutMs: number;\n researchTimeoutMs: number;\n maxSearchResults: number;\n maxFetchCharacters: number;\n maxSearchBodyBytes: number;\n maxPageBodyBytes: number;\n maxConcurrentSearches: number;\n maxConcurrentFetches: number;\n maxOutboundRequests: number;\n cacheEnabled: boolean;\n searchCacheTtlMs: number;\n newsCacheTtlMs: number;\n pageCacheTtlMs: number;\n cacheMaxEntries: number;\n globalExcludeDomains: string[];\n searxngUrl: string;\n diagnosticsEnabled: boolean;\n}\n\nexport async function loadConfig(): Promise<AppConfig> {\n const envConfig = parseEnvironment();\n let fileConfig: Record<string, unknown> = {};\n\n // Try to load optional JSON config file\n const configPath = process.env.FWSMCP_CONFIG_FILE;\n if (configPath) {\n try {\n const { readFile } = await import(\"node:fs/promises\");\n const raw = await readFile(configPath, \"utf-8\");\n fileConfig = JSON.parse(raw) as Record<string, unknown>;\n } catch (err) {\n const logger = getLogger();\n logger.warn(\"Failed to load config file, using environment defaults\", {\n path: configPath,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n const defaults = DEFAULTS as unknown as Record<string, unknown>;\n const envConfigRaw = envConfig as unknown as Record<string, unknown>;\n const merged = { ...defaults, ...fileConfig, ...envConfigRaw };\n const config = merged as unknown as AppConfig;\n\n // Log config (redacted)\n const logger = getLogger({ level: config.logLevel as \"debug\" | \"info\" | \"warn\" | \"error\" });\n logger.info(\"Configuration loaded\", {\n providers: config.providers,\n strategy: config.providerStrategy,\n cacheEnabled: config.cacheEnabled,\n diagnosticsEnabled: config.diagnosticsEnabled,\n });\n\n return config;\n}\n","/**\n * Create the MCP server instance with tool registration.\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { getLogger } from \"../observability/logger.js\";\nimport type { AppConfig } from \"../config/load-config.js\";\n\nexport function createServer(_config: AppConfig): McpServer {\n const logger = getLogger();\n\n const server = new McpServer({\n name: \"fast-web-search-mcp\",\n version: \"0.1.0\",\n });\n\n logger.info(\"MCP server created\", {\n name: \"fast-web-search-mcp\",\n version: \"0.1.0\",\n });\n\n return server;\n}\n","/**\n * Zod-based configuration schema for runtime validation.\n */\n\nimport { z } from \"zod\";\n\nexport const LogLevelSchema = z.enum([\"debug\", \"info\", \"warn\", \"error\"]);\nexport const LogFormatSchema = z.enum([\"text\", \"json\"]);\nexport const SafeSearchSchema = z.enum([\"off\", \"moderate\", \"strict\"]);\nexport const ProviderStrategySchema = z.enum([\"fallback\", \"merge\"]);\nexport const TimeRangeSchema = z.enum([\"day\", \"week\", \"month\", \"year\", \"any\"]);\nexport const OutputFormatSchema = z.enum([\"markdown\", \"text\"]);\n\nexport const SearchInputSchema = z.object({\n query: z.string().min(1).max(500),\n max_results: z.number().int().min(1).max(25).default(10),\n providers: z.array(z.string()).optional(),\n strategy: ProviderStrategySchema.default(\"fallback\"),\n region: z.string().default(\"us-en\"),\n language: z.string().default(\"en\"),\n time_range: TimeRangeSchema.default(\"any\"),\n safe_search: SafeSearchSchema.default(\"moderate\"),\n include_domains: z.array(z.string()).max(20).optional(),\n exclude_domains: z.array(z.string()).max(50).optional(),\n deduplicate: z.boolean().default(true),\n timeout_ms: z.number().int().min(1000).max(60_000).optional(),\n});\n\nexport type SearchInput = z.infer<typeof SearchInputSchema>;\n\nexport const NewsSearchInputSchema = z.object({\n query: z.string().min(1).max(500),\n max_results: z.number().int().min(1).max(25).default(10),\n providers: z.array(z.string()).optional(),\n region: z.string().default(\"us-en\"),\n language: z.string().default(\"en\"),\n time_range: z.enum([\"day\", \"week\", \"month\"]).default(\"week\"),\n include_domains: z.array(z.string()).max(20).optional(),\n exclude_domains: z.array(z.string()).max(50).optional(),\n timeout_ms: z.number().int().min(1000).max(60_000).optional(),\n});\n\nexport type NewsSearchInput = z.infer<typeof NewsSearchInputSchema>;\n\nexport const FetchUrlInputSchema = z.object({\n url: z.string().refine(\n (val) => {\n try {\n const url = new URL(val);\n return url.protocol === \"http:\" || url.protocol === \"https:\";\n } catch {\n return false;\n }\n },\n { message: \"Must be a valid HTTP or HTTPS URL\" },\n ),\n output: OutputFormatSchema.default(\"markdown\"),\n max_characters: z.number().int().min(100).max(100_000).default(20_000),\n include_metadata: z.boolean().default(true),\n include_links: z.boolean().default(false),\n timeout_ms: z.number().int().min(1000).max(60_000).optional(),\n});\n\nexport type FetchUrlInput = z.infer<typeof FetchUrlInputSchema>;\n\nexport const SearchAndFetchInputSchema = z.object({\n query: z.string().min(1).max(500),\n search_results: z.number().int().min(1).max(20).default(8),\n fetch_results: z.number().int().min(1).max(5).default(3),\n providers: z.array(z.string()).optional(),\n strategy: ProviderStrategySchema.default(\"fallback\"),\n region: z.string().default(\"us-en\"),\n language: z.string().default(\"en\"),\n time_range: TimeRangeSchema.default(\"any\"),\n include_domains: z.array(z.string()).max(20).optional(),\n exclude_domains: z.array(z.string()).max(50).optional(),\n max_characters_per_page: z.number().int().min(1000).max(100_000).default(20_000),\n total_character_budget: z.number().int().min(1000).max(500_000).default(100_000),\n timeout_ms: z.number().int().min(1000).max(120_000).optional(),\n});\n\nexport type SearchAndFetchInput = z.infer<typeof SearchAndFetchInputSchema>;\n\nexport const DiagnosticsInputSchema = z.object({});\n\n// Output schemas\nexport const SearchResultSchema = z.object({\n position: z.number(),\n title: z.string(),\n url: z.string(),\n display_url: z.string().optional(),\n snippet: z.string().optional(),\n provider: z.string(),\n source_type: z.enum([\"web\", \"news\", \"reference\"]),\n published_at: z.string().optional(),\n crawled_at: z.string().optional(),\n language: z.string().optional(),\n domain: z.string(),\n score: z.number().optional(),\n});\n\nexport type SearchResult = z.infer<typeof SearchResultSchema>;\n\nexport const ProviderAttemptSchema = z.object({\n provider: z.string(),\n success: z.boolean(),\n duration_ms: z.number(),\n result_count: z.number(),\n error: z.string().optional(),\n warnings: z.array(z.string()).optional(),\n});\n\nexport type ProviderAttempt = z.infer<typeof ProviderAttemptSchema>;\n\nexport const WebSearchOutputSchema = z.object({\n query: z.string(),\n results: z.array(SearchResultSchema),\n provider_attempts: z.array(ProviderAttemptSchema),\n cached: z.boolean(),\n partial: z.boolean(),\n warnings: z.array(z.string()),\n duration_ms: z.number(),\n});\n\nexport const FetchedPageSchema = z.object({\n url: z.string(),\n title: z.string().optional(),\n content_type: z.string(),\n content: z.string(),\n character_count: z.number(),\n fetched_at: z.string(),\n warnings: z.array(z.string()),\n});\n\nexport const FetchFailureSchema = z.object({\n url: z.string(),\n error: z.string(),\n code: z.string(),\n});\n\nexport const SearchAndFetchOutputSchema = z.object({\n query: z.string(),\n search_results: z.array(SearchResultSchema),\n pages: z.array(FetchedPageSchema),\n failures: z.array(FetchFailureSchema),\n partial: z.boolean(),\n duration_ms: z.number(),\n});\n","/**\n * Standard HTTP headers for outgoing requests.\n */\n\nexport const DEFAULT_HEADERS: Record<string, string> = {\n Accept: \"text/html,application/xhtml+xml,application/json;q=0.9,text/plain;q=0.8\",\n \"Accept-Language\": \"en-US,en;q=0.8\",\n \"Cache-Control\": \"no-cache\",\n};\n\nexport const USER_AGENT = \"fast-web-search-mcp/0.1 (+local-personal-mcp)\";\n\nexport function getHeaders(customHeaders?: Record<string, string>): Record<string, string> {\n return {\n ...DEFAULT_HEADERS,\n \"User-Agent\": USER_AGENT,\n ...customHeaders,\n };\n}\n","/**\n * HTTP error types for structured error handling.\n */\n\nexport class HttpError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly url: string,\n public readonly retryable: boolean = false,\n ) {\n super(message);\n this.name = \"HttpError\";\n }\n}\n\nexport class HttpTimeoutError extends Error {\n constructor(\n message: string,\n public readonly url: string,\n public readonly timeoutMs: number,\n ) {\n super(message);\n this.name = \"HttpTimeoutError\";\n }\n}\n\nexport class HttpBodyLimitError extends Error {\n constructor(\n message: string,\n public readonly url: string,\n public readonly limitBytes: number,\n ) {\n super(message);\n this.name = \"HttpBodyLimitError\";\n }\n}\n\nexport class HttpRedirectError extends Error {\n constructor(\n message: string,\n public readonly url: string,\n public readonly redirectCount: number,\n ) {\n super(message);\n this.name = \"HttpRedirectError\";\n }\n}\n","/**\n * Shared HTTP client wrapper.\n * Uses Node's built-in fetch with structured error handling.\n */\n\nimport { getHeaders } from \"./headers.js\";\nimport { HttpError, HttpTimeoutError, HttpBodyLimitError, HttpRedirectError } from \"./errors.js\";\nimport { getLogger } from \"../observability/logger.js\";\n\nexport interface HttpRequestOptions {\n url: string;\n method?: string;\n headers?: Record<string, string>;\n timeoutMs?: number;\n maxBodyBytes?: number;\n redirect?: \"follow\" | \"error\" | \"manual\";\n maxRedirects?: number;\n}\n\nexport interface HttpResponse {\n status: number;\n headers: Headers;\n body: string;\n finalUrl: string;\n}\n\n/**\n * Fetch a URL with timeout, size limit, and structured error handling.\n */\nexport async function httpFetch(options: HttpRequestOptions): Promise<HttpResponse> {\n const logger = getLogger();\n const {\n url,\n method = \"GET\",\n timeoutMs = 15_000,\n maxBodyBytes = 8_388_608, // 8 MB\n maxRedirects = 5,\n } = options;\n\n const headers = getHeaders(options.headers);\n\n logger.debug(\"HTTP request\", { url: new URL(url).hostname, method });\n\n const controller = new AbortController();\n const timeoutHandle = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n let currentUrl = url;\n let redirectCount = 0;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const response = await fetch(currentUrl, {\n method,\n headers,\n signal: controller.signal,\n redirect: \"manual\", // We handle redirects manually for validation\n });\n\n // Handle redirects\n if (response.status >= 300 && response.status < 400) {\n redirectCount++;\n if (redirectCount > maxRedirects) {\n throw new HttpRedirectError(\n `Too many redirects (${redirectCount})`,\n url,\n redirectCount,\n );\n }\n\n const location = response.headers.get(\"location\");\n if (!location) {\n throw new HttpError(\"Redirect without Location header\", response.status, url);\n }\n\n // Resolve relative redirects\n try {\n const redirectUrl = new URL(location, currentUrl);\n currentUrl = redirectUrl.toString();\n } catch {\n throw new HttpError(\"Invalid redirect URL\", response.status, url);\n }\n\n logger.debug(\"HTTP redirect\", { from: new URL(url).hostname, to: new URL(currentUrl).hostname });\n continue;\n }\n\n // Check status\n if (!response.ok) {\n const retryable = response.status === 429 || response.status >= 500;\n throw new HttpError(\n `HTTP ${response.status}: ${response.statusText}`,\n response.status,\n url,\n retryable,\n );\n }\n\n // Read body with size limit\n const contentLength = response.headers.get(\"content-length\");\n if (contentLength && Number.parseInt(contentLength, 10) > maxBodyBytes) {\n throw new HttpBodyLimitError(\n `Response body exceeds ${maxBodyBytes} bytes`,\n url,\n maxBodyBytes,\n );\n }\n\n const reader = response.body?.getReader();\n if (!reader) {\n return {\n status: response.status,\n headers: response.headers,\n body: \"\",\n finalUrl: currentUrl,\n };\n }\n\n const chunks: Uint8Array[] = [];\n let totalBytes = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n totalBytes += value.length;\n if (totalBytes > maxBodyBytes) {\n reader.cancel();\n throw new HttpBodyLimitError(\n `Response body exceeds ${maxBodyBytes} bytes`,\n url,\n maxBodyBytes,\n );\n }\n\n chunks.push(value);\n }\n\n const body = new TextDecoder().decode(Buffer.concat(chunks));\n\n return {\n status: response.status,\n headers: response.headers,\n body,\n finalUrl: currentUrl,\n };\n }\n\n // Unreachable but satisfies TypeScript\n throw new HttpError(\"Unexpected end of redirect chain\", 0, url);\n } catch (err) {\n if (err instanceof HttpError || err instanceof HttpTimeoutError || err instanceof HttpBodyLimitError || err instanceof HttpRedirectError) {\n throw err;\n }\n\n if (err instanceof DOMException && err.name === \"AbortError\") {\n throw new HttpTimeoutError(`Request timed out after ${timeoutMs}ms`, url, timeoutMs);\n }\n\n throw new HttpError(\n `Network error: ${err instanceof Error ? err.message : String(err)}`,\n 0,\n url,\n true,\n );\n } finally {\n clearTimeout(timeoutHandle);\n }\n}\n","/**\n * DuckDuckGo HTML parser — extracts search results from HTML response.\n *\n * Uses cheerio for fast HTML parsing.\n * Supports both standard result pages and lite HTML endpoint.\n */\n\nimport * as cheerio from \"cheerio\";\nimport type { RawSearchResult } from \"../provider.interface.js\";\n\nexport interface ParseResult {\n results: RawSearchResult[];\n hasChallenge: boolean;\n isRateLimited: boolean;\n isEmpty: boolean;\n warnings: string[];\n}\n\n/**\n * Detect CAPTCHA or bot challenge pages.\n */\nfunction detectChallenge($: cheerio.CheerioAPI): boolean {\n // Common challenge indicators\n const challengeSelectors = [\n \"#challenge-form\",\n \".challenge-form\",\n '[id*=\"captcha\"]',\n '[class*=\"captcha\"]',\n \"#botchallenge\",\n \".bot-detect\",\n ];\n\n for (const selector of challengeSelectors) {\n if ($(selector).length > 0) return true;\n }\n\n // Check page text for challenge messages\n const bodyText = $(\"body\").text().toLowerCase();\n const challengePhrases = [\n \"please confirm you are human\",\n \"bot detected\",\n \"access denied\",\n \"please verify\",\n \"unusual traffic\",\n \"automated queries\",\n ];\n\n for (const phrase of challengePhrases) {\n if (bodyText.includes(phrase)) return true;\n }\n\n return false;\n}\n\n/**\n * Detect rate limiting pages.\n */\nfunction detectRateLimited($: cheerio.CheerioAPI): boolean {\n const bodyText = $(\"body\").text().toLowerCase();\n return bodyText.includes(\"too many requests\") || bodyText.includes(\"rate limit\");\n}\n\n/**\n * Parse DuckDuckGo HTML search results.\n */\nexport function parseDuckDuckGoHtml(html: string): ParseResult {\n const $ = cheerio.load(html);\n const warnings: string[] = [];\n\n // Check for challenges\n if (detectChallenge($)) {\n return {\n results: [],\n hasChallenge: true,\n isRateLimited: false,\n isEmpty: false,\n warnings: [\"DuckDuckGo challenge/captcha detected\"],\n };\n }\n\n if (detectRateLimited($)) {\n return {\n results: [],\n hasChallenge: false,\n isRateLimited: true,\n isEmpty: false,\n warnings: [\"DuckDuckGo rate limit detected\"],\n };\n }\n\n const results: RawSearchResult[] = [];\n\n // DuckDuckGo HTML results are in .result or .web-result elements\n // Try multiple selectors for resilience\n const resultSelectors = [\".result\", \".web-result\", \".nrn-react-div\"];\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let $results: ReturnType<typeof $> = $([]);\n for (const selector of resultSelectors) {\n $results = $(selector);\n if ($results.length > 0) break;\n }\n\n $results.each((_index, element) => {\n const $el = $(element);\n\n // Extract title and URL\n const $link = $el.find(\"a[href]\").first();\n const href = $link.attr(\"href\");\n const title = $el.find(\"a.result__a, a.result-link, h2 a, .result__title a\").first().text().trim();\n\n if (!title || !href) return;\n\n // DuckDuckGo wraps URLs through redirects — extract the actual URL\n let url = href;\n if (href.includes(\"//duckduckgo.com/l/\")) {\n // DDG redirect wrapper — extract the actual URL from the 'uddg' parameter\n try {\n const ddgUrl = new URL(href, \"https://duckduckgo.com\");\n const actualUrl = ddgUrl.searchParams.get(\"uddg\");\n if (actualUrl) {\n url = decodeURIComponent(actualUrl);\n }\n } catch {\n // Keep original URL if parsing fails\n }\n }\n\n // Extract snippet\n const snippet = $el\n .find(\".result__snippet, .result__body, .snippet\")\n .first()\n .text()\n .trim();\n\n // Extract display URL\n const displayUrl = $el.find(\".result__url, .result__display-url\").first().text().trim();\n\n results.push({\n title,\n url,\n snippet: snippet || undefined,\n displayUrl: displayUrl || undefined,\n });\n });\n\n // If no results found with primary selectors, try a more generic approach\n if (results.length === 0) {\n // Try to find links in the main content area\n const $main = $(\"body\");\n $main.find(\"a[href]\").each((_index, element) => {\n const $a = $(element);\n const href = $a.attr(\"href\");\n const text = $a.text().trim();\n\n // Skip navigation, footer, and DuckDuckGo internal links\n if (!href || !text || text.length < 5) return;\n if (href.startsWith(\"/\") || href.includes(\"duckduckgo.com\")) return;\n if (href.includes(\"javascript:\")) return;\n\n // Skip very short titles (likely UI elements)\n if (text.length < 10) return;\n\n // Check if this looks like a search result\n try {\n const urlObj = new URL(href);\n if (urlObj.protocol === \"http:\" || urlObj.protocol === \"https:\") {\n results.push({\n title: text,\n url: href,\n });\n }\n } catch {\n // Skip invalid URLs\n }\n });\n\n if (results.length === 0) {\n warnings.push(\"No results found — page structure may have changed\");\n }\n }\n\n return {\n results: results.slice(0, 25), // Cap at 25\n hasChallenge: false,\n isRateLimited: false,\n isEmpty: results.length === 0,\n warnings,\n };\n}\n","/**\n * DuckDuckGo HTML endpoint adapter.\n */\n\nimport type {\n SearchProvider,\n ProviderCapabilities,\n ProviderContext,\n ProviderSearchRequest,\n ProviderSearchResponse,\n} from \"../provider.interface.js\";\nimport { httpFetch } from \"../../http/client.js\";\nimport { parseDuckDuckGoHtml } from \"./duckduckgo.parser.js\";\nimport { getLogger } from \"../../observability/logger.js\";\n\nexport class DuckDuckGoProvider implements SearchProvider {\n readonly id = \"duckduckgo\";\n readonly displayName = \"DuckDuckGo\";\n readonly capabilities: ProviderCapabilities = {\n web: true,\n news: false,\n images: false,\n timeRange: true,\n region: true,\n language: true,\n safeSearch: true,\n siteFilter: false, // DDG uses !bang syntax, not site: operator in HTML\n };\n\n isConfigured(): boolean {\n return true; // Always available — no API key needed\n }\n\n private buildSearchUrl(request: ProviderSearchRequest, context: ProviderContext): string {\n const params = new URLSearchParams();\n\n params.set(\"q\", request.query);\n\n // Region mapping for DDG\n const region = request.region || context.region;\n if (region) {\n params.set(\"kl\", region);\n }\n\n // Safe search\n const safeSearch = request.safeSearch || context.safeSearch;\n if (safeSearch === \"strict\") {\n params.set(\"kp\", \"1\");\n } else if (safeSearch === \"moderate\") {\n params.set(\"kp\", \"-2\");\n }\n\n // Time range\n if (request.timeRange && request.timeRange !== \"any\") {\n const dfMap: Record<string, string> = {\n day: \"d\",\n week: \"w\",\n month: \"m\",\n year: \"y\",\n };\n const df = dfMap[request.timeRange];\n if (df) {\n params.set(\"df\", df);\n }\n }\n\n return `https://html.duckduckgo.com/html/?${params.toString()}`;\n }\n\n async search(\n request: ProviderSearchRequest,\n context: ProviderContext,\n ): Promise<ProviderSearchResponse> {\n const logger = getLogger();\n const startTime = Date.now();\n const warnings: string[] = [];\n\n const url = this.buildSearchUrl(request, context);\n logger.debug(\"DuckDuckGo request\", { url: new URL(url).hostname, query: \"[REDACTED]\" });\n\n try {\n const response = await httpFetch({\n url,\n timeoutMs: context.timeoutMs,\n maxBodyBytes: 3_145_728, // 3 MB\n headers: {\n \"User-Agent\":\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36\",\n },\n });\n\n const parseResult = parseDuckDuckGoHtml(response.body);\n\n if (parseResult.hasChallenge) {\n logger.warn(\"DuckDuckGo challenge detected\");\n return {\n provider: this.id,\n results: [],\n durationMs: Date.now() - startTime,\n warnings: [\"DuckDuckGo returned a challenge/captcha page\"],\n metadata: { challenge: true },\n };\n }\n\n if (parseResult.isRateLimited) {\n logger.warn(\"DuckDuckGo rate limit detected\");\n return {\n provider: this.id,\n results: [],\n durationMs: Date.now() - startTime,\n warnings: [\"DuckDuckGo rate limit reached\"],\n metadata: { rateLimited: true },\n };\n }\n\n warnings.push(...parseResult.warnings);\n\n // Apply domain filters if provided\n let filteredResults = parseResult.results;\n if (request.includeDomains && request.includeDomains.length > 0) {\n filteredResults = filteredResults.filter((r) => {\n try {\n const hostname = new URL(r.url).hostname.toLowerCase();\n return request.includeDomains!.some(\n (d) => hostname === d.toLowerCase() || hostname.endsWith(\".\" + d.toLowerCase()),\n );\n } catch {\n return false;\n }\n });\n }\n\n if (request.excludeDomains && request.excludeDomains.length > 0) {\n filteredResults = filteredResults.filter((r) => {\n try {\n const hostname = new URL(r.url).hostname.toLowerCase();\n return !request.excludeDomains!.some(\n (d) => hostname === d.toLowerCase() || hostname.endsWith(\".\" + d.toLowerCase()),\n );\n } catch {\n return true; // Keep if URL parsing fails\n }\n });\n }\n\n // Limit results\n const limitedResults = filteredResults.slice(0, request.maxResults);\n\n logger.info(\"DuckDuckGo search completed\", {\n resultCount: limitedResults.length,\n durationMs: Date.now() - startTime,\n });\n\n return {\n provider: this.id,\n results: limitedResults,\n durationMs: Date.now() - startTime,\n warnings,\n };\n } catch (err) {\n const durationMs = Date.now() - startTime;\n logger.error(\"DuckDuckGo search failed\", {\n error: err instanceof Error ? err.message : String(err),\n durationMs,\n });\n\n return {\n provider: this.id,\n results: [],\n durationMs,\n warnings: [`DuckDuckGo request failed: ${err instanceof Error ? err.message : String(err)}`],\n metadata: { error: true },\n };\n }\n }\n}\n","/**\n * Bing HTML parser — extracts search results from Bing HTML responses.\n */\n\nimport * as cheerio from \"cheerio\";\nimport type { RawSearchResult } from \"../provider.interface.js\";\n\nexport interface BingParseResult {\n results: RawSearchResult[];\n hasChallenge: boolean;\n isRateLimited: boolean;\n isEmpty: boolean;\n warnings: string[];\n}\n\nfunction detectChallenge($: cheerio.CheerioAPI): boolean {\n const bodyText = $(\"body\").text().toLowerCase();\n const challengePhrases = [\n \"please complete the security check\",\n \"are you a human\",\n \"verify you are human\",\n \"unusual traffic\",\n \"bot detection\",\n ];\n for (const phrase of challengePhrases) {\n if (bodyText.includes(phrase)) return true;\n }\n return false;\n}\n\nfunction detectRateLimited($: cheerio.CheerioAPI): boolean {\n const bodyText = $(\"body\").text().toLowerCase();\n return bodyText.includes(\"too many requests\") || bodyText.includes(\"rate limit\");\n}\n\n/**\n * Parse Bing HTML search results.\n */\nexport function parseBingHtml(html: string): BingParseResult {\n const $ = cheerio.load(html);\n const warnings: string[] = [];\n\n if (detectChallenge($)) {\n return {\n results: [],\n hasChallenge: true,\n isRateLimited: false,\n isEmpty: false,\n warnings: [\"Bing challenge/captcha detected\"],\n };\n }\n\n if (detectRateLimited($)) {\n return {\n results: [],\n hasChallenge: false,\n isRateLimited: true,\n isEmpty: false,\n warnings: [\"Bing rate limit detected\"],\n };\n }\n\n const results: RawSearchResult[] = [];\n\n // Bing result selectors — try multiple for resilience\n const selectors = [\"li.b_algo\", \".b_algo\", \"li.b_algo h2 a\"];\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let $items: ReturnType<typeof $> = $([]);\n for (const selector of selectors) {\n if (selector.includes(\" a\")) {\n // For link selectors, find parent containers first\n $items = $(selector.replace(/ a$/, \"\")).filter(\"li.b_algo, .b_algo\");\n } else {\n $items = $(selector);\n }\n if ($items.length > 0) break;\n }\n\n // If we didn't find items with specific selectors, try a broader approach\n if ($items.length === 0) {\n // Look for common Bing result structures\n $items = $(\".b_algo\");\n }\n\n $items.each((_index, element) => {\n const $el = $(element);\n\n // Extract title and URL from the main link\n const $link = $el.find(\"h2 a\").first();\n const href = $link.attr(\"href\");\n const title = $link.text().trim();\n\n if (!title || !href) return;\n\n // Validate URL\n let url = href;\n try {\n const urlObj = new URL(href);\n if (urlObj.protocol !== \"http:\" && urlObj.protocol !== \"https:\") {\n return;\n }\n url = urlObj.toString();\n } catch {\n return; // Skip invalid URLs\n }\n\n // Extract snippet\n const snippet = $el.find(\".b_caption p, .b_lineclamp2, .b_algoSlug\").first().text().trim();\n\n // Extract display URL\n const displayUrl = $el.find(\".b_attribution cite, .tptt\").first().text().trim();\n\n results.push({\n title,\n url,\n snippet: snippet || undefined,\n displayUrl: displayUrl || undefined,\n });\n });\n\n if (results.length === 0) {\n warnings.push(\"No results found — Bing page structure may have changed\");\n }\n\n return {\n results: results.slice(0, 25),\n hasChallenge: false,\n isRateLimited: false,\n isEmpty: results.length === 0,\n warnings,\n };\n}\n","/**\n * Bing HTML search endpoint adapter.\n */\n\nimport type {\n SearchProvider,\n ProviderCapabilities,\n ProviderContext,\n ProviderSearchRequest,\n ProviderSearchResponse,\n} from \"../provider.interface.js\";\nimport { httpFetch } from \"../../http/client.js\";\nimport { parseBingHtml } from \"./bing.parser.js\";\nimport { getLogger } from \"../../observability/logger.js\";\n\nexport class BingProvider implements SearchProvider {\n readonly id = \"bing\";\n readonly displayName = \"Bing\";\n readonly capabilities: ProviderCapabilities = {\n web: true,\n news: false,\n images: false,\n timeRange: true,\n region: false,\n language: false,\n safeSearch: true,\n siteFilter: true, // Bing supports site: operator\n };\n\n isConfigured(): boolean {\n return true; // Always available — no API key needed for HTML endpoint\n }\n\n private buildSearchUrl(request: ProviderSearchRequest, context: ProviderContext): string {\n const params = new URLSearchParams();\n\n let query = request.query;\n\n // Add site: filter if include_domains specified\n if (request.includeDomains && request.includeDomains.length > 0) {\n const siteFilter = request.includeDomains.map((d) => `site:${d}`).join(\" OR \");\n query = `(${siteFilter}) ${query}`;\n }\n\n params.set(\"q\", query);\n\n // Safe search — Bing uses 'adlt' parameter (adult level)\n const safeSearch = request.safeSearch || context.safeSearch;\n if (safeSearch === \"strict\") {\n params.set(\"adlt\", \"strict\");\n } else if (safeSearch === \"off\") {\n params.set(\"adlt\", \"off\");\n }\n // moderate is Bing's default, no parameter needed\n\n // Count\n params.set(\"count\", String(Math.min(request.maxResults, 20)));\n\n return `https://www.bing.com/search?${params.toString()}`;\n }\n\n async search(\n request: ProviderSearchRequest,\n context: ProviderContext,\n ): Promise<ProviderSearchResponse> {\n const logger = getLogger();\n const startTime = Date.now();\n const warnings: string[] = [];\n\n const url = this.buildSearchUrl(request, context);\n logger.debug(\"Bing request\", { url: new URL(url).hostname, query: \"[REDACTED]\" });\n\n try {\n const response = await httpFetch({\n url,\n timeoutMs: context.timeoutMs,\n maxBodyBytes: 3_145_728, // 3 MB\n });\n\n const parseResult = parseBingHtml(response.body);\n\n if (parseResult.hasChallenge) {\n logger.warn(\"Bing challenge detected\");\n return {\n provider: this.id,\n results: [],\n durationMs: Date.now() - startTime,\n warnings: [\"Bing returned a challenge/captcha page\"],\n metadata: { challenge: true },\n };\n }\n\n if (parseResult.isRateLimited) {\n logger.warn(\"Bing rate limit detected\");\n return {\n provider: this.id,\n results: [],\n durationMs: Date.now() - startTime,\n warnings: [\"Bing rate limit reached\"],\n metadata: { rateLimited: true },\n };\n }\n\n warnings.push(...parseResult.warnings);\n\n // Apply exclude filter (include is handled by site: query operator)\n let filteredResults = parseResult.results;\n if (request.excludeDomains && request.excludeDomains.length > 0) {\n filteredResults = filteredResults.filter((r) => {\n try {\n const hostname = new URL(r.url).hostname.toLowerCase();\n return !request.excludeDomains!.some(\n (d) => hostname === d.toLowerCase() || hostname.endsWith(\".\" + d.toLowerCase()),\n );\n } catch {\n return true;\n }\n });\n }\n\n const limitedResults = filteredResults.slice(0, request.maxResults);\n\n logger.info(\"Bing search completed\", {\n resultCount: limitedResults.length,\n durationMs: Date.now() - startTime,\n });\n\n return {\n provider: this.id,\n results: limitedResults,\n durationMs: Date.now() - startTime,\n warnings,\n };\n } catch (err) {\n const durationMs = Date.now() - startTime;\n logger.error(\"Bing search failed\", {\n error: err instanceof Error ? err.message : String(err),\n durationMs,\n });\n\n return {\n provider: this.id,\n results: [],\n durationMs,\n warnings: [`Bing request failed: ${err instanceof Error ? err.message : String(err)}`],\n metadata: { error: true },\n };\n }\n }\n}\n","/**\n * In-memory LRU cache with TTL and max-entries eviction.\n * No native dependencies — pure TypeScript.\n */\n\nimport type { Cache, CacheGetResult, CacheEntry } from \"./cache.interface.js\";\n\ninterface LRUNode<T> {\n key: string;\n entry: CacheEntry<T>;\n prev: LRUNode<T> | null;\n next: LRUNode<T> | null;\n}\n\nexport class MemoryCache<T> implements Cache<T> {\n private map = new Map<string, LRUNode<T>>();\n private head: LRUNode<T> | null = null;\n private tail: LRUNode<T> | null = null;\n private _maxEntries: number;\n\n constructor(maxEntries: number = 250) {\n this._maxEntries = maxEntries;\n }\n\n get size(): number {\n return this.map.size;\n }\n\n get(key: string): CacheGetResult<T> | undefined {\n const node = this.map.get(key);\n if (!node) return undefined;\n\n // Check TTL\n if (Date.now() > node.entry.expiresAt) {\n this.removeNode(node);\n this.map.delete(key);\n return undefined;\n }\n\n // Move to front (most recently used)\n this.moveToFront(node);\n\n return {\n hit: true,\n value: node.entry.value,\n age: Date.now() - node.entry.createdAt,\n };\n }\n\n set(key: string, value: T, ttlMs: number): void {\n const existingNode = this.map.get(key);\n if (existingNode) {\n // Update existing\n existingNode.entry = {\n value,\n expiresAt: Date.now() + ttlMs,\n createdAt: Date.now(),\n };\n this.moveToFront(existingNode);\n return;\n }\n\n // Create new node\n const node: LRUNode<T> = {\n key,\n entry: {\n value,\n expiresAt: Date.now() + ttlMs,\n createdAt: Date.now(),\n },\n prev: null,\n next: null,\n };\n\n this.map.set(key, node);\n this.addToFront(node);\n\n // Evict if over capacity\n while (this.map.size > this._maxEntries && this.tail) {\n const tailKey = this.tail.key;\n this.removeNode(this.tail);\n this.map.delete(tailKey);\n }\n }\n\n delete(key: string): boolean {\n const node = this.map.get(key);\n if (!node) return false;\n this.removeNode(node);\n this.map.delete(key);\n return true;\n }\n\n has(key: string): boolean {\n const node = this.map.get(key);\n if (!node) return false;\n if (Date.now() > node.entry.expiresAt) {\n this.removeNode(node);\n this.map.delete(key);\n return false;\n }\n return true;\n }\n\n clear(): void {\n this.map.clear();\n this.head = null;\n this.tail = null;\n }\n\n private addToFront(node: LRUNode<T>): void {\n node.prev = null;\n node.next = this.head;\n if (this.head) {\n this.head.prev = node;\n }\n this.head = node;\n if (!this.tail) {\n this.tail = node;\n }\n }\n\n private removeNode(node: LRUNode<T>): void {\n if (node.prev) {\n node.prev.next = node.next;\n } else {\n this.head = node.next;\n }\n if (node.next) {\n node.next.prev = node.prev;\n } else {\n this.tail = node.prev;\n }\n node.prev = null;\n node.next = null;\n }\n\n private moveToFront(node: LRUNode<T>): void {\n if (node === this.head) return;\n this.removeNode(node);\n this.addToFront(node);\n }\n}\n","/**\n * Cache key generation — deterministic keys for search and fetch operations.\n */\n\n/**\n * Generate a cache key for a search operation.\n */\nexport function generateSearchCacheKey(params: {\n toolKind: string;\n query: string;\n maxResults: number;\n providers?: string[];\n strategy: string;\n region: string;\n language: string;\n timeRange: string;\n safeSearch: string;\n includeDomains?: string[];\n excludeDomains?: string[];\n}): string {\n const parts = [\n params.toolKind,\n params.query.toLowerCase().replace(/\\s+/g, \" \").trim(),\n `n${params.maxResults}`,\n `s${params.strategy}`,\n `r${params.region}`,\n `l${params.language}`,\n `t${params.timeRange}`,\n `ss${params.safeSearch}`,\n ];\n\n if (params.providers && params.providers.length > 0) {\n parts.push(`p${params.providers.sort().join(\",\")}`);\n }\n\n if (params.includeDomains && params.includeDomains.length > 0) {\n parts.push(`inc${params.includeDomains.sort().join(\",\")}`);\n }\n\n if (params.excludeDomains && params.excludeDomains.length > 0) {\n parts.push(`exc${params.excludeDomains.sort().join(\",\")}`);\n }\n\n return parts.join(\":\");\n}\n\n/**\n * Generate a cache key for a fetch operation.\n */\nexport function generateFetchCacheKey(params: {\n url: string;\n output: string;\n maxCharacters: number;\n}): string {\n const normalizedUrl = params.url\n .toLowerCase()\n .replace(/#.*$/, \"\")\n .replace(/\\/$/, \"\");\n return `fetch:${normalizedUrl}:${params.output}:${params.maxCharacters}`;\n}\n","/**\n * Domain utility functions for URL analysis and filtering.\n */\n\nimport { URL } from \"node:url\";\n\n/**\n * Extract registrable domain from a URL.\n * Simple heuristic for v1: uses the last two segments before the TLD for common domains,\n * or the last three for ccTLDs.\n */\nexport function extractDomain(urlString: string): string {\n try {\n const url = new URL(urlString);\n return url.hostname.toLowerCase();\n } catch {\n return \"\";\n }\n}\n\n/**\n * Check if a domain matches a filter domain (exact or subdomain match).\n */\nexport function domainMatchesFilter(domain: string, filterDomain: string): boolean {\n const normalizedDomain = domain.toLowerCase();\n const normalizedFilter = filterDomain.toLowerCase();\n return normalizedDomain === normalizedFilter || normalizedDomain.endsWith(\".\" + normalizedFilter);\n}\n\n/**\n * Check if a domain is in a list of domains.\n */\nexport function domainInList(domain: string, domains: string[]): boolean {\n return domains.some((d) => domainMatchesFilter(domain, d));\n}\n\n/**\n * Remove common tracking parameters from a URL.\n */\nconst TRACKING_PARAMS = new Set([\n \"utm_source\",\n \"utm_medium\",\n \"utm_campaign\",\n \"utm_term\",\n \"utm_content\",\n \"utm_id\",\n \"utm_cid\",\n \"gclid\",\n \"fbclid\",\n \"mc_cid\",\n \"mc_eid\",\n \"msclkid\",\n \"twclid\",\n \"li_fat_id\",\n \"igshid\",\n \"yclid\",\n]);\n\nexport function removeTrackingParams(urlString: string): string {\n try {\n const url = new URL(urlString);\n const paramsToDelete: string[] = [];\n url.searchParams.forEach((_value, key) => {\n if (TRACKING_PARAMS.has(key.toLowerCase())) {\n paramsToDelete.push(key);\n }\n });\n for (const key of paramsToDelete) {\n url.searchParams.delete(key);\n }\n return url.toString();\n } catch {\n return urlString;\n }\n}\n\n/**\n * Canonicalize a URL for deduplication purposes.\n */\nexport function canonicalizeUrl(urlString: string): string {\n try {\n const url = new URL(urlString);\n\n // Lowercase host\n url.hostname = url.hostname.toLowerCase();\n\n // Remove fragment\n url.hash = \"\";\n\n // Remove default ports\n if ((url.protocol === \"http:\" && url.port === \"80\") || (url.protocol === \"https:\" && url.port === \"443\")) {\n url.port = \"\";\n }\n\n // Remove trailing slash from path (except root)\n if (url.pathname !== \"/\" && url.pathname.endsWith(\"/\")) {\n url.pathname = url.pathname.slice(0, -1);\n }\n\n // Remove tracking params\n const cleaned = removeTrackingParams(url.toString());\n\n return cleaned;\n } catch {\n return urlString;\n }\n}\n\n// RFC1918 and other private ranges\nconst PRIVATE_IP_PATTERNS = [\n /^127\\./, // Loopback\n /^10\\./, // Class A private\n /^172\\.(1[6-9]|2\\d|3[01])\\./, // Class B private\n /^192\\.168\\./, // Class C private\n /^169\\.254\\./, // Link-local\n /^0\\./, // Current network\n /^100\\.(6[4-9]|[7-9]\\d|1[01]\\d|12[0-7])\\./, // Carrier-grade NAT\n /^192\\.0\\.0\\./, // IETF protocol assignments\n /^192\\.0\\.2\\./, // Documentation (TEST-NET-1)\n /^198\\.51\\.100\\./, // Documentation (TEST-NET-2)\n /^203\\.0\\.113\\./, // Documentation (TEST-NET-3)\n /^224\\./, // Multicast\n /^240\\./, // Reserved\n];\n\nconst PRIVATE_HOSTS = new Set([\"localhost\", \"localhost.\", \"*.localhost\"]);\n\n/**\n * Check if a hostname is a private/reserved address.\n */\nexport function isPrivateHost(hostname: string): boolean {\n const lower = hostname.toLowerCase();\n\n // Check exact matches\n if (PRIVATE_HOSTS.has(lower) || lower.endsWith(\".localhost\")) {\n return true;\n }\n\n // Check IPv6 loopback\n if (lower === \"::1\" || lower === \"[::1]\") {\n return true;\n }\n\n // Check IPv4 patterns\n for (const pattern of PRIVATE_IP_PATTERNS) {\n if (pattern.test(lower)) {\n return true;\n }\n }\n\n return false;\n}\n","/**\n * Search result normalization — converts raw provider results to normalized schema.\n */\n\nimport type { RawSearchResult } from \"../providers/provider.interface.js\";\nimport type { SearchResult } from \"../schemas/config.schema.js\";\nimport { canonicalizeUrl, extractDomain } from \"../utils/domains.js\";\n\nexport interface NormalizeOptions {\n provider: string;\n sourceType: \"web\" | \"news\" | \"reference\";\n startIndex?: number;\n}\n\n/**\n * Normalize raw results from a provider into the standard SearchResult schema.\n */\nexport function normalizeResults(\n rawResults: RawSearchResult[],\n options: NormalizeOptions,\n): SearchResult[] {\n const { provider, sourceType, startIndex = 0 } = options;\n\n return rawResults.map((raw, index) => {\n const url = canonicalizeUrl(raw.url);\n const domain = extractDomain(url);\n\n return {\n position: startIndex + index + 1,\n title: raw.title.trim(),\n url,\n display_url: raw.displayUrl,\n snippet: raw.snippet,\n provider,\n source_type: sourceType,\n published_at: raw.publishedAt,\n language: raw.language,\n domain,\n };\n });\n}\n","/**\n * Result deduplication — removes duplicate results by URL and title similarity.\n */\n\nimport type { SearchResult } from \"../schemas/config.schema.js\";\nimport { canonicalizeUrl } from \"../utils/domains.js\";\n\nexport interface DeduplicateOptions {\n enabled: boolean;\n}\n\n/**\n * Deduplicate search results.\n *\n * Priority:\n * 1. Exact canonical URL\n * 2. Same domain + normalized path\n * 3. Near-identical title on same domain\n *\n * When duplicates exist, prefer the one with richer metadata.\n */\nexport function deduplicateResults(\n results: SearchResult[],\n options: DeduplicateOptions = { enabled: true },\n): SearchResult[] {\n if (!options.enabled || results.length === 0) return results;\n\n const seen = new Map<string, number>(); // canonical URL -> index in unique array\n const domainPath = new Map<string, number>(); // domain+path -> index\n const titleDomain = new Map<string, number>(); // title+domain -> index\n const unique: SearchResult[] = [];\n\n for (const result of results) {\n const canonical = canonicalizeUrl(result.url);\n\n // Check exact URL match\n if (seen.has(canonical)) {\n mergeProviders(unique, seen.get(canonical)!, result);\n continue;\n }\n\n // Check domain + path\n const dpKey = `${result.domain}:${getNormalPath(canonical)}`;\n if (domainPath.has(dpKey)) {\n mergeProviders(unique, domainPath.get(dpKey)!, result);\n continue;\n }\n\n // Check title + domain\n const titleKey = `${result.domain}:${result.title.toLowerCase().replace(/\\s+/g, \" \").trim()}`;\n if (titleDomain.has(titleKey)) {\n mergeProviders(unique, titleDomain.get(titleKey)!, result);\n continue;\n }\n\n // New unique result\n const idx = unique.length;\n unique.push(result);\n seen.set(canonical, idx);\n domainPath.set(dpKey, idx);\n titleDomain.set(titleKey, idx);\n }\n\n return unique;\n}\n\nfunction getNormalPath(urlString: string): string {\n try {\n const url = new URL(urlString);\n return url.pathname.replace(/\\/$/, \"\") || \"/\";\n } catch {\n return urlString;\n }\n}\n\nfunction mergeProviders(results: SearchResult[], existingIndex: number, newResult: SearchResult): void {\n const existing = results[existingIndex]!;\n // Prefer the one with richer metadata\n const existingScore = scoreMetadata(existing);\n const newScore = scoreMetadata(newResult);\n\n if (newScore > existingScore) {\n results[existingIndex] = newResult;\n }\n}\n\nfunction scoreMetadata(result: SearchResult): number {\n let score = 0;\n if (result.snippet) score += 1;\n if (result.published_at) score += 1;\n if (result.display_url) score += 0.5;\n if (result.language) score += 0.5;\n return score;\n}\n","/**\n * Search result ranking — conservative, explainable scoring.\n *\n * Score components:\n * - Upstream rank position (inverse)\n * - Provider reliability weight\n * - Domain match bonus (for include_filters)\n * - Freshness bonus (verified publication date)\n * - Metadata quality bonus\n * - URL quality penalty (tracking-heavy, very long, etc.)\n */\n\nimport type { SearchResult } from \"../schemas/config.schema.js\";\n\nexport interface RankOptions {\n includeDomains?: string[];\n providerWeights?: Record<string, number>;\n}\n\nconst DEFAULT_PROVIDER_WEIGHT = 1.0;\n\n// Scoring constants — configurable in future versions\nconst SCORE_WEIGHTS = {\n upstreamRank: 10.0, // Higher rank = lower position number = higher score\n providerWeight: 2.0,\n domainMatch: 10.0,\n freshness: 3.0,\n metadataQuality: 2.0,\n urlQualityPenalty: -2.0,\n};\n\n/**\n * Rank search results by a composite score.\n * Returns results sorted by descending score with assigned position numbers.\n */\nexport function rankResults(results: SearchResult[], options: RankOptions = {}): SearchResult[] {\n const { includeDomains = [], providerWeights = {} } = options;\n\n const scored = results.map((result, index) => {\n let score = 0;\n\n // Upstream rank: earlier position = higher score\n const maxPosition = results.length || 1;\n score += SCORE_WEIGHTS.upstreamRank * ((maxPosition - index) / maxPosition);\n\n // Provider weight\n const providerWeight = providerWeights[result.provider] ?? DEFAULT_PROVIDER_WEIGHT;\n score += SCORE_WEIGHTS.providerWeight * providerWeight;\n\n // Domain match bonus\n if (includeDomains.length > 0) {\n const isMatch = includeDomains.some(\n (d) => result.domain === d.toLowerCase() || result.domain.endsWith(\".\" + d.toLowerCase()),\n );\n if (isMatch) {\n score += SCORE_WEIGHTS.domainMatch;\n }\n }\n\n // Freshness bonus (if published_at is valid and recent)\n if (result.published_at) {\n try {\n const pubDate = new Date(result.published_at);\n const daysSincePublication = (Date.now() - pubDate.getTime()) / (1000 * 60 * 60 * 24);\n if (daysSincePublication <= 7) {\n score += SCORE_WEIGHTS.freshness;\n } else if (daysSincePublication <= 30) {\n score += SCORE_WEIGHTS.freshness * 0.5;\n }\n } catch {\n // Invalid date — no bonus\n }\n }\n\n // Metadata quality bonus\n if (result.snippet) score += SCORE_WEIGHTS.metadataQuality * 0.5;\n if (result.display_url) score += SCORE_WEIGHTS.metadataQuality * 0.3;\n if (result.language) score += SCORE_WEIGHTS.metadataQuality * 0.2;\n\n // URL quality penalty\n const url = result.url;\n if (url.includes(\"tracking\") || url.includes(\"click\") || url.includes(\"redirect\")) {\n score += SCORE_WEIGHTS.urlQualityPenalty;\n }\n if (url.length > 200) {\n score += SCORE_WEIGHTS.urlQualityPenalty * 0.5;\n }\n\n return { result, score };\n });\n\n // Sort by score descending, then by original position (stable sort)\n scored.sort((a, b) => {\n if (b.score !== a.score) return b.score - a.score;\n return a.result.position - b.result.position;\n });\n\n // Reassign positions\n return scored.map((item, index) => ({\n ...item.result,\n position: index + 1,\n score: Math.round(item.score * 100) / 100,\n }));\n}\n","/**\n * Domain filters — include and exclude domain matching.\n */\n\nimport type { SearchResult } from \"../schemas/config.schema.js\";\n\nexport interface DomainFilterOptions {\n includeDomains?: string[];\n excludeDomains?: string[];\n globalExcludeDomains?: string[];\n}\n\nexport interface DomainFilterResult {\n results: SearchResult[];\n filteredCount: number;\n warnings: string[];\n}\n\n/**\n * Apply domain include/exclude filters to search results.\n */\nexport function applyDomainFilters(\n results: SearchResult[],\n options: DomainFilterOptions,\n): DomainFilterResult {\n const { includeDomains = [], excludeDomains = [], globalExcludeDomains = [] } = options;\n const warnings: string[] = [];\n let filtered = [...results];\n let totalFiltered = 0;\n\n // Apply include filter (must match at least one)\n if (includeDomains.length > 0) {\n const before = filtered.length;\n filtered = filtered.filter((result) => {\n return domainMatchesAny(result.domain, includeDomains);\n });\n totalFiltered += before - filtered.length;\n }\n\n // Apply exclude filter (must not match any)\n const allExcludes = [...excludeDomains, ...globalExcludeDomains];\n if (allExcludes.length > 0) {\n const before = filtered.length;\n filtered = filtered.filter((result) => {\n return !domainMatchesAny(result.domain, allExcludes);\n });\n totalFiltered += before - filtered.length;\n }\n\n if (filtered.length === 0 && results.length > 0 && totalFiltered > 0) {\n warnings.push(\"Domain filtering removed all results — returning unfiltered results\");\n filtered = results;\n totalFiltered = 0;\n }\n\n return {\n results: filtered,\n filteredCount: totalFiltered,\n warnings,\n };\n}\n\nfunction domainMatchesAny(domain: string, domains: string[]): boolean {\n const lowerDomain = domain.toLowerCase();\n return domains.some((filterDomain) => {\n const lowerFilter = filterDomain.toLowerCase();\n return lowerDomain === lowerFilter || lowerDomain.endsWith(\".\" + lowerFilter);\n });\n}\n","/**\n * In-flight request coalescer — deduplicates identical concurrent requests.\n *\n * When multiple identical searches arrive simultaneously, only one\n * upstream request is made and all callers share the result.\n */\n\nexport interface CoalescerEntry<T> {\n promise: Promise<T>;\n refCount: number;\n}\n\nexport class RequestCoalescer<T> {\n private inflight = new Map<string, CoalescerEntry<T>>();\n\n /**\n * Get or create a coalesced request.\n * If an identical request is already in-flight, returns its promise.\n * Otherwise, executes the factory and stores the promise.\n */\n async acquire(key: string, factory: () => Promise<T>): Promise<T> {\n const existing = this.inflight.get(key);\n if (existing) {\n existing.refCount++;\n try {\n return await existing.promise;\n } finally {\n existing.refCount--;\n if (existing.refCount <= 0) {\n this.inflight.delete(key);\n }\n }\n }\n\n const entry: CoalescerEntry<T> = {\n promise: factory(),\n refCount: 1,\n };\n\n this.inflight.set(key, entry);\n\n try {\n const result = await entry.promise;\n return result;\n } finally {\n entry.refCount--;\n if (entry.refCount <= 0) {\n this.inflight.delete(key);\n }\n }\n }\n\n /**\n * Check if a request is currently in-flight.\n */\n has(key: string): boolean {\n return this.inflight.has(key);\n }\n\n /**\n * Get the number of in-flight requests.\n */\n get size(): number {\n return this.inflight.size;\n }\n\n /**\n * Clear all in-flight requests (does not cancel them).\n */\n clear(): void {\n this.inflight.clear();\n }\n}\n","/**\n * Per-provider rate limiter with dynamic cooldown on rate-limit responses.\n *\n * Uses a simple timer-based approach:\n * - Each provider has a minimum interval between requests.\n * - On 429/rate-limit, the cooldown increases.\n * - On success, the cooldown resets.\n */\n\nexport interface ProviderThrottleState {\n consecutiveFailures: number;\n lastFailureAt?: number;\n cooldownMs: number;\n nextAvailableAt: number;\n}\n\nexport class RateLimiter {\n private states = new Map<string, ProviderThrottleState>();\n private defaultIntervalMs: number;\n\n constructor(defaultIntervalMs: number = 1500) {\n this.defaultIntervalMs = defaultIntervalMs;\n }\n\n /**\n * Wait until the provider is available, respecting rate limits.\n */\n async acquire(providerId: string, signal?: AbortSignal): Promise<void> {\n const state = this.getState(providerId);\n const now = Date.now();\n\n if (state.nextAvailableAt > now) {\n const waitMs = state.nextAvailableAt - now;\n\n // Check if signal is already aborted\n if (signal?.aborted) {\n throw new DOMException(\"Aborted\", \"AbortError\");\n }\n\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, waitMs);\n signal?.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timer);\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n },\n { once: true },\n );\n });\n }\n\n // Set next available time\n const state2 = this.getState(providerId);\n state2.nextAvailableAt = Date.now() + this.defaultIntervalMs;\n }\n\n /**\n * Report a rate-limited response — increases cooldown.\n */\n reportRateLimited(providerId: string, retryAfterMs?: number): void {\n const state = this.getState(providerId);\n state.consecutiveFailures++;\n state.lastFailureAt = Date.now();\n\n // Exponential backoff: base * 2^(failures-1), capped at 10 minutes\n const base = retryAfterMs ?? this.defaultIntervalMs;\n const backoff = Math.min(base * Math.pow(2, state.consecutiveFailures - 1), 600_000);\n state.cooldownMs = backoff;\n state.nextAvailableAt = Date.now() + backoff;\n }\n\n /**\n * Report a success — resets failure state.\n */\n reportSuccess(providerId: string): void {\n const state = this.getState(providerId);\n state.consecutiveFailures = 0;\n state.cooldownMs = this.defaultIntervalMs;\n state.lastFailureAt = undefined;\n // Allow immediate next request after success\n state.nextAvailableAt = 0;\n }\n\n /**\n * Get the current state for a provider.\n */\n getState(providerId: string): ProviderThrottleState {\n let state = this.states.get(providerId);\n if (!state) {\n state = {\n consecutiveFailures: 0,\n cooldownMs: this.defaultIntervalMs,\n nextAvailableAt: 0,\n };\n this.states.set(providerId, state);\n }\n return state;\n }\n\n /**\n * Check if a provider is currently available.\n */\n isAvailable(providerId: string): boolean {\n const state = this.states.get(providerId);\n if (!state) return true;\n return Date.now() >= state.nextAvailableAt;\n }\n\n /**\n * Reset all state.\n */\n reset(): void {\n this.states.clear();\n }\n}\n","/**\n * Search orchestrator — full pipeline for executing searches.\n *\n * Flow:\n * Validate input → cache check → coalesce → select providers →\n * rate limit → execute → normalize → filter → dedup → rank → cache → return\n */\n\nimport type { SearchProvider, ProviderContext, ProviderSearchRequest } from \"../providers/provider.interface.js\";\nimport type { SearchResult, ProviderAttempt } from \"../schemas/config.schema.js\";\nimport type { Cache } from \"../cache/cache.interface.js\";\nimport type { AppConfig } from \"../config/load-config.js\";\nimport { generateSearchCacheKey } from \"../cache/cache-key.js\";\nimport { normalizeResults } from \"./normalize.js\";\nimport { deduplicateResults } from \"./deduplicate.js\";\nimport { rankResults } from \"./rank.js\";\nimport { applyDomainFilters } from \"./filters.js\";\nimport { RequestCoalescer } from \"./coalescer.js\";\nimport { RateLimiter } from \"./rate-limiter.js\";\nimport { getLogger } from \"../observability/logger.js\";\n\nexport interface OrchestratorOptions {\n providers: SearchProvider[];\n strategy: \"fallback\" | \"merge\";\n cache: Cache<unknown>;\n config: AppConfig;\n}\n\nexport interface SearchOrchestrationRequest {\n query: string;\n maxResults: number;\n timeRange?: \"day\" | \"week\" | \"month\" | \"year\" | \"any\";\n region: string;\n language: string;\n safeSearch: \"off\" | \"moderate\" | \"strict\";\n includeDomains?: string[];\n excludeDomains?: string[];\n deduplicate: boolean;\n timeoutMs?: number;\n}\n\nexport interface SearchOrchestrationResult {\n query: string;\n results: SearchResult[];\n providerAttempts: ProviderAttempt[];\n cached: boolean;\n partial: boolean;\n warnings: string[];\n durationMs: number;\n}\n\n// Module-level singletons for coalescing and rate limiting\nconst coalescer = new RequestCoalescer<SearchOrchestrationResult>();\nconst rateLimiter = new RateLimiter(1500);\n\n/**\n * Execute a search through the full orchestrator pipeline.\n */\nexport async function orchestrateSearch(\n request: SearchOrchestrationRequest,\n options: OrchestratorOptions,\n): Promise<SearchOrchestrationResult> {\n const logger = getLogger();\n const startTime = Date.now();\n const { providers, strategy, cache, config } = options;\n\n // Generate cache key\n const cacheKey = generateSearchCacheKey({\n toolKind: \"web_search\",\n query: request.query,\n maxResults: request.maxResults,\n providers: providers.map((p) => p.id),\n strategy,\n region: request.region,\n language: request.language,\n timeRange: request.timeRange ?? \"any\",\n safeSearch: request.safeSearch,\n includeDomains: request.includeDomains,\n excludeDomains: request.excludeDomains,\n });\n\n // Check cache\n const cached = cache.get(cacheKey);\n if (cached && cached.hit) {\n logger.debug(\"Cache hit\", { key: cacheKey });\n const result = cached.value as SearchOrchestrationResult;\n return { ...result, cached: true };\n }\n\n logger.debug(\"Cache miss\", { key: cacheKey });\n\n // Coalesce concurrent identical requests\n return coalescer.acquire(cacheKey, async () => {\n const providerContext: ProviderContext = {\n timeoutMs: request.timeoutMs ?? config.providerTimeoutMs,\n safeSearch: request.safeSearch,\n region: request.region,\n language: request.language,\n };\n\n const allResults: SearchResult[] = [];\n const providerAttempts: ProviderAttempt[] = [];\n const warnings: string[] = [];\n let partial = false;\n\n if (strategy === \"fallback\") {\n // Try providers in order until we have enough results\n for (const provider of providers) {\n if (allResults.length >= request.maxResults) break;\n\n const { attempt, results: providerResults } = await executeProvider(provider, {\n query: request.query,\n maxResults: request.maxResults - allResults.length,\n timeRange: request.timeRange,\n region: request.region,\n language: request.language,\n safeSearch: request.safeSearch,\n includeDomains: request.includeDomains,\n excludeDomains: request.excludeDomains,\n }, providerContext);\n\n allResults.push(...providerResults);\n providerAttempts.push(attempt);\n\n if (attempt.success) {\n rateLimiter.reportSuccess(provider.id);\n } else {\n rateLimiter.reportRateLimited(provider.id);\n partial = true;\n warnings.push(...(attempt.warnings ?? []));\n }\n\n // Break if we have enough\n if (allResults.length >= request.maxResults) break;\n }\n } else {\n // Merge strategy — query top providers concurrently\n const topProviders = providers.slice(0, 2);\n const settled = await Promise.allSettled(\n topProviders.map((provider) =>\n executeProvider(provider, {\n query: request.query,\n maxResults: request.maxResults,\n timeRange: request.timeRange,\n region: request.region,\n language: request.language,\n safeSearch: request.safeSearch,\n includeDomains: request.includeDomains,\n excludeDomains: request.excludeDomains,\n }, providerContext),\n ),\n );\n\n for (const result of settled) {\n if (result.status === \"fulfilled\") {\n allResults.push(...result.value.results);\n providerAttempts.push(result.value.attempt);\n if (result.value.attempt.success) {\n rateLimiter.reportSuccess(result.value.attempt.provider);\n } else {\n partial = true;\n warnings.push(...(result.value.attempt.warnings ?? []));\n }\n } else {\n partial = true;\n warnings.push(`Provider call failed: ${result.reason}`);\n }\n }\n }\n\n // Apply domain filters\n const filtered = applyDomainFilters(allResults, {\n includeDomains: request.includeDomains,\n excludeDomains: request.excludeDomains,\n globalExcludeDomains: config.globalExcludeDomains,\n });\n warnings.push(...filtered.warnings);\n\n // Deduplicate\n const deduplicated = deduplicateResults(filtered.results, { enabled: request.deduplicate });\n\n // Rank\n const ranked = rankResults(deduplicated);\n\n // Cap results\n const capped = ranked.slice(0, request.maxResults);\n\n // Build result\n const durationMs = Date.now() - startTime;\n const result: SearchOrchestrationResult = {\n query: request.query,\n results: capped,\n providerAttempts,\n cached: false,\n partial: partial || capped.length < request.maxResults,\n warnings,\n durationMs,\n };\n\n // Cache successful results\n if (capped.length > 0) {\n const cacheTtl = config.searchCacheTtlMs;\n cache.set(cacheKey, result, cacheTtl);\n }\n\n return result;\n });\n}\n\ninterface ProviderExecutionResult {\n attempt: ProviderAttempt;\n results: SearchResult[];\n}\n\nasync function executeProvider(\n provider: SearchProvider,\n request: ProviderSearchRequest,\n context: ProviderContext,\n): Promise<ProviderExecutionResult> {\n const logger = getLogger();\n const startTime = Date.now();\n\n try {\n // Wait for rate limiter\n await rateLimiter.acquire(provider.id);\n\n logger.debug(\"Provider attempt started\", { provider: provider.id });\n\n const response = await provider.search(request, context);\n\n // Normalize results\n const normalized = normalizeResults(response.results, {\n provider: response.provider,\n sourceType: \"web\",\n });\n\n const durationMs = Date.now() - startTime;\n\n logger.debug(\"Provider attempt completed\", {\n provider: provider.id,\n resultCount: normalized.length,\n durationMs,\n });\n\n return {\n attempt: {\n provider: provider.id,\n success: normalized.length > 0,\n duration_ms: durationMs,\n result_count: normalized.length,\n error: response.warnings.length > 0 ? response.warnings.join(\"; \") : undefined,\n warnings: response.warnings,\n },\n results: normalized,\n };\n } catch (err) {\n const durationMs = Date.now() - startTime;\n const message = err instanceof Error ? err.message : String(err);\n\n logger.error(\"Provider attempt failed\", {\n provider: provider.id,\n error: message,\n durationMs,\n });\n\n return {\n attempt: {\n provider: provider.id,\n success: false,\n duration_ms: durationMs,\n result_count: 0,\n error: message,\n },\n results: [],\n };\n }\n}\n","/**\n * web_search MCP tool — search the general web.\n *\n * Uses the orchestrator pipeline with DuckDuckGo + Bing fallback.\n */\n\nimport { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { AppConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../observability/logger.js\";\nimport { SearchInputSchema } from \"../schemas/config.schema.js\";\nimport { DuckDuckGoProvider } from \"../providers/duckduckgo/duckduckgo.provider.js\";\nimport { BingProvider } from \"../providers/bing/bing.provider.js\";\nimport { MemoryCache } from \"../cache/memory-cache.js\";\nimport { orchestrateSearch } from \"../search/orchestrator.js\";\n\n// Module-level singletons\nlet initialized = false;\nconst providers = [new DuckDuckGoProvider(), new BingProvider()];\nconst cache = new MemoryCache(250);\n\nexport function registerWebSearchTool(server: McpServer, config: AppConfig): void {\n if (!initialized) {\n initialized = true;\n }\n\n server.tool(\n \"web_search\",\n \"Search the general web and return normalized results.\",\n {\n query: z.string().min(1).max(500).describe(\"Search query, 1-500 characters\"),\n max_results: z.number().int().min(1).max(25).default(10).describe(\"Maximum number of results (1-25)\"),\n providers: z\n .array(z.string())\n .optional()\n .describe(\"Preferred providers in priority order\"),\n strategy: z\n .enum([\"fallback\", \"merge\"])\n .default(\"fallback\")\n .describe(\"Provider strategy: fallback tries providers in order, merge combines top 2\"),\n region: z.string().default(\"us-en\").describe(\"Region code\"),\n language: z.string().default(\"en\").describe(\"Language code\"),\n time_range: z\n .enum([\"day\", \"week\", \"month\", \"year\", \"any\"])\n .default(\"any\")\n .describe(\"Time range filter\"),\n safe_search: z\n .enum([\"off\", \"moderate\", \"strict\"])\n .default(\"moderate\")\n .describe(\"Safe search level\"),\n include_domains: z\n .array(z.string())\n .max(20)\n .optional()\n .describe(\"Only include results from these domains\"),\n exclude_domains: z\n .array(z.string())\n .max(50)\n .optional()\n .describe(\"Exclude results from these domains\"),\n deduplicate: z.boolean().default(true).describe(\"Deduplicate results by URL\"),\n timeout_ms: z\n .number()\n .int()\n .min(1000)\n .max(60_000)\n .optional()\n .describe(\"Operation timeout in milliseconds\"),\n },\n async (args) => {\n const logger = getLogger();\n\n logger.info(\"web_search called\", {\n query: config.redactQueries ? \"[REDACTED]\" : args.query,\n maxResults: args.max_results,\n });\n\n // Validate input\n const parseResult = SearchInputSchema.safeParse(args);\n if (!parseResult.success) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify({\n error: {\n code: \"INVALID_INPUT\",\n message: \"Invalid search parameters\",\n details: parseResult.error.flatten(),\n },\n }),\n },\n ],\n isError: true,\n };\n }\n\n const input = parseResult.data;\n\n // Filter to requested providers\n let activeProviders = providers;\n if (input.providers && input.providers.length > 0) {\n activeProviders = providers.filter((p) => input.providers!.includes(p.id));\n if (activeProviders.length === 0) activeProviders = providers;\n }\n\n // Run through orchestrator\n const orchestrationResult = await orchestrateSearch(\n {\n query: input.query,\n maxResults: input.max_results,\n timeRange: input.time_range,\n region: input.region,\n language: input.language,\n safeSearch: input.safe_search,\n includeDomains: input.include_domains,\n excludeDomains: input.exclude_domains,\n deduplicate: input.deduplicate,\n timeoutMs: input.timeout_ms,\n },\n {\n providers: activeProviders,\n strategy: input.strategy,\n cache,\n config,\n },\n );\n\n // Build MCP output\n const output = {\n query: orchestrationResult.query,\n results: orchestrationResult.results,\n provider_attempts: orchestrationResult.providerAttempts,\n cached: orchestrationResult.cached,\n partial: orchestrationResult.partial,\n warnings: orchestrationResult.warnings,\n duration_ms: orchestrationResult.durationMs,\n };\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify(output),\n },\n ],\n };\n },\n );\n}\n","/**\n * URL safety validation — blocks private networks, SSRF, and unsupported schemes.\n */\n\nimport { isPrivateHost } from \"../utils/domains.js\";\n\nconst ALLOWED_SCHEMES = new Set([\"http:\", \"https:\"]);\n\nexport interface UrlValidationResult {\n valid: boolean;\n error?: string;\n code?: string;\n}\n\n/**\n * Validate a URL for safe fetching.\n * Blocks: non-HTTP schemes, credentials, private networks, localhost.\n */\nexport function validateUrl(urlString: string): UrlValidationResult {\n let url: URL;\n try {\n url = new URL(urlString);\n } catch {\n return {\n valid: false,\n error: \"Invalid URL format\",\n code: \"INVALID_URL\",\n };\n }\n\n // Check scheme\n if (!ALLOWED_SCHEMES.has(url.protocol)) {\n return {\n valid: false,\n error: `Unsupported scheme: ${url.protocol}`,\n code: \"UNSUPPORTED_SCHEME\",\n };\n }\n\n // Check for credentials in URL\n if (url.username || url.password) {\n return {\n valid: false,\n error: \"URLs with credentials are not allowed\",\n code: \"INVALID_URL\",\n };\n }\n\n // Check for private/reserved hosts\n if (isPrivateHost(url.hostname)) {\n return {\n valid: false,\n error: \"Private/reserved network addresses are not allowed\",\n code: \"PRIVATE_NETWORK_BLOCKED\",\n };\n }\n\n return { valid: true };\n}\n","/**\n * Content type detection and handling.\n */\n\nconst SUPPORTED_TEXT_TYPES = new Set([\n \"text/html\",\n \"text/plain\",\n \"text/css\",\n \"text/xml\",\n \"application/json\",\n \"application/xml\",\n \"application/xhtml+xml\",\n]);\n\nconst REJECTED_TYPES = new Set([\n \"application/pdf\",\n \"image/\",\n \"audio/\",\n \"video/\",\n \"application/zip\",\n \"application/x-tar\",\n \"application/gzip\",\n \"application/octet-stream\",\n \"application/x-executable\",\n \"application/x-msdownload\",\n]);\n\nexport interface ContentTypeInfo {\n isSupported: boolean;\n isText: boolean;\n isHtml: boolean;\n rejectionReason?: string;\n}\n\n/**\n * Determine if a content type is supported for extraction.\n */\nexport function classifyContentType(contentType: string | null): ContentTypeInfo {\n if (!contentType) {\n return { isSupported: true, isText: true, isHtml: false };\n }\n\n const normalized = contentType.split(\";\")[0]!.trim().toLowerCase();\n\n // Check rejected types first\n for (const rejected of REJECTED_TYPES) {\n if (normalized.startsWith(rejected)) {\n return {\n isSupported: false,\n isText: false,\n isHtml: false,\n rejectionReason: `Unsupported content type: ${normalized}`,\n };\n }\n }\n\n const isHtml = normalized.includes(\"html\");\n const isText = normalized.startsWith(\"text/\") || SUPPORTED_TEXT_TYPES.has(normalized);\n\n return {\n isSupported: true,\n isText,\n isHtml,\n };\n}\n","/**\n * HTML content extraction pipeline.\n *\n * Uses Mozilla Readability for main content extraction,\n * with fallbacks for <main>, <article>, and body text.\n */\n\nimport type { CheerioAPI } from \"cheerio\";\nimport * as cheerio from \"cheerio\";\n\nexport interface ExtractedContent {\n title?: string;\n byline?: string;\n siteName?: string;\n publishedAt?: string;\n content: string;\n textContent: string;\n}\n\n/**\n * Extract main content from HTML using Readability, with fallbacks.\n */\nexport async function extractMainContent(html: string, url: string): Promise<ExtractedContent> {\n const $ = cheerio.load(html);\n\n // Extract basic metadata first\n const meta = extractMetadata($, url);\n\n // Try Readability extraction\n try {\n const { parseHTML } = await import(\"linkedom\");\n const { Readability } = await import(\"@mozilla/readability\");\n const { document } = parseHTML(html);\n const reader = new Readability(document as never);\n const article = reader.parse();\n\n if (article && article.textContent && article.textContent.trim().length > 50) {\n return {\n title: article.title || meta.title,\n byline: article.byline || meta.byline,\n siteName: meta.siteName,\n publishedAt: meta.publishedAt,\n content: article.content || \"\",\n textContent: article.textContent || \"\",\n };\n }\n } catch {\n // Readability failed — fall through to fallbacks\n }\n\n // Fallback: try <main>\n const mainContent = extractBySelector($, \"main\");\n if (mainContent) {\n return {\n ...meta,\n content: mainContent,\n textContent: stripTags($, mainContent),\n };\n }\n\n // Fallback: try <article>\n const articleContent = extractBySelector($, \"article\");\n if (articleContent) {\n return {\n ...meta,\n content: articleContent,\n textContent: stripTags($, articleContent),\n };\n }\n\n // Fallback: body text\n const bodyContent = $(\"body\").html() || \"\";\n return {\n ...meta,\n content: bodyContent,\n textContent: stripTags($, bodyContent),\n };\n}\n\nfunction extractMetadata($: CheerioAPI, url: string): Omit<ExtractedContent, \"content\" | \"textContent\"> {\n const title =\n $(\"meta[property='og:title']\").attr(\"content\") ||\n $(\"title\").text().trim() ||\n undefined;\n\n const byline =\n $(\"meta[name='author']\").attr(\"content\") ||\n undefined;\n\n let siteName =\n $(\"meta[property='og:site_name']\").attr(\"content\") ||\n undefined;\n\n if (!siteName) {\n try {\n siteName = new URL(url).hostname;\n } catch {\n // ignore\n }\n }\n\n const publishedAt =\n $(\"meta[property='article:published_time']\").attr(\"content\") ||\n $(\"meta[name='date']\").attr(\"content\") ||\n $(\"meta[name='pubdate']\").attr(\"content\") ||\n undefined;\n\n return {\n title,\n byline,\n siteName,\n publishedAt,\n };\n}\n\nfunction extractBySelector($: CheerioAPI, selector: string): string | null {\n const $el = $(selector).first();\n if ($el.length === 0) return null;\n\n // Remove noise elements\n $el.find(\"script, style, nav, footer, aside, form, iframe\").remove();\n const htmlStr = $el.html();\n return htmlStr && htmlStr.trim().length > 50 ? htmlStr : null;\n}\n\n/**\n * Strip HTML tags from a string, reusing an existing cheerio instance.\n */\nfunction stripTags($: CheerioAPI, htmlStr: string): string {\n return $(htmlStr)\n .text()\n .replace(/\\s+/g, \" \")\n .trim();\n}\n","/**\n * HTML to Markdown conversion using Turndown.\n */\n\n// Lazy-loaded Turndown to avoid startup cost\nlet turndownInstance: { turndown(html: string): string } | null = null;\n\nasync function getTurndown() {\n if (!turndownInstance) {\n const TurndownService = (await import(\"turndown\")).default;\n const service = new TurndownService({\n headingStyle: \"atx\",\n codeBlockStyle: \"fenced\",\n bulletListMarker: \"-\",\n });\n\n // Remove scripts and styles before conversion\n service.remove([\"script\", \"style\", \"noscript\"]);\n turndownInstance = service;\n }\n return turndownInstance;\n}\n\n/**\n * Convert HTML to Markdown.\n */\nexport async function htmlToMarkdown(html: string): Promise<string> {\n const service = await getTurndown();\n return service.turndown(html);\n}\n","/**\n * Text utility functions.\n */\n\n/**\n * Truncate text to a maximum character count, adding indicator if truncated.\n */\nexport function truncateText(text: string, maxLength: number): { text: string; truncated: boolean } {\n if (text.length <= maxLength) {\n return { text, truncated: false };\n }\n const truncated = text.slice(0, maxLength);\n const lastSpace = truncated.lastIndexOf(\" \");\n // Try to break at a word boundary\n const cutPoint = lastSpace > maxLength * 0.9 ? lastSpace : maxLength;\n return {\n text: truncated.slice(0, cutPoint) + \"...\",\n truncated: true,\n };\n}\n\n/**\n * Normalize whitespace: collapse runs, trim.\n */\nexport function normalizeWhitespace(text: string): string {\n return text.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Strip HTML tags from a string.\n */\nexport function stripHtml(html: string): string {\n return html\n .replace(/<[^>]*>/g, \"\")\n .replace(/ /g, \" \")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n","/**\n * Fetch page — full pipeline: validate URL → HTTP fetch → classify → extract → convert.\n */\n\nimport { validateUrl } from \"./validate-url.js\";\nimport { classifyContentType } from \"./content-types.js\";\nimport { extractMainContent } from \"./extract-main-content.js\";\nimport { htmlToMarkdown } from \"./html-to-markdown.js\";\nimport { httpFetch } from \"../http/client.js\";\nimport { truncateText } from \"../utils/text.js\";\nimport type { AppConfig } from \"../config/load-config.js\";\n\nexport interface FetchPageOptions {\n url: string;\n output: \"markdown\" | \"text\";\n maxCharacters: number;\n includeMetadata: boolean;\n timeoutMs: number;\n config: AppConfig;\n}\n\nexport interface FetchPageResult {\n requestedUrl: string;\n finalUrl: string;\n title?: string;\n byline?: string;\n siteName?: string;\n publishedAt?: string;\n contentType: string;\n content: string;\n truncated: boolean;\n characterCount: number;\n fetchedAt: string;\n warnings: string[];\n}\n\n/**\n * Fetch and extract content from a URL.\n */\nexport async function fetchPage(options: FetchPageOptions): Promise<FetchPageResult> {\n const { url, output, maxCharacters, config } = options;\n const warnings: string[] = [];\n\n // Validate URL\n const validation = validateUrl(url);\n if (!validation.valid) {\n throw new Error(validation.error);\n }\n\n // Fetch the page\n const response = await httpFetch({\n url,\n timeoutMs: options.timeoutMs || config.fetchTimeoutMs,\n maxBodyBytes: config.maxPageBodyBytes,\n maxRedirects: 5,\n });\n\n // Classify content type\n const contentType = response.headers.get(\"content-type\");\n const typeInfo = classifyContentType(contentType);\n\n if (!typeInfo.isSupported) {\n throw new Error(typeInfo.rejectionReason || \"Unsupported content type\");\n }\n\n const finalContentType = contentType?.split(\";\")[0]?.trim() || \"text/html\";\n\n // Handle non-HTML text content\n if (!typeInfo.isHtml) {\n const { text, truncated } = truncateText(response.body, maxCharacters);\n return {\n requestedUrl: url,\n finalUrl: response.finalUrl,\n contentType: finalContentType,\n content: text,\n truncated,\n characterCount: text.length,\n fetchedAt: new Date().toISOString(),\n warnings,\n };\n }\n\n // Extract main content from HTML\n const extracted = await extractMainContent(response.body, response.finalUrl);\n\n // Convert to output format\n let content: string;\n if (output === \"markdown\") {\n content = await htmlToMarkdown(extracted.content || response.body);\n } else {\n content = extracted.textContent || stripHtml(extracted.content || response.body);\n }\n\n // Truncate\n const { text: truncatedContent, truncated } = truncateText(content, maxCharacters);\n\n // Add untrusted content warning\n warnings.push(\"External webpage content is untrusted and may contain instructions intended for AI systems.\");\n\n return {\n requestedUrl: url,\n finalUrl: response.finalUrl,\n title: extracted.title,\n byline: extracted.byline,\n siteName: extracted.siteName,\n publishedAt: extracted.publishedAt,\n contentType: finalContentType,\n content: truncatedContent,\n truncated,\n characterCount: truncatedContent.length,\n fetchedAt: new Date().toISOString(),\n warnings,\n };\n}\n\nfunction stripHtml(html: string): string {\n return html\n .replace(/<[^>]*>/g, \" \")\n .replace(/ /g, \" \")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n","/**\n * fetch_url MCP tool — fetch and extract content from a public URL.\n */\n\nimport { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { AppConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../observability/logger.js\";\nimport { FetchUrlInputSchema } from \"../schemas/config.schema.js\";\nimport { fetchPage } from \"../fetch/fetch-page.js\";\n\nexport function registerFetchUrlTool(server: McpServer, config: AppConfig): void {\n server.tool(\n \"fetch_url\",\n \"Fetch a public HTTP(S) URL and return extracted content as clean Markdown or plain text.\",\n {\n url: z.string().describe(\"HTTP or HTTPS URL to fetch\"),\n output: z.enum([\"markdown\", \"text\"]).default(\"markdown\").describe(\"Output format\"),\n max_characters: z\n .number()\n .int()\n .min(100)\n .max(100_000)\n .default(20_000)\n .describe(\"Maximum characters to return\"),\n include_metadata: z.boolean().default(true).describe(\"Include page metadata\"),\n include_links: z.boolean().default(false).describe(\"Include extracted links\"),\n timeout_ms: z\n .number()\n .int()\n .min(1000)\n .max(60_000)\n .optional()\n .describe(\"Fetch timeout in milliseconds\"),\n },\n async (args) => {\n const logger = getLogger();\n\n let hostname = \"unknown\";\n try {\n hostname = new URL(args.url).hostname;\n } catch {\n // Use raw string if URL parsing fails\n }\n\n logger.info(\"fetch_url called\", { url: hostname });\n\n // Validate input\n const parseResult = FetchUrlInputSchema.safeParse(args);\n if (!parseResult.success) {\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify({\n error: {\n code: \"INVALID_INPUT\",\n message: \"Invalid fetch parameters\",\n details: parseResult.error.flatten(),\n },\n }),\n },\n ],\n isError: true,\n };\n }\n\n const input = parseResult.data;\n\n try {\n const result = await fetchPage({\n url: input.url,\n output: input.output,\n maxCharacters: input.max_characters,\n includeMetadata: input.include_metadata,\n timeoutMs: input.timeout_ms || config.fetchTimeoutMs,\n config,\n });\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify(result),\n },\n ],\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n logger.error(\"fetch_url failed\", { error: message, url: hostname });\n\n return {\n content: [\n {\n type: \"text\" as const,\n text: JSON.stringify({\n error: {\n code: \"FETCH_FAILED\",\n message,\n },\n }),\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n","/**\n * search_and_fetch MCP tool — combined search + fetch research workflow.\n *\n * Executes a web search, selects top results, fetches them concurrently\n * with bounded parallelism, and returns extracted content.\n */\n\nimport { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { AppConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../observability/logger.js\";\nimport { SearchAndFetchInputSchema } from \"../schemas/config.schema.js\";\nimport { DuckDuckGoProvider } from \"../providers/duckduckgo/duckduckgo.provider.js\";\nimport { BingProvider } from \"../providers/bing/bing.provider.js\";\nimport { MemoryCache } from \"../cache/memory-cache.js\";\nimport { orchestrateSearch } from \"../search/orchestrator.js\";\nimport { fetchPage } from \"../fetch/fetch-page.js\";\nimport { isPrivateHost } from \"../utils/domains.js\";\n\n// Module-level singletons\nconst providers = [new DuckDuckGoProvider(), new BingProvider()];\nconst cache = new MemoryCache(250);\n\nexport function registerSearchAndFetchTool(server: McpServer, config: AppConfig): void {\n server.tool(\n \"search_and_fetch\",\n \"Search the web and fetch the best results. One call for research: search, rank, and fetch the best few pages.\",\n {\n query: z.string().min(1).max(500).describe(\"Search query\"),\n search_results: z.number().int().min(1).max(20).default(8).describe(\"Number of search results to consider\"),\n fetch_results: z.number().int().min(1).max(5).default(3).describe(\"Number of pages to fetch\"),\n providers: z.array(z.string()).optional().describe(\"Preferred providers\"),\n strategy: z.enum([\"fallback\", \"merge\"]).default(\"fallback\"),\n region: z.string().default(\"us-en\"),\n language: z.string().default(\"en\"),\n time_range: z.enum([\"day\", \"week\", \"month\", \"year\", \"any\"]).default(\"any\"),\n include_domains: z.array(z.string()).max(20).optional(),\n exclude_domains: z.array(z.string()).max(50).optional(),\n max_characters_per_page: z.number().int().min(1000).max(100_000).default(20_000),\n total_character_budget: z.number().int().min(1000).max(500_000).default(100_000),\n timeout_ms: z.number().int().min(5000).max(120_000).optional(),\n },\n async (args) => {\n const logger = getLogger();\n const startTime = Date.now();\n const totalTimeout = args.timeout_ms || config.researchTimeoutMs;\n\n logger.info(\"search_and_fetch called\", {\n query: config.redactQueries ? \"[REDACTED]\" : args.query,\n fetchResults: args.fetch_results,\n });\n\n // Validate input\n const parseResult = SearchAndFetchInputSchema.safeParse(args);\n if (!parseResult.success) {\n return {\n content: [{\n type: \"text\" as const,\n text: JSON.stringify({\n error: {\n code: \"INVALID_INPUT\",\n message: \"Invalid parameters\",\n details: parseResult.error.flatten(),\n },\n }),\n }],\n isError: true,\n };\n }\n\n const input = parseResult.data;\n\n try {\n // Phase 1: Execute search\n let activeProviders = providers;\n if (input.providers && input.providers.length > 0) {\n activeProviders = providers.filter((p) => input.providers!.includes(p.id));\n if (activeProviders.length === 0) activeProviders = providers;\n }\n\n const searchResult = await orchestrateSearch(\n {\n query: input.query,\n maxResults: input.search_results,\n timeRange: input.time_range,\n region: input.region,\n language: input.language,\n safeSearch: \"moderate\",\n includeDomains: input.include_domains,\n excludeDomains: input.exclude_domains,\n deduplicate: true,\n timeoutMs: Math.min(totalTimeout, 20_000),\n },\n {\n providers: activeProviders,\n strategy: input.strategy,\n cache,\n config,\n },\n );\n\n // Phase 2: Select candidates for fetching\n const candidates = searchResult.results\n .filter((r) => {\n try {\n const url = new URL(r.url);\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") return false;\n if (isPrivateHost(url.hostname)) return false;\n return true;\n } catch {\n return false;\n }\n })\n .slice(0, input.fetch_results);\n\n // Phase 3: Fetch pages with bounded concurrency\n const pages: Array<{\n url: string;\n title?: string;\n content_type: string;\n content: string;\n character_count: number;\n fetched_at: string;\n warnings: string[];\n }> = [];\n\n const failures: Array<{\n url: string;\n error: string;\n code: string;\n }> = [];\n\n let totalCharacters = 0;\n const maxPerPage = Math.min(\n input.max_characters_per_page,\n input.total_character_budget - totalCharacters,\n );\n\n // Fetch sequentially with budget tracking\n for (const candidate of candidates) {\n if (totalCharacters >= input.total_character_budget) break;\n\n // Check timeout\n if (Date.now() - startTime > totalTimeout) {\n failures.push({\n url: candidate.url,\n error: \"Operation timeout\",\n code: \"OPERATION_CANCELLED\",\n });\n continue;\n }\n\n const remainingBudget = input.total_character_budget - totalCharacters;\n const charLimit = Math.min(maxPerPage, remainingBudget);\n\n try {\n const fetched = await fetchPage({\n url: candidate.url,\n output: \"markdown\",\n maxCharacters: charLimit,\n includeMetadata: true,\n timeoutMs: Math.min(config.fetchTimeoutMs, totalTimeout - (Date.now() - startTime)),\n config,\n });\n\n pages.push({\n url: fetched.finalUrl,\n title: fetched.title || candidate.title,\n content_type: fetched.contentType,\n content: fetched.content,\n character_count: fetched.characterCount,\n fetched_at: fetched.fetchedAt,\n warnings: fetched.warnings,\n });\n\n totalCharacters += fetched.characterCount;\n } catch (err) {\n failures.push({\n url: candidate.url,\n error: err instanceof Error ? err.message : String(err),\n code: \"FETCH_FAILED\",\n });\n }\n }\n\n const durationMs = Date.now() - startTime;\n const partial = searchResult.partial || failures.length > 0 || pages.length < input.fetch_results;\n\n const warnings = [...searchResult.warnings];\n if (failures.length > 0) {\n warnings.push(`${failures.length} page fetch(es) failed`);\n }\n\n return {\n content: [{\n type: \"text\" as const,\n text: JSON.stringify({\n query: input.query,\n search_results: searchResult.results,\n pages,\n failures,\n partial,\n duration_ms: durationMs,\n }),\n }],\n };\n } catch (err) {\n logger.error(\"search_and_fetch failed\", {\n error: err instanceof Error ? err.message : String(err),\n });\n\n return {\n content: [{\n type: \"text\" as const,\n text: JSON.stringify({\n error: {\n code: \"INTERNAL_ERROR\",\n message: err instanceof Error ? err.message : String(err),\n },\n }),\n }],\n isError: true,\n };\n }\n },\n );\n}\n","/**\n * news_search MCP tool — search for recent news articles.\n *\n * Uses providers that support news results (DDG news, Bing news).\n * Returns date-sensitive results with publisher info.\n */\n\nimport { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { AppConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../observability/logger.js\";\nimport { NewsSearchInputSchema } from \"../schemas/config.schema.js\";\nimport { DuckDuckGoProvider } from \"../providers/duckduckgo/duckduckgo.provider.js\";\nimport { BingProvider } from \"../providers/bing/bing.provider.js\";\nimport { MemoryCache } from \"../cache/memory-cache.js\";\nimport { orchestrateSearch } from \"../search/orchestrator.js\";\n\nconst providers = [new DuckDuckGoProvider(), new BingProvider()];\nconst cache = new MemoryCache(250);\n\nexport function registerNewsSearchTool(server: McpServer, config: AppConfig): void {\n server.tool(\n \"news_search\",\n \"Search for recent news articles. Returns date-sensitive results with publisher and publication time.\",\n {\n query: z.string().min(1).max(500).describe(\"News search query\"),\n max_results: z.number().int().min(1).max(25).default(10).describe(\"Maximum number of results\"),\n providers: z.array(z.string()).optional().describe(\"Preferred providers\"),\n region: z.string().default(\"us-en\").describe(\"Region code\"),\n language: z.string().default(\"en\").describe(\"Language code\"),\n time_range: z.enum([\"day\", \"week\", \"month\"]).default(\"week\").describe(\"Time range filter\"),\n include_domains: z.array(z.string()).max(20).optional().describe(\"Only include these domains\"),\n exclude_domains: z.array(z.string()).max(50).optional().describe(\"Exclude these domains\"),\n timeout_ms: z.number().int().min(1000).max(60_000).optional().describe(\"Timeout in ms\"),\n },\n async (args) => {\n const logger = getLogger();\n\n logger.info(\"news_search called\", {\n query: config.redactQueries ? \"[REDACTED]\" : args.query,\n maxResults: args.max_results,\n });\n\n const parseResult = NewsSearchInputSchema.safeParse(args);\n if (!parseResult.success) {\n return {\n content: [{\n type: \"text\" as const,\n text: JSON.stringify({\n error: {\n code: \"INVALID_INPUT\",\n message: \"Invalid news search parameters\",\n details: parseResult.error.flatten(),\n },\n }),\n }],\n isError: true,\n };\n }\n\n const input = parseResult.data;\n\n // Use news-capable providers\n let activeProviders = providers.filter((p) => p.capabilities.news || p.capabilities.web);\n if (input.providers && input.providers.length > 0) {\n activeProviders = providers.filter((p) => input.providers!.includes(p.id));\n if (activeProviders.length === 0) activeProviders = providers;\n }\n\n const result = await orchestrateSearch(\n {\n query: input.query,\n maxResults: input.max_results,\n timeRange: input.time_range,\n region: input.region,\n language: input.language,\n safeSearch: \"moderate\",\n includeDomains: input.include_domains,\n excludeDomains: input.exclude_domains,\n deduplicate: true,\n timeoutMs: input.timeout_ms,\n },\n {\n providers: activeProviders,\n strategy: \"fallback\",\n cache,\n config,\n },\n );\n\n const output = {\n query: result.query,\n results: result.results.map((r) => ({\n ...r,\n source_type: \"news\" as const,\n })),\n provider_attempts: result.providerAttempts,\n cached: result.cached,\n partial: result.partial,\n warnings: [\n ...result.warnings,\n \"Publication dates are only included when provided by the source. Dates may be missing or approximate.\",\n ],\n duration_ms: result.durationMs,\n };\n\n return {\n content: [{\n type: \"text\" as const,\n text: JSON.stringify(output),\n }],\n };\n },\n );\n}\n","/**\n * diagnostics MCP tool — return non-sensitive server diagnostics.\n *\n * Disabled by default. Enable with FWSMCP_DIAGNOSTICS_ENABLED=true.\n * Never exposes: secrets, IP addresses, search history, full paths.\n */\n\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { AppConfig } from \"../config/load-config.js\";\nimport { getLogger } from \"../observability/logger.js\";\n\nexport function registerDiagnosticsTool(server: McpServer, config: AppConfig): void {\n server.tool(\n \"diagnostics\",\n \"Return non-sensitive server diagnostics for troubleshooting.\",\n {},\n async () => {\n const logger = getLogger();\n logger.debug(\"diagnostics called\");\n\n const output = {\n version: \"0.1.0\",\n nodeVersion: process.version,\n platform: process.platform,\n arch: process.arch,\n enabledProviders: [\"duckduckgo\", \"bing\", \"wikipedia\"],\n cacheEnabled: config.cacheEnabled,\n diagnosticsEnabled: config.diagnosticsEnabled,\n limits: {\n maxSearchResults: config.maxSearchResults,\n maxFetchCharacters: config.maxFetchCharacters,\n searchTimeoutMs: config.searchTimeoutMs,\n providerTimeoutMs: config.providerTimeoutMs,\n fetchTimeoutMs: config.fetchTimeoutMs,\n },\n concurrency: {\n maxConcurrentSearches: config.maxConcurrentSearches,\n maxConcurrentFetches: config.maxConcurrentFetches,\n },\n cache: {\n maxEntries: config.cacheMaxEntries,\n searchTtlMs: config.searchCacheTtlMs,\n newsTtlMs: config.newsCacheTtlMs,\n pageTtlMs: config.pageCacheTtlMs,\n },\n uptime: Math.floor(process.uptime()),\n memoryUsage: {\n rss: Math.round(process.memoryUsage().rss / 1024 / 1024),\n heapUsed: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),\n },\n };\n\n return {\n content: [{\n type: \"text\" as const,\n text: JSON.stringify(output),\n }],\n };\n },\n );\n}\n","/**\n * Register all MCP tools on the server.\n */\n\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { AppConfig } from \"../config/load-config.js\";\nimport { registerWebSearchTool } from \"../tools/web-search.tool.js\";\nimport { registerFetchUrlTool } from \"../tools/fetch-url.tool.js\";\nimport { registerSearchAndFetchTool } from \"../tools/search-and-fetch.tool.js\";\nimport { registerNewsSearchTool } from \"../tools/news-search.tool.js\";\nimport { registerDiagnosticsTool } from \"../tools/diagnostics.tool.js\";\nimport { getLogger } from \"../observability/logger.js\";\n\nexport function registerTools(server: McpServer, config: AppConfig): void {\n const logger = getLogger();\n registerWebSearchTool(server, config);\n registerFetchUrlTool(server, config);\n registerSearchAndFetchTool(server, config);\n registerNewsSearchTool(server, config);\n\n if (config.diagnosticsEnabled) {\n registerDiagnosticsTool(server, config);\n }\n\n const tools = [\"web_search\", \"fetch_url\", \"search_and_fetch\", \"news_search\"];\n if (config.diagnosticsEnabled) tools.push(\"diagnostics\");\n\n logger.info(\"Tools registered\", { tools });\n}\n","/**\n * fast-web-search-mcp — Entry point.\n *\n * MCP server over stdio. All output to stdout is MCP protocol only.\n * All diagnostics go to stderr.\n */\n\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { loadConfig } from \"./config/load-config.js\";\nimport { getLogger, resetLogger } from \"./observability/logger.js\";\nimport { createServer } from \"./server/create-server.js\";\nimport { registerTools } from \"./server/register-tools.js\";\n\nconst VERSION = \"0.1.0\";\n\nfunction handleCliArgs(): void {\n const args = process.argv.slice(2);\n\n if (args.includes(\"--version\") || args.includes(\"-v\")) {\n console.log(VERSION);\n process.exit(0);\n }\n\n if (args.includes(\"--help\") || args.includes(\"-h\")) {\n console.log(`\nfast-web-search-mcp v${VERSION}\n\nA fast, lightweight, local MCP server for free web search and webpage extraction.\n\nUSAGE\n fast-web-search-mcp Start the MCP server (stdio transport)\n fast-web-search-mcp --version Print version and exit\n fast-web-search-mcp --help Show this help message\n\nENVIRONMENT VARIABLES\n FWSMCP_LOG_LEVEL Log level: debug, info, warn, error (default: warn)\n FWSMCP_DEFAULT_REGION Default region code (default: us-en)\n FWSMCP_DEFAULT_LANGUAGE Default language code (default: en)\n FWSMCP_PROVIDERS Comma-separated providers (default: duckduckgo,bing,wikipedia)\n FWSMCP_PROVIDER_STRATEGY Strategy: fallback or merge (default: fallback)\n FWSMCP_CACHE_ENABLED Enable cache: true or false (default: true)\n FWSMCP_SEARXNG_URL Optional SearXNG instance URL\n FWSMCP_DIAGNOSTICS_ENABLED Enable diagnostics tool (default: false)\n\nSee https://github.com/iPraBhu/fast-web-search-mcp for full documentation.\n`);\n process.exit(0);\n }\n}\n\nasync function main(): Promise<void> {\n // Handle CLI flags before starting MCP server\n handleCliArgs();\n\n // Load configuration\n const config = await loadConfig();\n\n const logger = getLogger({\n level: config.logLevel as \"debug\" | \"info\" | \"warn\" | \"error\",\n format: config.logFormat as \"text\" | \"json\",\n redact: config.redactQueries,\n });\n\n logger.info(\"Starting fast-web-search-mcp\");\n\n // Create MCP server\n const server = createServer(config);\n\n // Register tools\n registerTools(server, config);\n\n // Set up stdio transport\n const transport = new StdioServerTransport();\n\n // Graceful shutdown\n let isShuttingDown = false;\n\n const shutdown = async (reason: string, exitCode: number = 0): Promise<void> => {\n if (isShuttingDown) return;\n isShuttingDown = true;\n\n logger.info(\"Shutdown initiated\", { reason });\n\n try {\n await transport.close();\n } catch (err) {\n logger.error(\"Error closing transport\", {\n error: err instanceof Error ? err.message : String(err),\n });\n }\n\n logger.info(\"Shutdown complete\");\n resetLogger();\n process.exit(exitCode);\n };\n\n process.on(\"SIGINT\", () => shutdown(\"SIGINT\", 0));\n process.on(\"SIGTERM\", () => shutdown(\"SIGTERM\", 0));\n\n process.on(\"uncaughtException\", (error) => {\n logger.error(\"Uncaught exception\", {\n error: error.message,\n stack: error.stack,\n });\n shutdown(\"uncaughtException\", 1);\n });\n\n process.on(\"unhandledRejection\", (reason) => {\n logger.error(\"Unhandled rejection\", {\n reason: reason instanceof Error ? reason.message : String(reason),\n });\n shutdown(\"unhandledRejection\", 1);\n });\n\n // Handle stdin close (client disconnected)\n process.stdin.on(\"end\", () => {\n shutdown(\"stdin closed\", 0);\n });\n\n process.stdin.on(\"error\", () => {\n shutdown(\"stdin error\", 0);\n });\n\n // Connect server to transport\n await server.connect(transport);\n\n logger.info(\"MCP server connected via stdio\", {\n pid: process.pid,\n nodeVersion: process.version,\n });\n}\n\nmain().catch((error) => {\n process.stderr.write(\n JSON.stringify({\n level: \"error\",\n message: \"Fatal startup error\",\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n }) + \"\\n\",\n );\n process.exit(1);\n});\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fast-web-search-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A fast, lightweight, local MCP server for free web search and webpage extraction.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"fast-web-search-mcp": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"CHANGELOG.md"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=22"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"dev": "tsx src/index.ts",
|
|
21
|
+
"build": "tsup",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"lint": "eslint .",
|
|
24
|
+
"format": "prettier --write .",
|
|
25
|
+
"format:check": "prettier --check .",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"test:watch": "vitest",
|
|
28
|
+
"test:coverage": "vitest run --coverage",
|
|
29
|
+
"test:integration": "vitest run test/integration",
|
|
30
|
+
"test:security": "vitest run test/security",
|
|
31
|
+
"test:unit": "vitest run test/unit"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"mcp",
|
|
35
|
+
"web-search",
|
|
36
|
+
"model-context-protocol",
|
|
37
|
+
"fast-web-search"
|
|
38
|
+
],
|
|
39
|
+
"author": "",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
43
|
+
"@mozilla/readability": "^0.6.0",
|
|
44
|
+
"cheerio": "^1.2.0",
|
|
45
|
+
"linkedom": "^0.18.13",
|
|
46
|
+
"turndown": "^7.2.4",
|
|
47
|
+
"zod": "^4.4.3"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
51
|
+
"@eslint/js": "^10.0.1",
|
|
52
|
+
"@types/node": "^26.1.1",
|
|
53
|
+
"@types/turndown": "^5.0.6",
|
|
54
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
55
|
+
"cross-env": "^10.1.0",
|
|
56
|
+
"eslint": "^10.7.0",
|
|
57
|
+
"prettier": "^3.9.5",
|
|
58
|
+
"publint": "^0.3.21",
|
|
59
|
+
"tsup": "^8.5.1",
|
|
60
|
+
"tsx": "^4.23.1",
|
|
61
|
+
"typescript": "^6.0.3",
|
|
62
|
+
"typescript-eslint": "^8.64.0",
|
|
63
|
+
"vitest": "^4.1.10"
|
|
64
|
+
}
|
|
65
|
+
}
|