Skip to main content
Glama

searxng-mcp

Built with Claude Code CI License: MIT npm

一个用于通过自托管的 SearXNG 实例进行私有网络搜索的 MCP 服务器。结果由本地 ML 模型重新排序,完整页面内容通过 Firecrawl 获取,可选的 Ollama 实例提供查询扩展和 LLM 合成的摘要。

专为需要网络搜索但不想将查询发送给第三方搜索 API 的 Claude Code 和 LibreChat 代理设计。

使用 Claude Code 构建,采用 homelab-agent 中的多代理工作流——该平台在生产环境中使用 searxng-mcp 进行 AI 辅助研究。

快速开始

需要一个正在运行的 SearXNG 实例。强烈建议使用缓存后端。

最小化部署——启动一个 Dragonfly/Valkey 缓存后端并运行 searxng-mcp:

docker compose -f docker-compose.example.yml up -d
SEARXNG_URL=http://localhost:8081 CACHE_URL=redis://localhost:6381 npx @tadmstr/searxng-mcp

如需包含 Firecrawl、Crawl4AI、Ollama、Kiwix、广告拦截代理和 NATS 的完整本地拓扑,请参阅 docker-compose.full.yml

Related MCP server: searxng-mcp-bridge

工具

工具

描述

关键参数

search

通过 SearXNG 搜索并进行本地重排序。获取更广泛的结果池,按相关性重新排序,返回前 N 条。SearXNG 原生的直接答案、信息框、拼写纠正和相关建议会显示在列表上方以及 structuredContent 中。

querynum_results(1–20)、categorytime_rangedomain_profileexpandlanguageenginessite

search_and_fetch

搜索、重排序,然后使用获取级联(Firecrawl → Crawl4AI → 原始 HTTP)获取前几个结果的完整内容。

querycategorytime_rangefetch_count(1–3)、domain_profileexpandlanguageenginessite

search_and_summarize

搜索、获取前几个结果,然后通过 Ollama(OLLAMA_SUMMARIZE_MODEL)合成带引用的摘要。如果 Ollama 不可用,则回退到原始获取内容。

queryfetch_count(1–5)、categorytime_rangedomain_profileexpandlanguageenginessite

fetch_url

从任何公共 URL 获取并提取可读的 Markdown。GitHub 主机走 GitHub 快速路径;YouTube 视频 URL 返回字幕,Reddit 帖子 URL 返回帖子+评论(两者均通过 robots 选择加入,见下文);其他所有 URL 使用获取级联(Firecrawl → Crawl4AI → 原始 HTTP)。按 token 预算截断(默认约 8,000 字符)。

urldomain_profilemax_tokenstarget_selectorwait_for_selector

crawl_site

抓取整个网站并返回每个页面的 URL/标题/摘要清单。先尝试 Firecrawl 抓取,回退到 sitemap 解析,然后可选 BFS。完整页面内容缓存在 Valkey 中,因此后续的 fetch_url 调用零成本。

urlmax_pages(默认:CRAWL_MAX_PAGES_DEFAULT)、bfs(布尔值,选择加入 BFS)

clear_cache

清除搜索缓存、获取缓存、抓取清单缓存或全部。适用于研究快速变化主题时缓存结果可能过时的情况。

targetsearchfetchcrawlall

domain_stats

域名能力数据库的只读视图。带 hostname:单个域名的各层级成功率和能力标志。不带:所有跟踪域名的聚合(各层级成功率、最差失败域名、已见但从未获取的计数)。返回 MCP 结构化输出(structuredContent)以进行编程阈值判断。

hostname(可选)

参数

categorygeneral(默认)、newsitscience

time_rangedayweekmonthyear — 按发布日期限制结果。省略则返回所有时间的结果。

fetch_count — 要获取完整内容的前几个重排序结果的数量(search_and_fetch 默认 1,最大 3search_and_summarize 默认 3,最大 5)。

domain_profile — 应用命名的域名过滤配置文件:homelab(突出自托管/Linux 文档)或 dev(突出 Stack Overflow、MDN、npm)。省略则使用默认过滤器。

expand — 当为 true 时,在搜索前通过 Ollama(OLLAMA_EXPAND_MODEL)重写查询以提高召回率。需要 OLLAMA_URL。默认为 EXPAND_QUERIES 环境变量的值。

language — BCP-47 语言代码(例如 ende)或 all 以限制为特定语言。省略则使用 SearXNG 实例默认值。适用于 searchsearch_and_fetchsearch_and_summarize

engines — 逗号分隔的 SearXNG 引擎名称,用于限制搜索范围(例如 google,duckduckgo)。原样转发;未知/禁用的引擎会退化为较少结果而不是报错。适用于所有三个搜索工具。

site — 将结果限制为一个域名或列表(例如 github.com["github.com", "gitlab.com"])。尽力作为 site: 查询运算符应用——大多数引擎(Google、Bing、DDG、Brave)会遵守,有些会忽略。适用于所有三个搜索工具。

max_tokensfetch_url)— 返回内容的近似 token 预算(字符 ≈ token × 4)。省略则使用约 2,000 token / 8,000 字符的默认值;最大 10,000 token。

target_selectorfetch_url)— CSS 选择器,用于将提取范围限定到特定元素(例如 articlemain .content)。Firecrawl/Crawl4AI 原生支持,并在原始 HTTP 层客户端应用;快速路径和未匹配时忽略。

wait_for_selectorfetch_url)— 提取前等待的 CSS 选择器,用于 JS 渲染页面。渲染层(Firecrawl/Crawl4AI)支持;原始 HTTP(无 JS)忽略。

架构

MCP client (stdio)
      │
      ▼
  searxng-mcp ──────────────→ cache ($CACHE_URL)           → result cache (search 1h, fetch 24h, crawl 6h)
      │
      ├── expand (optional) →  Ollama ($OLLAMA_URL)        → rewritten query (qwen3:4b)
      ├── search ───────────→ SearXNG ($SEARXNG_URL)      → raw results
      ├── rerank ───────────→ Reranker ($RERANKER_URL)    → ranked results
      │                       (fallback: SearXNG order if reranker unavailable)
      ├── fetch content ────┬→ GitHub API (github.com)    → markdown
      │                     ├→ Kiwix ($KIWIX_URL)         → ZIM content (Wikipedia/SO/Arch Wiki, fast path)
      │                     ├→ Hister ($HISTER_URL)       → browsing-history index (login-walled/JS-heavy fast path)
      │                     ├→ Firecrawl ($FIRECRAWL_URL) → page markdown (tier 1)
      │                     ├→ Crawl4AI ($CRAWL4AI_URL)  → page markdown (tier 2, optional; via $ADBLOCK_PROXY_URL if set)
      │                     ├→ Raw HTTP + Readability     → page markdown (tier 3 fallback; via $ADBLOCK_PROXY_URL if set)
      │                     └→ Wayback Machine (opt-in)  → archived page markdown (tier 4, $WAYBACK_ENABLED)
      ├── crawl_site ───────┬→ Firecrawl crawl           → page manifest (phase 1)
      │                     ├→ Sitemap parsing           → page manifest (phase 2 fallback, fast-xml-parser)
      │                     └→ BFS crawl (opt-in)        → page manifest (phase 3, $CRAWL_BFS_ENABLED)
      └── summarize (opt.) →  Ollama ($OLLAMA_URL)        → synthesized summary ($OLLAMA_SUMMARIZE_MODEL)
flowchart TD
    entry["fetchPage(url)"]
    cache{"Valkey cache hit?"}
    cached["→ return cached { title, url, text }"]
    github{"GitHub host?\ngithub.com · raw · api"}
    gh_fetch["GitHub API / raw.githubusercontent.com / api.github.com\n→ return"]
    llms{"llms.txt domain?"}
    llms_fetch["Probe /llms-full.txt\nextract matching section\n→ return"]
    kiwix{"Kiwix host?\nKIWIX_URL set"}
    kiwix_fetch["Local Kiwix ZIM\nWikipedia · Stack Overflow · Arch Wiki\n→ cache + return"]
    pdf{".pdf URL?"}
    robots["robots.txt pre-check — tiers 1–3\ndisallowed → RobotsDisallowedError (cached 24h)"]
    tier_skip(["Per-domain tier skip\nsuccess rate <30% over ≥10 tries\nor tier_skip operator override"])
    t1["Tier 1 — Firecrawl\n$FIRECRAWL_URL"]
    t2["Tier 2 — Crawl4AI\n$CRAWL4AI_URL · optional\nadblock proxy if $ADBLOCK_PROXY_URL"]
    t3["Tier 3 — Raw HTTP + Readability\nfallback: raw HTML slice\nadblock proxy if $ADBLOCK_PROXY_URL"]
    t4["Tier 4 — Wayback Machine CDX API\narchived snapshot · WAYBACK_ENABLED=true"]
    post["Post-extraction\nJSON-LD Article · title cascade\nog:title → twitter:title → title → h1 → URL"]
    result["→ return { title, url, text }"]

    entry --> cache
    cache -->|hit| cached
    cache -->|miss| github
    github -->|yes| gh_fetch
    github -->|no| llms
    llms -->|yes| llms_fetch
    llms -->|no| kiwix
    kiwix -->|yes| kiwix_fetch
    kiwix -->|no| pdf
    pdf -->|"yes — skip tier 1"| t2
    pdf -->|no| robots
    robots --> tier_skip
    tier_skip --> t1
    t1 -->|success| post
    t1 -->|"empty / error"| t2
    t2 -->|success| post
    t2 -->|"empty / error"| t3
    t3 -->|success| post
    t3 -->|"empty / error"| t4
    t4 -->|success| result
    post --> result

    style entry fill:#ffffff,stroke:#333333,color:#000000
    style cache fill:#ffffff,stroke:#333333,color:#000000
    style cached fill:#ffffff,stroke:#333333,color:#000000
    style github fill:#dae8fc,stroke:#6c8ebf,color:#000000
    style gh_fetch fill:#dae8fc,stroke:#6c8ebf,color:#000000
    style llms fill:#dae8fc,stroke:#6c8ebf,color:#000000
    style llms_fetch fill:#dae8fc,stroke:#6c8ebf,color:#000000
    style kiwix fill:#fff9c4,stroke:#b8860b,color:#000000
    style kiwix_fetch fill:#fff9c4,stroke:#b8860b,color:#000000
    style pdf fill:#ffffff,stroke:#333333,color:#000000
    style robots fill:#ffffff,stroke:#333333,color:#000000
    style tier_skip fill:#f5f5f5,stroke:#666666,color:#000000
    style t1 fill:#d5e8d4,stroke:#5a8a4a,color:#000000
    style t2 fill:#d5e8d4,stroke:#5a8a4a,color:#000000
    style t3 fill:#d5e8d4,stroke:#5a8a4a,color:#000000
    style t4 fill:#f8cecc,stroke:#a03030,color:#000000
    style post fill:#e1d5e7,stroke:#7a5a8a,color:#000000
    style result fill:#ffffff,stroke:#333333,color:#000000

SearXNG 和 Firecrawl 是必需的。Crawl4AI、Valkey、Ollama、Kiwix 和重排序器是可选的——当其中任何一个不可用时,服务器会优雅降级。

广告拦截

searxng-mcp 使用两个独立的广告拦截边车,每个获取层级组一个:

边车

层级

机制

docker/puppeteer-adblock/

第 1 层(Firecrawl)

CDP 级拦截——完整 HTTPS 过滤,同一浏览器进程

docker/adblock-proxy/

第 2+3 层(Crawl4AI、原始获取)

HTTP 转发代理——过滤纯 HTTP 广告域名

第 1 层 — Puppeteer 广告拦截

Firecrawl 使用的 firecrawl-puppeteer 服务运行自定义镜像(docker/puppeteer-adblock/),该镜像在上游 trieve/puppeteer-service-ts 之上叠加了 @ghostery/adblocker-puppeteer。启动时加载 EasyList + EasyPrivacy,每 168 小时刷新一次;拦截器应用于 Firecrawl 创建的每个页面。加快广告密集型网站的获取速度并缩小渲染 DOM 大小。

环境变量:

变量

默认值

描述

ADBLOCK_DISABLE

未设置

设置为 true 以完全跳过过滤器加载。

ADBLOCK_FILTERS_URL

EasyList + EasyPrivacy

逗号分隔的过滤器列表 URL。

ADBLOCK_REFRESH_HOURS

168

拦截器从配置的 URL 重建的节奏。

基础镜像按 SHA256 摘要固定。要部署更改,请重建并重启服务:

docker compose -f ~/docker/firecrawl-simple/docker-compose.yml up -d --build firecrawl-puppeteer

按域名绕过: domains.json 为未来的操作员覆盖保留了 adblock_skip 槽位。接线尚未实现——这需要 Firecrawl 将自定义标头转发到 puppeteer-service,而这不在其当前 API 中。跟踪为范围蔓延项 I。

第 2+3 层 — 广告拦截代理

设置 ADBLOCK_PROXY_URL(例如 http://adblock-proxy:8118)以将 Crawl4AI 和原始 Node fetch 请求路由到 HTTP 转发代理,该代理过滤广告和跟踪器请求。HTTPS CONNECT 隧道原样传递——无 MITM,因此过滤仅适用于纯 HTTP 广告域名。第 1 层的 puppeteer 钩子已处理该层的完整 HTTPS 过滤;代理覆盖第 2 层和第 3 层泄漏的内容。

参见 docker/adblock-proxy/ 了解服务定义、配置选项和部署说明(包含在 docker-compose.full.yml 中)。

数据驱动的层级路由

在调用获取级联之前,searxng-mcp 读取域名的 tier_stats_30d(参见 域名能力数据库),并跳过任何在至少 10 次尝试中成功率低于 30% 的层级。冷启动域名(少于 10 次尝试)保留默认级联。每次跳过都会发出 searxng.fetch.tier.skipped NATS 事件,reason: low_success_rate,并递增 searxng_fetch_total{outcome=skipped}

操作员覆盖。domains.json 中添加 tier_skip 映射以强制跳过层级,无论统计如何:

{
  "tier_skip": {
    "example-bot-blocked.com": ["tier1"],
    "another-site.example": ["tier1", "tier2"]
  }
}

tier_skip 键可以是裸域名(example.com 匹配该域名及其所有子域名)或域名 + 路径前缀(example.com/api/)。文件热重载——无需重启。手动覆盖发出 reason: operator_override

内容类型快速路径

提供结构化、非 HTML 内容的 URL —— application/json、任何 *+json、XML、YAML、TOML、CSV 或 text/plain —— 通过 HEAD 探测检测,并直接路由到原始 HTTP 层,而不是完整的 Firecrawl/Crawl4AI 级联。JSON 以美化格式返回,并放在围栏代码块中。以前,要求无头浏览器渲染 JSON API 响应或 CDN 资源会返回空 markdown,因此 API 和 CDN 端点(registry.npmjs.orgapi.osv.devcdn.jsdelivr.net 等)直接失败。

保证:

  • 探测是故障开放的。无法访问的主机、拒绝 HEAD 的服务器或不可读/无法解析的 Content-Type 头都会照常落入正常级联。

  • application/xhtml+xml 被有意排除——那是给浏览器看的标记,不是结构化数据。

  • 服务器错误标记为 text/plain 的 HTML 仍会被解析为 HTML,而不是作为原始文本块转储。

域名能力数据库

每次抓取都会将 searxng-mcp 了解到的目标域名信息记录到 Valkey 的 domain:<hostname> 下(90 天 TTL,schema_version 5)。每条记录捕获:

  • tier_stats_30d.{tier1,tier2,tier3,tier4,github}.{attempts, ok, fail, last_fail_reason, window_start_ms} —— 滚动 30 天窗口内每个层的抓取成功率。截止时间在读取时应用,由层路由决策和 domain_stats 报告共享,因此两者不会不一致——一个被抓取一次然后闲置的域名会报告一个真正空的窗口,而不是让过时数字一直存活到下次写入。tier4(Wayback Machine)槽位仅在 WAYBACK_ENABLED=true 时记录。github 槽位记录 GitHub 快速路径raw.githubusercontent.com / api.github.com / github.com README 抓取),该路径绕过层级联但仍在此跟踪。schema_version 提升会重新构建现有记录——当前闲置域名的累积窗口会被丢弃(在 1→2、2→3、3→4、4→5 的提升中已有先例)。

  • capabilities.metadata_fetch.{attempts, ok, fail, last_fail_reason} —— 元数据侧信道抓取(fetchRawHtmlForMetadata,用于 JSON-LD/og:title 采样)的成功/失败。与 tier_stats_30d 分开跟踪,因为它回答的是“该域名是否可达”,而不是“完整内容交付是否成功”。

  • capabilities.seen_in_search.{count, last_seen_ms} —— 该域名在 search 结果中出现的频率。由 searxSearch() 在每条返回路径上(包括缓存命中)以即发即忘方式写入,不执行抓取,因此域名可以在被抓取之前就被跟踪。

  • capabilities.robots_txt.{present, fetched, allows_us} —— robots.txt 是否存在以及是否允许我们

  • capabilities.llms_full_txt.{present, size_bytes, last_checked} —— 该域名是否提供 /llms-full.txt

  • capabilities.json_ld_article.{sampled, present, last_sampled_at} —— 页面是否带有 Article 模式的 JSON-LD(Schema.org Article/NewsArticle/BlogPosting/TechArticle 及其子类型如 ScholarlyArticle/OpinionNewsArticle/LiveBlogPosting,通过裸名称或完全限定的 https://schema.org/... @type 匹配),无论该模式是否有可提取的正文文本——许多网站发布只有标题/元数据的 JSON-LD,没有 articleBody,这与 提取后处理 实际使用它不同。

  • capabilities.og_title.{sampled, present, last_sampled_at} —— 与 <meta property="og:title"> 相同

  • preferred_strategy —— 当前在探测命中时设置为 llms_full_txt;未来阶段将使用它来跳过层级联

使用捆绑的 CLI 检查记录,或通过 domain_stats 工具从代理查询(单域名或聚合;参见 工具):

pnpm dump-domain docs.anthropic.com

dump-domain 区分已过期的窗口和完全没有数据的层,而不是将两者显示为相同。

同一主机名的并发更新(一次抓取期间并行触发的层尝试、robots 探测和提取后采样记录器)通过服务器端 Lua 比较并设置(CAS)序列化,并配以进程内每键队列,消除单个进程自身写入者之间的争用,因此 CAS 只需仲裁跨进程的真正并发写入。v3.17.0 之前的版本使用共享连接上的 WATCH/MULTI/EXEC 读-修改-写,这实际上并未序列化并发写入者——因此 v3.17.0 之前收集的数据大幅不完整。升级会通过 schema 提升丢弃现有的层统计;升级后 domain_stats 预计会接近空,并在接下来的几天内重新填充。

域名数据库持久化

域名数据库仅存在于 Valkey 中,具有 90 天 TTL 和 30 天滚动窗口,因此缓存刷新或 TTL 过期会擦除重新获取成本高昂的能力学习。两个 CLI 使其持久化:

pnpm domain-db-maintenance   # SCAN all domain:* records → write a dated JSON snapshot (+ prune) and emit OTel gauges
pnpm restore-domain-db       # re-seed the domain-db from the newest snapshot after a flush
  • domain-db-maintenance 是一个独立作业(通过 cron 或 PM2 cron-restart 按计划运行——不是进程内定时器,因为 searxng-mcp 作为多个并发的每代理 stdio 子进程运行,每个都会触发它)。一次有界的 SCAN 同时提供两个输出:一个持久的带日期快照,以及当设置了 OTEL_EXPORTER_OTLP_ENDPOINT 时,在退出前强制刷新的指标(searxng_domains_trackedsearxng_domains_failingsearxng_domain_tier_success_ratio{tier})。

  • restore-domain-db 仅重新播种缺失的键或实时记录严格比快照更旧的键(比较 last_fetch)——它绝不会覆盖更新或相等的实时记录,因此可以安全地针对活跃、部分填充的 Valkey 运行(例如在服务启动序列中用于自动刷新恢复)。

环境变量

默认值

用途

DOMAIN_DB_SNAPSHOT_DIR

./domain-db-snapshots

写入/读取带日期快照的位置。在部署中设置为持久路径(应用数据或 NFS 挂载)。

DOMAIN_DB_SNAPSHOT_RETENTION

14

保留多少快照;每次维护运行时会修剪较旧的。

llms.txt 快速路径

对于 domains.jsonllms_txt 数组)中白名单的文档域名,fetchPage 在调用任何层之前先尝试 <origin>/llms-full.txt,并提取与请求 URL 匹配的部分。这避免了针对文档完善的站点运行 puppeteer,并直接返回干净的 markdown 部分。探测结果和完整正文缓存在 Valkey 中(llms:<origin>:full,存在/不存在分别为 24 小时 / 7 天)。默认白名单:docs.anthropic.comdocs.openai.comdocs.stripe.comdocs.crawl4ai.comdocs.firecrawl.devdocs.cursor.com。通过编辑 domains.json 扩展——该文件会热重载。

Kiwix 快速路径

当设置 KIWIX_URL 时,对已知可离线主机的抓取请求会在 Firecrawl/Crawl4AI 级联之前被拦截,并从本地 Kiwix ZIM 存档提供。这消除了像 Wikipedia(阻止无头抓取器)这样的站点 100% 的 tier-1 失败率,并返回干净可读的内容,零外部网络流量。

支持的主机和 ZIM 书籍(kiwix-serve 必须使用 --nodatealiases / -z 运行):

主机

ZIM 书籍

en.wikipedia.org, wikipedia.org

wikipedia_en_all_mini

stackoverflow.com

stackoverflow.com_en_all

wiki.archlinux.org

archlinux_en_all_maxi

Kiwix 路径在 llms-txt 快速路径之后、robots 门之前运行。如果 Kiwix 请求失败或返回空,则正常运行完整层级联。当 KIWIX_URL 未设置时,该功能零开销——isKiwixHost() 立即返回 false。

KIWIX_URL 设置为你的 kiwix-serve 基础 URL(例如 http://localhost:8292)。

YouTube 和 Reddit 快速路径

fetch_url 识别 YouTube 视频 URL(youtube.comyoutu.be)和 Reddit 帖子 URL,并可以直接提供它们,而不是抓取渲染后的页面:

  • YouTube —— 从观看页面提取视频的字幕轨道并返回转录文本。由 YOUTUBE_TRANSCRIPT_ENABLED 启用(默认开启)。

  • Reddit —— 获取公开的 .json 视图,并返回帖子及顶级评论,采用标准 {title, url, text} 形状;在 HTTP 429 时回退。由 REDDIT_FASTPATH_ENABLED 启用(默认开启)。

两者都依赖非官方、未记录的端点(YouTube 的 timedtext API、Reddit 的 .json)——尽力而为,无 SLA;任一都可能因上游更改而中断,因此有终止开关。任何未命中时,请求都会回退到正常层级联(这仍然可以获取 YouTube 页面的标题/描述)。

robots.txt: 两个端点都被站点的 robots.txt 禁止(Reddit 禁止所有内容;YouTube 禁止 /api/,转录文本就在那里)。默认情况下,这些快速路径尊重这一点并保持休眠,回退到级联。在你自己的实例上,你可以选择使用 YOUTUBE_IGNORE_ROBOTS=true / REDDIT_IGNORE_ROBOTS=true 直接抓取。

站点爬取

crawl_site 爬取整个站点,并返回每个找到的页面的 URL/标题/摘要清单。它使用三阶段策略级联:

  1. Firecrawl 爬取 —— 向 Firecrawl 发送爬取作业(/crawl 端点),轮询直到完成,并返回完整页面列表。由 FIRECRAWL_CRAWL_POLL_INTERVAL_MSFIRECRAWL_CRAWL_MAX_WAIT_MS 控制。

  2. Sitemap 解析 —— 如果 Firecrawl 失败或返回空,则获取 /sitemap.xml(以及链接的 sitemap)并提取带标题/摘要的 URL。使用 fast-xml-parser 解析 sitemap XML。

  3. BFS 爬取(可选)—— 如果 sitemap 解析也失败,则从给定 URL 开始执行广度优先爬取,最多 CRAWL_BFS_MAX_DEPTH 次链接跳转。仅在 CRAWL_BFS_ENABLED=truebfs 工具参数为 true 时运行。

爬取期间获取的完整页面内容缓存在 Valkey 中(TTL:CRAWL_MANIFEST_TTL_SECONDS,默认 6 小时)。后续对清单中任何 URL 的 fetch_url 调用都会立即从缓存返回——后续读取零抓取开销。

可以使用 clear_cache(target="crawl") 清除清单缓存。

Wayback Machine 回退

WAYBACK_ENABLED=true 时,当所有三个主要层都失败时,第四层查询 Wayback Machine CDX API 以获取存档快照。返回的内容带有来源头([Archived snapshot – <timestamp> – <original_url>]),以便调用者知道内容可能不反映当前页面状态。

抓取质量

任何层返回带有原始 HTML 的内容后,提取后处理会提高标题和正文质量:

  • JSON-LD 文章提取 —— Schema.org Article / NewsArticle / BlogPosting / TechArticle 块提供比 tier-1 chrome 抓取更干净的 headlinearticleBody(每个脚本标签大小上限为 1 MB)。

  • 标题级联 —— 依次回退到 og:titletwitter:title<title>(带发布者后缀剥离)→ 第一个 <h1> → URL。

  • Tier-2 Readability 比较 —— 当 Crawl4AI 返回 markdown 时,JSDOM+Readability 也会在其原始 HTML 上运行,并且当其文本更长时(或当 Crawl4AI 返回少于 500 个字符时无条件)优先使用。

韧性

  • 缓存绝不会让搜索挂起。 Valkey 客户端受 CACHE_COMMAND_TIMEOUT_MS/CACHE_CONNECT_TIMEOUT_MS/CACHE_MAX_RETRIES_PER_REQUEST 约束(见配置)。当缓存后端停滞或 CPU 飙升时,命令会被拒绝而不是无限期挂起——现有的故障软降级处理会将该拒绝降级为缓存未命中(走实时搜索),而不是抛出异常。缓存连接失败、客户端错误和单条命令错误会输出一条限流的 [searxng-mcp] stderr 日志行(按 key 去重,因此持续故障只会留下周期性的面包屑,而不会刷屏)——stderr 是已部署的 PM2 进程上唯一接通的遥测出口。

  • 进程崩溃处理——uncaughtException 记录日志后以退出码 1 退出(干净的 PM2 重启);unhandledRejection 记录日志后继续运行,而不是让共享进程静默崩溃。

  • 优雅降级警告——重排序器回退以及 Ollama/LLM 扩展与摘要回退在静默降低质量时(重排序器不可用、LLM 后端不可达),各自输出一条限流的 stderr 日志行。

  • 版本号单一来源——运行时从 package.json 读取(src/version.ts)——McpServer 版本、OTel tracer/meter 版本以及出站 USER_AGENT 都跟随它,因此不会各自漂移。

可观测性(可选启用)

追踪、指标和事件发布完全可选——只要不设置以下任何环境变量,服务器就零可观测性开销,且运行时绝不加载 OpenTelemetry 或 NATS 包。

OpenTelemetry(追踪 + 指标)——设置 OTEL_EXPORTER_OTLP_ENDPOINT 指向你的 collector HTTP 端点后,服务器会输出:

  • Span(每个请求):tool.<name>expand_query? → searxng_requestrerankfetch(×N)→ tier1_firecrawl | tier2_crawl4ai | tier3_rawfetchpost_extractsearch_and_summarize 另有 summarize_llm

  • 计数器:searxng_search_total{profile, expand}searxng_fetch_total{tier, outcome}searxng_cache_total{namespace, outcome}searxng_errors_total{stage, error_type}

  • 直方图:searxng_search_duration_seconds{profile}searxng_fetch_duration_seconds{tier, outcome}

标准 OTEL 环境变量同样适用(OTEL_SERVICE_NAME 默认为 searxng-mcp)。

NATS 事件——设置 NATS_URL(例如 nats://localhost:4222)后,服务器会在每次搜索、抓取、缓存命中/未命中、robots 跳过和错误时发布一条结构化事件。通过 NATS_CREDS(JWT 凭据文件)或 NATS_USER/NATS_PASSWORD(bcrypt 用户名/密码)进行认证——两者同时设置时凭据文件认证优先。主题:

主题

触发时机

searxng.search.requested

搜索工具被调用

searxng.search.completed

搜索返回(含来源、延迟、是否应用重排序)

searxng.fetch.requested

fetchPage 被调用

searxng.fetch.tier.miss

某一层返回空内容或抛出异常

searxng.fetch.tier.skipped

robots.txt 禁止访问

searxng.fetch.completed

抓取完成(含 tier_servedtext_len、延迟)

searxng.cache.hit / .miss

每次 Valkey 查询时

searxng.error

带阶段标签的错误

每个信封都包含 request_id,并在启用 OTel 时包含 trace_id,以便订阅者将两条流关联起来。主题前缀可通过 NATS_SUBJECT_PREFIX 覆盖。搜索查询会流经 search.* 事件——下游消费者负责任何 PII 脱敏。

礼貌性

  • 诚实的 User-Agent——出站请求标识为 searxng-mcp/<version> (+https://github.com/TadMSTR/searxng-mcp; personal research)

  • robots.txt 合规——每个来源的 /robots.txt 只抓取一次,并在 Valkey 中以 robots:<origin> 为 key 缓存 24 小时。禁止的路径在任何层运行之前就被跳过,并记录为 skipped_robots url=… reason=…

传输方式

stdio(默认)——兼容 Claude Code MCP 插件和 LibreChat 的 stdio 配置。

HTTP——设置 SEARXNG_MCP_TRANSPORT=http 以运行共享的 HTTP/SSE 服务器,适用于多客户端部署或基于 Docker 的场景。绑定到 SEARXNG_MCP_HOST:SEARXNG_MCP_PORT(默认 127.0.0.1:3001):

SEARXNG_MCP_TRANSPORT=http SEARXNG_MCP_PORT=3001 npx @tadmstr/searxng-mcp

向 Claude Code 注册以对接 HTTP 服务器:

claude mcp add-json searxng --scope user '{
  "type": "http",
  "url": "http://localhost:3001/mcp"
}'

会话以 Mcp-Session-Id 请求头为 key,因此多个客户端可以并发连接到同一个共享进程。空闲会话在 HTTP_SESSION_IDLE_TIMEOUT_MS 之后被清理,并硬性限制为 HTTP_MAX_SESSIONS 个——见配置

HTTP 传输认证

HTTP 传输默认不认证,这之所以安全,仅仅是因为它默认绑定 127.0.0.1。如果你将 SEARXNG_MCP_HOST 改为其他任何地址——包括容器运行所必需的 0.0.0.0——请同时设置 SEARXNG_MCP_AUTH_TOKEN

SEARXNG_MCP_AUTH_TOKEN=$(openssl rand -hex 32)

设置后,除 GET /health 外的每个请求都必须携带该令牌作为 RFC 6750 bearer 凭据:

Authorization: Bearer <token>

任何其他情况——无请求头、使用不同方案、令牌错误——都会收到 401,响应带 WWW-Authenticate: Bearer 和 JSON-RPC 错误体。三种情况下的响应完全相同,且绝不回显所提交的凭据。令牌以 SHA-256 摘要进行比较,因此比较是恒定时间的,不会泄露长度信息。

向 Claude Code 注册已认证的服务器:

claude mcp add-json searxng --scope user '{
  "type": "http",
  "url": "http://localhost:3001/mcp",
  "headers": {"Authorization": "Bearer <token>"}
}'

保持该变量未设置则完全保留之前的行为,因此 stdio 用户和现有的回环绑定 HTTP 部署无需任何更改。没有按调用方授权的模型——单个令牌认证的是对服务器的访问,而非特定客户端身份。启动时,非回环绑定且未设置令牌会记录一条警告。

GET /health 有意豁免于该检查。它是容器健康检查和监控存活探针,不接受任何输入,其响应(statuscachesessions)不携带任何机密。

GET /health——无需认证的存活探针,与 MCP 端点一同绑定在 localhost。通过有界缓存命令超时来 ping Valkey(因此该检查本身绝不会挂起),并返回:

{"status": "ok", "cache": "up", "sessions": 3}

或者,当缓存后端不可达时:

{"status": "degraded", "cache": "degraded", "sessions": 3}

sessions 是实时的 HTTP 会话数。对系统管理员监控很有用,可以从 MCP 侧检测缓存降级,而无需直接对缓存后端进行插桩。

前置条件

  • Node.js 20+

  • pnpm(或 npm)

  • 一个运行中的 SearXNG 实例

  • 一个运行中的 Firecrawl 实例

  • 一个运行中的、暴露 Jina 兼容 /v1/rerank 端点的重排序器(可选)

  • 一个运行中的 Valkey 或 Redis 兼容实例(可选,用于结果缓存)

  • 一个运行中的 Ollama 实例,已拉取 qwen3:4b 和/或 qwen3:14b(可选,用于查询扩展和摘要)

SearXNG

SearXNG 必须启用 JSON 输出格式。在 settings.yml 中:

search:
  formats:
    - html
    - json

重排序器

重排序器必须暴露 Jina 兼容的 /v1/rerank 端点。轻量级 FlashRank 封装效果很好——参见 homelab-agent 中的 docker/reranker/ 参考实现。

Firecrawl

任何 Firecrawl 兼容实例都可以。本地的 firecrawl-simple 部署就足够了。如果你的实例需要认证,请设置 FIRECRAWL_API_KEY(对于跳过认证的本地部署,默认为 placeholder-local)。

Crawl4AI

Crawl4AI 是可选的第二层抓取回退,在 Firecrawl 返回空内容时使用(被机器人拦截的页面、JS 重站点)。设置 CRAWL4AI_URL 以启用。如果未设置,级联会跳过该层直接进行原始 HTTP 抓取。

docker run -d -p 11235:11235 unclecode/crawl4ai:0.8.6

如果你的实例需要 API 令牌认证,请设置 CRAWL4AI_API_TOKEN

search_and_summarize 路径上,Crawl4AI 请求使用 fit_markdown 进行去噪内容提取。其他调用方(search_and_fetchfetch_url)使用 raw_markdown

Kiwix(可选)

kiwix-serve 通过 HTTP 提供 ZIM 归档服务。下载所需的 ZIM 文件并以 --nodatealiases-z)运行 kiwix-serve,这样书名才能保持稳定:

kiwix-serve --port 8292 --nodatealiases /path/to/zims/

每个受支持主机所需的 ZIM 文件:

  • Wikipedia:wikipedia_en_all_mini(或 maxi

  • Stack Overflow:stackoverflow.com_en_all

  • Arch Wiki:archlinux_en_all_maxi

ZIM 文件可以从 library.kiwix.org 下载。

Hister(可选)

Hister 是一个由 Firefox 扩展填充的浏览历史索引。设置 HISTER_URL 后,fetchPage 会在调用层级级联之前先查询历史索引——对于抓取器无法处理的登录墙页面和 JS 重页面很有用。

HISTER_URL 设置为你的 Hister 实例基础 URL,如果要求 bearer 令牌认证,则设置 HISTER_TOKEN

Valkey / Redis

任何 Redis 兼容实例均可。推荐使用 Valkey。搜索结果缓存 1 小时;抓取的页面缓存 24 小时。如果不可用,服务器将在无缓存模式下运行。

Ollama

expandsearch_and_summarize 需要它。拉取所需模型:

ollama pull qwen3:4b   # query expansion
ollama pull qwen3:14b  # summarization

think: false 行为会自动处理——无需额外的 Ollama 配置。

配置

所有服务 URL 均可通过环境变量配置。

Variable

Default

Description

SEARXNG_URL

http://localhost:8081

SearXNG 实例 URL

FIRECRAWL_URL

http://localhost:3002

Firecrawl 实例 URL

RERANKER_URL

http://localhost:8787

Reranker 实例 URL

FIRECRAWL_API_KEY

placeholder-local

Firecrawl API 密钥(如需要)

GITHUB_TOKEN

(unset)

GitHub 个人访问令牌 — 将速率限制从 60 提升至 5,000 次/小时

OLLAMA_URL

(unset)

Ollama API 基础 URL — expandsearch_and_summarize 必需

OLLAMA_API_KEY

(unset)

用于已认证 Ollama 代理的 Bearer 令牌 — 设置后添加 Authorization: Bearer <key> 请求头

OLLAMA_EXPAND_MODEL

qwen3:4b

查询扩展(expand 参数)使用的模型。无需重新构建即可覆盖。

OLLAMA_SUMMARIZE_MODEL

qwen3:14b

search_and_summarize 使用的模型。无需重新构建即可覆盖。

LLM_BASE_URL

(unset)

用于 expandsearch_and_summarize 的 OpenAI 兼容聊天端点(如 vLLM、llama.cpp、LM Studio)。必须包含 API 路径 — 例如 http://host:8000/v1 — 服务器会追加 /chat/completions。设置后优先于 OLLAMA_URL,因此可以复用已加载的模型,而无需运行单独的 Ollama 模型。

LLM_MODEL

(unset)

OpenAI 兼容后端的模型 ID;设置后覆盖 OLLAMA_EXPAND_MODEL / OLLAMA_SUMMARIZE_MODEL

LLM_API_KEY

(unset)

OpenAI 兼容后端的 Bearer 令牌 — 设置后添加 Authorization: Bearer <key>

LLM_DISABLE_THINKING

true

发送 chat_template_kwargs.enable_thinking: false,使推理模型(如 Qwen3)返回直接输出。对于拒绝该字段的服务器,请设置为 false

CACHE_URL

redis://localhost:6381

Redis 兼容 URL — 启用结果缓存。也接受 VALKEY_URLREDIS_URL 作为别名。支持 Redis、Valkey 和 Dragonfly。服务器在不可用时会优雅降级。

CACHE_COMMAND_TIMEOUT_MS

2500

Valkey 命令超时 — 停滞/CPU 飙升的缓存后端会拒绝而非挂起(cacheGet() 是每次搜索中的第一个 await)。无效/非正值会回退到默认值,而不会变成会禁用超时的 NaN。

CACHE_CONNECT_TIMEOUT_MS

3000

Valkey 连接超时。与 CACHE_COMMAND_TIMEOUT_MS 相同的回退行为。

CACHE_MAX_RETRIES_PER_REQUEST

2

每个 Valkey 命令在拒绝前的最大重试次数。与 CACHE_COMMAND_TIMEOUT_MS 相同的回退行为。

CACHE_TTL_SECONDS

3600

搜索结果缓存 TTL(秒)

FETCH_CACHE_TTL_SECONDS

86400

已抓取页面缓存 TTL(秒)

CRAWL_MANIFEST_TTL_SECONDS

21600

爬取清单和页面内容缓存 TTL(秒)(6 小时)

CRAWL_MAX_PAGES_DEFAULT

20

未传入 max_pagescrawl_site 返回的默认最大页数

CRAWL_BFS_ENABLED

false

设置为 true 可在全局启用 crawl_site 中的 BFS 回退。也可以通过 bfs 参数按调用启用。

CRAWL_BFS_MAX_DEPTH

3

BFS 爬取的最大链接跳数深度

FIRECRAWL_CRAWL_POLL_INTERVAL_MS

2000

等待 Firecrawl 爬取任务完成时的轮询间隔

FIRECRAWL_CRAWL_MAX_WAIT_MS

120000

在回退到站点地图之前等待 Firecrawl 爬取任务的最长时间

EXPAND_QUERIES

false

设置为 true 可在全局启用查询扩展

CRAWL4AI_URL

(unset)

Crawl4AI 实例 URL — 在 Firecrawl 失败时启用第二层抓取回退

CRAWL4AI_API_TOKEN

(unset)

可选 Bearer 令牌,用于启用了 API 令牌保护的 Crawl4AI 实例

WAYBACK_ENABLED

false

设置为 true 可启用 Wayback Machine 第四层回退 — 当所有三层都失败时获取存档快照

ADBLOCK_PROXY_URL

(unset)

用于第二层(Crawl4AI)和第三层(原始 Node fetch)广告拦截的 HTTP 代理 URL — 例如 http://adblock-proxy:8118。参见 docker/adblock-proxy/

KIWIX_URL

(unset)

kiwix-serve 基础 URL(例如 http://localhost:8292)— 为 Wikipedia、Stack Overflow 和 Arch Wiki 启用 Kiwix 快速路径。未设置时该功能禁用且零开销。

HISTER_URL

(unset)

Hister 浏览历史索引基础 URL — 在层级级联之前为登录墙和 JS 密集型页面启用 Hister 快速路径。未设置时该功能禁用且零开销。

HISTER_TOKEN

(unset)

用于 Hister API 认证的 Bearer 令牌。当设置了 HISTER_URL 且实例启用了令牌认证时必需。

YOUTUBE_TRANSCRIPT_ENABLED

true

fetch_url 中启用 YouTube 字幕快速路径。设置为 false 可禁用(例如非官方 timedtext 端点在上游损坏时)。

YOUTUBE_IGNORE_ROBOTS

false

选择在 YouTube 的 robots.txt 禁止 /api/ 的情况下仍获取 YouTube 字幕。默认遵守 robots(快速路径保持休眠,回退到级联)。

REDDIT_FASTPATH_ENABLED

true

fetch_url 中启用 Reddit .json 快速路径。设置为 false 可禁用。

REDDIT_IGNORE_ROBOTS

false

选择在 Reddit 的 robots.txtDisallow: /)禁止的情况下仍获取 Reddit .json。默认遵守 robots(快速路径保持休眠,回退到级联)。

SEARXNG_MCP_TRANSPORT

stdio

传输模式:stdio(默认,单客户端)或 http(共享 HTTP/SSE 服务器)。

SEARXNG_MCP_PORT

3001

HTTP 监听端口(仅 HTTP 传输模式)。

SEARXNG_MCP_HOST

127.0.0.1

HTTP 监听地址(仅 HTTP 传输模式)。

SEARXNG_MCP_AUTH_TOKEN

(unset)

仅 HTTP 传输。设置后,除 GET /health 外的每个请求都必须发送 Authorization: Bearer <token>,否则返回 401。未设置(默认)则完全禁用检查。只要 SEARXNG_MCP_HOST 不是回环地址,就应设置此项 — 参见 HTTP 传输认证

HTTP_SESSION_IDLE_TIMEOUT_MS

600000

仅 HTTP 传输。空闲时间超过此值的会话会被后台清理程序驱逐(有进行中请求的会话除外,因此长时间的 crawl_site 调用绝不会在请求中途被关闭)。限制因客户端在回合中途被终止而导致的会话映射增长,此类客户端永远不会触发 transport.onclose

HTTP_MAX_SESSIONS

256

仅 HTTP 传输。硬上限兜底 — 如果会话映射超过此值,无论空闲超时如何,都会驱逐最近最少使用的空闲会话。

NATS_USER

(unset)

用于 bcrypt 用户名/密码认证的 NATS 用户名,与 NATS_PASSWORD 一起使用。如果同时设置了 NATS_CREDS,则忽略此项(凭据文件 JWT 认证优先)。

NATS_PASSWORD

(unset)

NATS 密码 — 参见 NATS_USER

安装

npm(推荐)

npm install -g @tadmstr/searxng-mcp

或直接使用 npx 运行:

npx @tadmstr/searxng-mcp

从源码构建

git clone https://github.com/TadMSTR/searxng-mcp.git
cd searxng-mcp
pnpm install
pnpm build

输出:build/src/index.js

MCP 客户端配置

Claude Code(CLI)

推荐使用 claude mcp add-json 注册服务器,以支持完整的环境变量注入:

claude mcp add-json searxng --scope user '{
  "command": "npx",
  "args": ["-y", "@tadmstr/searxng-mcp"],
  "env": {
    "SEARXNG_URL": "http://localhost:8081",
    "FIRECRAWL_URL": "http://localhost:3002",
    "RERANKER_URL": "http://localhost:8787",
    "OLLAMA_URL": "http://localhost:11434",
    "CACHE_URL": "redis://localhost:6379",
    "CACHE_TTL_SECONDS": "3600",
    "FETCH_CACHE_TTL_SECONDS": "86400",
    "EXPAND_QUERIES": "false",
    "CRAWL4AI_URL": "http://localhost:11235"
  }
}'

这会写入 ~/.claude.json。请勿将 searxng 添加到 ~/.claude/settings.json——该文件不用于 Claude Code 中的 MCP 环境变量注入。

Claude Desktop(claude_desktop_config.json

{
  "mcpServers": {
    "searxng": {
      "command": "npx",
      "args": ["-y", "@tadmstr/searxng-mcp"],
      "env": {
        "SEARXNG_URL": "http://localhost:8081",
        "FIRECRAWL_URL": "http://localhost:3002",
        "RERANKER_URL": "http://localhost:8787",
        "OLLAMA_URL": "http://localhost:11434",
        "CACHE_URL": "redis://localhost:6379",
        "CRAWL4AI_URL": "http://localhost:11235"
      }
    }
  }
}

LibreChat(librechat.yaml

mcpServers:
  searxng:
    type: stdio
    command: node
    args:
      - /path/to/searxng-mcp/build/src/index.js
    env:
      SEARXNG_URL: http://localhost:8081
      FIRECRAWL_URL: http://localhost:3002
      RERANKER_URL: http://localhost:8787
      OLLAMA_URL: http://localhost:11434
      CACHE_URL: redis://localhost:6379
      CRAWL4AI_URL: http://localhost:11235

GitHub URL

GitHub URL 由原生处理,无需 Firecrawl。githubFetch 根据主机名进行分发:

  • 仓库根目录github.com/owner/repo)——通过 GitHub API 获取 README

  • 文件 blobgithub.com/owner/repo/blob/branch/path/to/file)——重写为 raw.githubusercontent.com 并获取原始内容

  • 原始文件raw.githubusercontent.com/...)——按原样直接获取

  • APIapi.github.com/...)——响应解码(base64 content 字段)或格式化为 JSON 输出

此前,直接的 raw.githubusercontent.comapi.github.com URL 仅匹配 github.com,会落入 HTML 抓取层级级联,而该级联无法渲染原始文本文件或裸 JSON 响应——它们 100% 失败。现在它们走 GitHub 快速路径。

未认证请求的速率限制为 60 次/小时。设置 GITHUB_TOKEN 可将其提升至 5,000 次/小时。

安全

URL 安全(SSRF)

每次对受调用方影响或发现的 URL 的出站获取——原始 HTTP 层、robots.txt / llms.txt / Wayback / sitemap 探测、BFS 爬取链接获取以及 GitHub 快速路径——都受到双重防护:

  1. 字符串检查assertPublicUrl)——拒绝非 HTTP(S) URL 和私有/内部 IP 字面量:RFC1918(10.x192.168.x172.16–31.x)、回环(127.x::1)、链路本地/云元数据(169.254.x)、CGNAT(100.64/10)、IPv6 ULA(fc00::/7)和链路本地(fe80::/10)、IPv4 映射以及组播/保留范围。

  2. 连接时 DNS 验证——一个共享的 undici 分发器,其 connect.lookup 验证 解析后的 地址(即套接字实际连接的地址)。这弥补了 DNS 重绑定 / TOCTOU 漏洞——即公共主机名解析为私有地址的情况——并且它会在每个重定向跳转时重新运行,因此重定向链无法跳入你的内部网络。

Firecrawl(tier1)和 Crawl4AI(tier2)自行解析并获取目标 URL,因此上述连接时分发器无法覆盖它们。fetchPagecrawlSite 在分发给任一服务之前立即调用 assertResolvedPublic(url)——一次性主机名解析,拒绝任何私有/保留结果——从而关闭该路径上常见的 DNS 重绑定情况(TOCTOU 窗口比连接时防护更窄,因为服务会重新解析)。

已配置的内部服务(Firecrawl、Crawl4AI、SearXNG、Ollama、Reranker)通过各自的 URL 访问,有意不加以防护。

重定向保护

原始 HTTP 和 GitHub 快速路径获取额外使用 redirect: "manual" 并直接拒绝 3xx 响应(Location 头永远不会回显给调用方)。跟随重定向的探测(robots.txt、llms.txt、sitemap)由上述连接时 DNS 验证覆盖,该验证会重新检查每一跳。

传输层暴露

stdio 没有网络面。HTTP 传输默认绑定 127.0.0.1,在该配置下无需认证;如果将其移出回环地址而不设置 SEARXNG_MCP_AUTH_TOKEN,则会将所有工具——包括任意 URL 的 fetch_url 和破坏性的 clear_cache——暴露给任何可以路由到该端口的对象。参见 HTTP 传输认证

依赖审计

CI 在每次推送时运行 pnpm audit。锁文件(pnpm-lock.yaml)已提交,以确保构建可复现、可审计。

凭据处理

服务器不存储或记录任何凭据。API 密钥(FIRECRAWL_API_KEYGITHUB_TOKENCRAWL4AI_API_TOKEN)从环境变量中读取,仅用于对各自服务的出站请求。

输入验证

环境变量在启动时进行验证——RERANK_RECENCY_WEIGHT 在值为 NaN、负数或 >1.0 时发出警告。数值型工具参数使用带范围约束的 z.coerce.number()

贡献

有关设置说明、提交规范和 PR 流程,请参阅 CONTRIBUTING.md

集成测试

一个覆盖域数据库并发的真实 Valkey 集成测试套件以 VALKEY_TEST_URL 为门槛,未设置时完全跳过,因此在没有 Valkey 的情况下,普通的 pnpm test 仍然可以运行:

VALKEY_TEST_URL=redis://:<password>@<host>:<port>/<scratch-db> pnpm test

使用临时数据库索引——该套件会写入和删除 domain:* 键,并拒绝针对索引 01 运行,作为安全防护。

许可证

MIT

Install Server
A
license - permissive license
A
quality
A
maintenance

Maintenance

Maintainers
Response time
6dRelease cycle
19Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server for web search and content extraction using DuckDuckGo or SearXNG, with Playwright-based fetching and LLM-powered data extraction.
    140
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    A minimal MCP server that exposes a private SearXNG instance as a search tool over streamable-HTTP, enabling web search from the llama.cpp WebUI or any compatible MCP client.
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Offline-first MCP server for web search and content fetching. It requires no external API keys and uses local models for intent classification, optional cross-lingual search, semantic re-ranking, and direct-answer extraction.
    ISC
  • A
    license
    Not graded
    quality
    C
    maintenance
    A fully local MCP server that provides web search via self-hosted SearXNG and page-to-markdown conversion (static and JS-rendered), all aggregated behind a single endpoint for use with AI assistants.
    MIT

View all related MCP servers

Related MCP Connectors

  • Serper MCP — wraps the Serper Google Search API (serper.dev)

  • MCP server for Google search results via SERP API

  • Multi-engine search for AI agents. Trust scoring, local corpus, MCP-native. Self-hostable, BYOK.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TadMSTR/searxng-mcp'

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