mcpField
O
OwnSearch

OwnSearch

本地服务
github.com搜索与检索0今天更新

关于 OwnSearch

OwnSearch 是自托管的 MCP 和 HTTP 搜索服务,通过评分后的公共 SearXNG 实例组成搜索集群,适合需要自管搜索流程的用户。它在本地 SQLite 保存集群状态,并支持实例轮换、故障切换和结果合并。

主要功能

  1. 01发现并探测公共 SearXNG 实例
  2. 02评分并维护本地实例集群
  3. 03轮换实例并在故障时切换
  4. 04合并结果并保留来源信息
  5. 05抓取网页并提取正文

适用场景

  1. 01通过多个 SearXNG 实例执行网页搜索
  2. 02实例故障时继续获取搜索结果
  3. 03抓取网页并提取 Markdown 或文本
  4. 04检查实例健康状态与搜索能力

MCP 相关

作为 MCP 服务,OwnSearch 可通过 stdio 或 Streamable HTTP 连接客户端,提供搜索、网页抓取、实例管理与状态查询工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库
安装包
cargoownsearch0.3.0
npm@devops-infinity/ownsearch0.3.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

OwnSearch

通过一组按评分筛选的公共 SearXNG 实例,提供可自托管的 MCP 和 HTTP 搜索服务。

mcp-name: io.github.devops-infinity/ownsearch

状态:预发布版本,工作区版本为 0.2.0。

OwnSearch 会从 searx.space 发现公共 SearXNG 实例,以较低频率探测并评分,将实例列表保存在本地 SQLite 数据库中;它会轮换起始实例,在实例故障时重试,并从下一个健康实例返回结果。每条结果都会附带提供该结果的来源,包括实例,以及在已知时提供结果的引擎。它通过标准输入/输出或 Streamable HTTP 作为模型上下文协议(MCP)服务运行,HTTP 端口还提供两个 REST 调用。

所有者:Md. Sazzad Hossain Sharkar。

参考资料:实例策略见 docs/scanner-policy.md,运行手册见 docs/operations.md,发布流程见 RELEASING.md,报告政策见 SECURITY.md。

目录

功能

  • 从 https://searx.space/data/instances.json 发现公共 HTTPS SearXNG 实例;首次运行时,在进行任何网络调用前导入包含 67 个实例的内嵌快照。
  • 每次扫描对每个候选实例探测一次:解析主机并验证 TLS 证书链和证书日期,读取 /config,并进行一次 JSON 搜索。只有在 JSON 搜索被拒绝时才会进行 HTML 搜索;只有在实例声明支持 exact-Google 引擎且 JSON 搜索成功时,才会进行 exact-Google 搜索。
  • 评分前先应用硬性门槛,因此证书即将过期、存在分析跟踪器或无法读取 /config 的实例不会进入活跃实例列表。
  • 通过实例数量上限、每个网络的实例数量上限和滞后机制选择活跃实例列表,避免一次不良扫描就移除正常运行的实例。
  • 每次搜索都会轮换起始实例;遇到网络错误或 5xx 时,每个实例最多尝试三次;反复失败的实例会进入冷却状态;随后切换到下一个实例,直到搜索成功或超过截止时间。
  • 合并多个实例的结果,保留每条来源观测记录,并标记覆盖不完整的情况。
  • 绝不重试 429,绝不执行工作量证明,也绝不伪装成人类浏览器。如果操作员设置了 OWNSEARCH_CAPSOLVER_KEY,对于只出现在渲染页面中的验证挑战,可以使用 CapSolver 服务解决该页面的挑战。

默认启用的功能

这些功能默认启用。每项功能都由配置中对应的设置控制。

  • HTML 搜索回退:开启。当某个实例以 403、其他 4xx 或 5xx 响应拒绝 JSON,或返回非 JSON 响应体时,OwnSearch 会改为读取普通 HTML 结果页。对于 401、429 和挑战页面,不会重试 HTML;这些情况将按隔离和冷却规则处理。
  • 轮询选择:开启。每次搜索都会从不同的健康实例开始。
  • 故障转移:开启。发生故障的实例会按配置进行重试,随后进入冷却,搜索会切换到下一个实例。
  • 所选实例启用的所有搜索引擎:开启。默认情况下,OwnSearch 不发送引擎筛选条件,因此 Google、Bing、DuckDuckGo、Brave 以及该实例运行的所有其他引擎均可用。可在调用时设置 engines 以缩小范围。
  • 所有 SearXNG 类别:开启。默认情况下,OwnSearch 不发送类别筛选条件。
  • 精确 Google 探测:开启;只要实例声明支持 google 引擎,就会启用。
  • 页面提取:开启。ownsearch_fetch 会抓取公开页面,并以 Markdown、纯文本或清理后的 HTML 格式返回内容,同时包含标题并限制内容大小。
  • JavaScript 渲染:开启。当页面是空壳页面或调用设置了 render: "always" 时,会使用无头 Chrome 渲染;浏览器会在使用期间保持打开,并在空闲、连续两次未收到健康检查响应或达到最长运行时间时关闭。
  • 同主机爬取:开启。ownsearch_fetch 会从你指定的页面跟进最多 max_pages - 1 个链接,最多七个,并将每个页面放在 pages 下返回。same_host_only 默认为 true,因此除非你允许,否则调用不会跳转到其他网站。
  • 结果归属信息、字段预设、响应缓存、会话统计和类型化数据库更改(带预览和一次性令牌)均可直接使用,无需额外标志。

它不会做什么

  • 它不会托管或运营 SearXNG 实例。
  • 它不会调用付费搜索 API。
  • 它不会让你的查询匿名。每个公共实例的运营者都能看到这些查询。
  • 它不会在普通搜索结果上运行 JavaScript。无头浏览器仅供提取工具用于你指定的页面;作为最后手段,也会用于拒绝所有 HTTP 格式的实例所返回的搜索页面或探测页面。
  • 它不会绕过机器人检查。许多公共实例会向自动化客户端返回 429、挑战页面或 CAPTCHA。OwnSearch 会记录这些情况并继续尝试其他实例;但如果设置了 OWNSEARCH_CAPSOLVER_KEY,则可通过 CapSolver 服务解决仅在渲染页面中出现的挑战。

要求

  • 构建需要 Rust 1.94.1 或更高版本。固定工具链版本见 rust-toolchain.toml(1.99.1)。
  • Linux 或 macOS 机器。Windows 构建也在发布目标列表中。
  • 用于发现、探测和搜索的出站 HTTPS 连接。
  • 用于构建捆绑的 SQLite 的 C 编译器:Debian 和 Ubuntu 上的 build-essential,或 macOS 上的 Command Line Tools。
  • 用于 JavaScript 渲染的 Chrome 或 Chromium 可执行文件。如果自动检测未能找到,请设置 OWNSEARCH_BROWSER_PATH。

构建和安装

git clone https://github.com/devops-infinity/ownsearch
cd ownsearch
cargo build --release --locked

二进制文件会生成在 target/release/ownsearch。通过完整检查后,可将其安装到 ~/.local/bin:

tools/reinstall.sh

快速开始

ownsearch doctor
ownsearch scan                # refresh discovery and probe the fleet
ownsearch scan                # once OWNSEARCH_SCAN_MIN_INTERVAL_SECS (30 by default) has passed, a second pass promotes repeat successes to active
ownsearch serve               # MCP over stdio

试运行不会更改任何服务集数据,只会打印将要执行的操作。首次运行时可能会创建空的状态架构:

ownsearch scan --dry-run --limit 12

搜索使用当前活动服务集。如果没有活动实例,OwnSearch 会回退到通过所有硬性门槛的已扫描候选实例,并在 warnings 中说明这一点。

连接 MCP 客户端

{
  "mcpServers": {
    "ownsearch": {
      "command": "/home/you/.local/bin/ownsearch",
      "args": ["serve"],
      "env": {
        "OWNSEARCH_STATE_DIR": "/home/you/.local/state/ownsearch"
      }
    }
  }
}

无需 API 密钥。OwnSearch 唯一可能持有的机密是 HTTP Bearer 令牌,仅在通过 Streamable HTTP 提供服务时使用。

使用 Streamable HTTP 时,将客户端指向 http://127.0.0.1:8774/mcp,或指向同一主机且不带路径的地址。这两个地址都会提供 MCP 端点,其他路径均会返回带有问题详情的 404 响应。该端口还响应 /healthz、/startupz、/readyz 和 /metrics。设置 OWNSEARCH_BEARER_TOKENS 后,请发送 Authorization: Bearer <token>。REST 调用 POST /v1/search 和 POST /v1/fetch 将工具参数作为 JSON 请求体。

工具

  • ownsearch_search:联邦式网络搜索。参数:query(必填)、categories、engines、language、page、time_range(day、week、month、year)、safesearch(off、moderate、strict)、limit、fields(minimal、standard、full)、mode(fast、balanced、exhaustive)、timeout_secs 和 result_text(summary、full)。回答前可能会刷新本地服务集状态。
  • ownsearch_fetch:以 markdown(默认)、text 或 html 格式获取公开页面;url 为必填项,max_chars 范围为 1000 到 200000。max_pages 范围为 1 到 8,默认值为 3;设为大于 1 时,会跟随第一页中的链接,并将结果放在 pages 下;除非 same_host_only 为 false,否则仅访问同一主机。HTTP 重定向最多跟随三跳,每一跳都会像首次请求一样通过公开地址检查;回答会报告 finalUrl 和 redirects 链,调用方无需猜测链接最终指向何处。application/pdf 响应会在解压文本上限为 8 MiB 的条件下进行解析,并整理成 Markdown 段落。render 用于选择浏览器:auto(默认)仅渲染看起来像空 JavaScript 框架的页面,always 渲染每次调用,never 则仅使用 HTTP。Markdown 从主要内容中提取:导航、侧边栏、Cookie 横幅、分享区块、评论区和页脚会被清除;内容最密集的根节点优先于链接列表;代码围栏会标注语言。私有地址和环回地址会被拒绝,且每个页面都会受到大小限制并经过清理。
  • ownsearch_instance_info:提供单个实例或实例列表的生命周期和能力信息,包括其 slug、状态、评分、排名、版本、JSON 和 HTML 访问方式、引擎、类别以及精确 Google 结果的证据。每个结果来源和每次扫描状态变更都会携带 slug;失败的来源会标明其实例 ID 和 URL。/config 中的实例名称来自 ownsearch_db_query,其 entity 为 "capabilities"。
  • ownsearch_instance_health:提供硬性门槛结果、证书剩余天数、TLS 协议和等级、搜索中位耗时、冷却状态、连续失败次数以及最近的生命周期事件。
  • ownsearch_scan:刷新发现结果、探测实例、重新评分并重新选择服务集。默认值为 dry_run: true。在同一进程内,每个状态数据库一次只能运行一个写入扫描;两次运行之间会等待 OWNSEARCH_SCAN_MIN_INTERVAL_SECS,并且如果指定实例尚未到期,会拒绝执行,除非调用设置了 force。
  • ownsearch_session:提供本地调用次数、缓存状态、账本长度和头部信息,以及服务集大小。不进行网络调用。
  • ownsearch_db_query:对实例、质量、策略覆盖项、能力快照、事件、快照和发现运行进行有界只读查询。每个实体都有自己的筛选条件;如果所选实体无法应用某个筛选条件,则会拒绝该条件,而非忽略。事件通过 SQL 分页,因此可以访问任意偏移量。它不接受 SQL。
  • ownsearch_db_crud:执行一项有类型约束的生命周期或策略变更。需要写入模式、变更原因,以及来自试运行预览的一次性确认令牌。无法删除实例行。

每个工具都会返回 structuredContent 和一行文本摘要。每个输入架构都将 additionalProperties 设为 false。预设可能会省略的所有字段,在已发布的输出架构中均为可选项。

搜索行为

模式用于控制有多少个实例响应一次查询。

  • fast 目标为一个实例。
  • balanced(默认模式)目标为三个实例。
  • exhaustive 目标为 OWNSEARCH_EXHAUSTIVE_MAX。

所有模式的故障转移方式相同。选中的实例会并行响应。对于每个实例,网络错误、超时或 5xx 最多重试 OWNSEARCH_SEARCH_ATTEMPTS 次。除 408 和 429 之外的 4xx、403 或质询页面都不会重试。如果实例仍然失败,OwnSearch 会设置其 cooldown_until,记录一个 search_failed 事件,并按评分顺序尝试下一个实例,直到达到目标数量或搜索截止时间(OWNSEARCH_SEARCH_DEADLINE_SECS)。搜索失败不会改变状态,也不会更改探测计数器。扫描探测或操作员命令会将实例切换到活跃、观察或隔离状态,且只有探测才会重置成功和失败计数。故障转移会按顺序继续遍历评分后的实例,直到达到目标数量或截止时间,因此仍能找到列表靠后的答案。前面设有一个有界队列:OWNSEARCH_SEARCH_MAX_CONCURRENT 个搜索会同时运行,最多有 OWNSEARCH_SEARCH_QUEUE_LIMIT 个搜索等待空位,等待时间为 OWNSEARCH_SEARCH_QUEUE_WAIT_SECS;其余搜索会返回 ownsearch.rate_limited,不会继续堆积任务,从而在小型机器上限制内存和 CPU 的使用。零结果答案也算成功,而非失败;只有结果中不含可用标题和 URL 的页面才算解析器失败。

轮询会在排名靠前的健康实例范围内轮换起始位置,因此连续两次搜索不会总是从同一个实例开始。如果你希望严格按评分顺序处理,可通过 OWNSEARCH_ROUND_ROBIN=false 关闭此功能。

在任何扫描为实例群评分之前,或所有已评分实例都处于冷却状态时,搜索会回退到排名最高、且未通过硬性检查失败的已发现实例,而不是以 ownsearch.no_fleet 失败,并会在响应的 warnings 中说明这一点。响应绝不会编造结果:当所有尝试都遭到拒绝或受到速率限制时,sources.failed 会列出每个实例、其代码以及响应内容。sources.fallbacks 会列出每个使用 HTML 解析器而非 JSON 返回答案的实例。

字段预设用于控制负载大小。minimal 保留标题、URL、排名、评分和来源 ID。standard 会额外包含摘要、引擎、发布日期和完整来源列表。full 保留所有内容。

扫描器策略

  • 内置调度器会在启动时以及每个发现时间窗口(OWNSEARCH_DISCOVERY_REFRESH_SECS)刷新发现结果,文档上限为 500 条记录。随后,它会在扫描间隔到期时探测符合条件的实例;每次只扫描一个实例,并在扫描前等待一段随机抖动时间。
  • 即使实例的得分会使其落选,固定的实例仍会保留在选择结果中。固定实例会优先于得分排序、滞后机制、每个网络的数量上限以及 Google 要求,并允许候选记录或缺失记录加入实例集群。硬性门槛检查失败的实例仍会被排除。
  • 如果发现记录中的主机解析到环回、私有、链路本地、文档专用或保留地址,则会跳过该记录;明确扫描被拒绝、已禁用、已退役或处于冷却状态的实例时会遭到拒绝。
  • 每次运行中,每个实例的每种类型只探测一次。
  • 默认情况下,探测任务并发数为 4,并带有随机抖动。OWNSEARCH_SCAN_CONCURRENCY 可更改任何运行(定时或按需)的并发数。
  • 429 会启动冷却,但保留实例状态。401 或挑战页面会立即将实例隔离。403 会计为扫描失败:重新安排扫描,并在失败次数超过阈值后将实例转入观察期或隔离状态。重复失败也会降低实例得分。
  • 用户代理会标明产品名称:OwnSearch (MCP fleet scanner; +https://github.com/devops-infinity/ownsearch) v<version>。
  • 不轮换代理,也不伪造请求头。只有在所有 HTTP 格式都被拒绝后,浏览器才会作为最后手段访问实例页面以检查其功能;绝不会用浏览器绕过已检测到的挑战。

完整策略见 docs/scanner-policy.md。

质量模型

硬性门槛,按以下顺序检查。任一项失败,实例都会被排除在活跃实例集群之外。

  • 仅限 HTTPS。
  • 证书链有效,且主机名匹配。
  • 证书剩余有效天数不少于 OWNSEARCH_CERT_MIN_DAYS。
  • 不含分析跟踪器。
  • /config 可解析。
  • 必须包含精确的 Google,但仅在 OWNSEARCH_GOOGLE_REQUIRED=true 时要求。

总分为 100 分:

  • 月度正常运行时间,20 分。
  • 年度正常运行时间,10 分。
  • 搜索成功率,20 分。
  • 搜索中位耗时,15 分。
  • 初始响应成功率和耗时,10 分。
  • 精确 Google 的成功率和耗时,10 分。
  • TLS 等级、协议和证书有效期,10 分。
  • SearXNG 版本新近程度,5 分。
  • 有上限的修正项,最多 5 分,依据包括引擎覆盖率、类别覆盖率、连续成功、连续失败和解析器偏差。

实例集群选择按得分排序,最多选取 OWNSEARCH_FLEET_MAX 个实例;同一公告网络前缀下最多选取 OWNSEARCH_MAX_PER_NETWORK 个实例;排除 Tor 记录;如果设置了 OWNSEARCH_GOOGLE_REQUIRED,则排除不支持精确 Google 的实例,但固定的实例除外。滞后机制要求连续 OWNSEARCH_PROMOTE_SUCCESSES 次扫描成功才会晋升,连续 OWNSEARCH_PROBATION_FAILURES 次扫描失败才会降级,连续 OWNSEARCH_QUARANTINE_FAILURES 次扫描失败才会隔离。恢复的缺失实例会先进入观察期。

配置

设置的优先级依次为:CLI 标志、OWNSEARCH_* 环境变量、${XDG_CONFIG_HOME}/ownsearch/profile.toml 中的 TOML 配置档案,然后是内置默认值。

大多数环境变量都有对应的配置档案键:去掉 OWNSEARCH_ 前缀,并将其余部分转换为小写。例如,OWNSEARCH_FLEET_MAX 对应 fleet_max,OWNSEARCH_STATE_DIR 对应 state_dir。有三个键不遵循此规则:OWNSEARCH_BROWSER_PATH 对应 browser_executable,而 OWNSEARCH_BEARER_TOKENS 和 OWNSEARCH_PROFILE 没有对应的配置档案键。只有配置档案中存在的键有两个:cache_max_bytes 和 preset。

路径和传输方式
  • OWNSEARCH_PROFILE:TOML 配置文件的路径。
  • OWNSEARCH_STATE_DIR:存放 instances.db、快照、事件和备份的目录。默认值为 ${XDG_STATE_HOME}/ownsearch。
  • OWNSEARCH_LEDGER_DIR:存放 calls.jsonl、其归档文件和 args.key 的目录。默认值为 ${XDG_DATA_HOME}/ownsearch/ledger。
  • OWNSEARCH_HTTP:使用 Streamable HTTP 而非 stdio 提供服务。默认值为 false。
  • OWNSEARCH_BIND:HTTP 绑定地址。默认值为 127.0.0.1:8774。
  • OWNSEARCH_BEARER_TOKENS:以逗号分隔的 bearer 令牌,每个至少 32 个字符。
  • OWNSEARCH_ALLOWED_HOSTS:HTTP 模式下以逗号分隔的 Host 值。
  • OWNSEARCH_ALLOWED_ORIGINS:HTTP 模式下以逗号分隔的 Origin 值。
  • OWNSEARCH_LOG_FORMAT:text 或 json。日志仅写入 stderr。
  • OWNSEARCH_ALLOW_PRIVATE_INSTANCES:接受发现记录、探测、搜索和抓取中的回环地址及专用地址。默认值为 false,此选项仅用于本地测试。在任何可访问互联网的部署中都应保持关闭,因为启用后,恶意发现文档可能会将扫描器指向本地服务。
发现和扫描
  • OWNSEARCH_DISCOVERY_URL:发现源。默认值为 https://searx.space/data/instances.json。
  • OWNSEARCH_DISCOVERY_REFRESH_SECS:刷新间隔。默认值为 21600。
  • OWNSEARCH_OFFLINE:跳过发现,仅使用本地状态。默认值为 false。
  • OWNSEARCH_SCAN_CONCURRENCY:并行探测数,范围为 1 到 8。默认值为 4。
  • OWNSEARCH_SCAN_JITTER_MS:探测之间的随机延迟,上限为此毫秒数。默认值为 250。
  • OWNSEARCH_PROBE_TIMEOUT_SECS:每个探测步骤中单个请求的超时时间。默认值为 15;单次探测在达到此值的 5 倍时停止。
  • OWNSEARCH_SCAN_DEADLINE_SECS:整个扫描的时限。默认值为 600,范围为 30 到 7200。超过时限后,扫描会发出警告并停止。
  • OWNSEARCH_SCAN_MIN_INTERVAL_SECS:同一状态数据库上两次写入扫描之间的最短间隔。默认值为 30,范围为 0 到 3600;设为 0 可关闭间隔限制。无论如何,同一进程内始终一次只运行一个扫描。
  • OWNSEARCH_FETCH_DEADLINE_SECS:整个抓取的时限,包括跟踪链接和浏览器渲染。默认值为 60,范围为 5 到 600。
  • OWNSEARCH_BROWSER:在无头 Chrome 中渲染 JavaScript 页面。默认值为 true。
  • OWNSEARCH_BROWSER_PATH:Chrome 或 Chromium 可执行文件。留空时自动检测。
  • OWNSEARCH_BROWSER_IDLE_SECS:浏览器空闲时保持打开的时间。默认值为 120,范围为 30 到 3600。
  • OWNSEARCH_BROWSER_NO_SANDBOX:传入 --no-sandbox;对于无法设置沙箱的容器,此选项为必需。默认值为 false。
  • OWNSEARCH_BROWSER_WATCHDOG_SECS:检查此进程启动的浏览器是否响应的频率。默认值为 30,范围为 5 到 600。连续两次未收到响应时会关闭浏览器。
  • OWNSEARCH_BROWSER_MAX_LIFETIME_SECS:浏览器会话被替换前可持续的最长时间。默认值为 1800,范围为 60 到 86400。
  • OWNSEARCH_REQUEST_TIMEOUT_SECS:HTTP 客户端超时时间。默认值为 30。
  • OWNSEARCH_CONNECT_TIMEOUT_SECS:连接超时时间。默认值为 5。
  • OWNSEARCH_MAX_UPSTREAM_BYTES:响应正文大小上限。默认值为 4194304。
  • OWNSEARCH_COOLDOWN_SECS:触发速率限制、遇到验证挑战或搜索失败后的冷却时间。默认值为 3600。
  • OWNSEARCH_PROMOTE_SUCCESSES、OWNSEARCH_PROBATION_FAILURES、OWNSEARCH_QUARANTINE_FAILURES:滞后阈值。默认值分别为 2、2、4。
  • OWNSEARCH_FLEET_MIN、OWNSEARCH_FLEET_MAX:实例集群大小。默认值分别为 6 和 12。
  • OWNSEARCH_MAX_PER_NETWORK:每个公告网络前缀允许的实例数。默认值为 2。
  • OWNSEARCH_CERT_MIN_DAYS:证书有效期门槛。默认值为 14。
  • OWNSEARCH_HTML_FALLBACK:启用 HTML 探测和回退。默认值为 true。
  • OWNSEARCH_GOOGLE_REQUIRED:将精确匹配 Google 设为硬性门槛。默认值为 false。
搜索
  • OWNSEARCH_SEARCH_DEADLINE_SECS:整个搜索的截止时间,默认 30。
  • OWNSEARCH_EXHAUSTIVE_MAX:exhaustive 模式下的实例数,默认 16。
  • OWNSEARCH_SEARCH_ATTEMPTS:每个实例的尝试次数,范围为 1 至 5。默认 3。
  • OWNSEARCH_SEARCH_FAILOVER:故障时切换到下一个实例。默认 true。
  • OWNSEARCH_ROUND_ROBIN:轮换起始实例。默认 true。
  • OWNSEARCH_RESULT_CAP:默认结果上限,也是一次调用的 limit 上限。默认 25,范围为 1 至 100。
  • OWNSEARCH_SEARCH_MAX_CONCURRENT:同时运行的搜索数,默认 8。
  • OWNSEARCH_SEARCH_QUEUE_LIMIT:允许等待空位的搜索数,默认 64。
  • OWNSEARCH_SEARCH_QUEUE_WAIT_SECS:排队中的搜索等待多久后返回 ownsearch.rate_limited,默认 30。
  • OWNSEARCH_CACHE_TTL_SECS:缓存的答案保持新鲜的时长。默认 300,设为 0 可关闭缓存。
  • 配置文件键 cache_max_bytes:缓存字节上限。默认 16 MiB。
  • 配置文件键 preset:默认字段预设,可选 minimal、standard 或 full。默认 standard。
保留窗口与维护
  • OWNSEARCH_KEEP_WINDOW:账本归档、事件行和迁移前备份的保留时长。接受 90s、15m、2h、3d 或纯秒数。默认 3d。最短 1 小时,最长 90 天;负值或格式错误的值会在启动时被拒绝。
  • OWNSEARCH_MAINTENANCE_INTERVAL_SECS:运行中的服务执行清理程序的频率。默认 3600,最小 60,最大 86400。
  • OWNSEARCH_WATCHDOG_SECS:进程在退出前允许无进展的时长;超时后进程以代码 75 退出,以便监管程序重新启动。默认 120,范围为 0 至 3600;设为 0 可关闭此功能。

清理程序会在启动时、每次扫描应用后、服务运行期间按该间隔执行,也会在 ownsearch db maintenance 中执行。如果实时账本中最早的行超过保留时长,就会轮换账本;还会删除超过保留窗口的账本归档和 pre-migration-*.db 文件,并从 instances.events.jsonl 中清除旧行。清理期间会锁定文件,因此不会丢失恰好在同一时刻写入的事件。相同的间隔也会清理 SQLite 中的旧行:探测、TLS 观察、能力快照、指标、快照、事件和发现运行各自有独立的保留窗口;ownsearch db maintenance 会报告清理内容。同一状态数据库上的两个进程会通过锁文件轮流执行,因此清理不会重复运行。如果文件无法删除,本次运行会记录一条警告,指出可通过 ownsearch db maintenance 手动修复;如果清理报告了问题,还会在 maintenance_runs 中写入一条 attention 记录。

AI 数据库更改
  • OWNSEARCH_AI_DB_MODE:read-only 或 read-write。默认 read-write,因为每项更改仍需预览和一次性令牌;设置为 read-only 可拒绝所有通过输入执行的数据库更改。
  • OWNSEARCH_AI_DB_MAX_CHANGES_PER_CALL:每次调用的字段更改数,默认 5。
  • OWNSEARCH_AI_DB_CONFIRM_TTL_SECS:确认有效期,默认 120。
  • OWNSEARCH_AI_DB_MIN_INTERVAL_SECS:应用更改的最小间隔,默认 2。
配置文件示例
version = 1
fleet_min = 6
fleet_max = 12
html_fallback = true
google_required = false
result_cap = 10
search_attempts = 3
round_robin = true
keep_window = "3d"
ai_db_mode = "read-only"

HTTP 模式

OWNSEARCH_BEARER_TOKENS="$(openssl rand -hex 24)" ownsearch serve --http

任何长度至少为 32 个字符的随机值都可用;openssl rand -hex 24 是一种生成方式。

  • 默认绑定地址为 127.0.0.1:8774。
  • 不带 bearer token 的非环回绑定会在启动时被拒绝。
  • token 至少需要 32 个字符,并采用恒定时间比较。
  • Host 会根据环回地址列表或 OWNSEARCH_ALLOWED_HOSTS 进行检查。
  • 除非 Origin 标头与 OWNSEARCH_ALLOWED_ORIGINS 匹配,否则请求会被拒绝。
  • 请求正文上限为 1 MiB,标头必须在 10 秒内到达,并发请求数量也设有上限。
  • GET /healthz 用于存活检查。GET /startupz 会在每次请求时执行快速数据库检查,检查失败时返回 503。GET /readyz 会在每次请求时执行开销较低的存活读取,并在关闭期间失败,因此监控程序无需等待全数据库扫描。GET /metrics 会报告调用计数、各工具计数,以及带有延迟总和与最大值的各路由 HTTP 计数。
  • 中间件按最外层优先的顺序运行:正文截止时间、请求 ID、Origin 检查、Host 检查、bearer 检查、并发限制、正文大小限制、跟踪层、指标、路由。安全标头会包裹整个路由器。跟踪层会记录方法、路径、状态和延迟。
  • 关闭时会先将就绪状态设为不可用,然后在截止时间内排空正在处理的调用。
  • 在 supervisor 下,卡死的进程会被替换。OWNSEARCH_WATCHDOG_SECS 限制进程卡顿后以代码 75 退出前的最长时间;docker-compose.yml 设置了 restart: unless-stopped,并将停止宽限期设为 30 秒。
REST 端点

同一引擎会在 HTTP 端口上提供两个 JSON 端点,并与 MCP 流使用相同的 bearer 检查、Origin 检查、Host 检查和正文大小限制。

  • POST /v1/search 接受 ownsearch_search 的字段,其中 query 为必填项。
  • POST /v1/fetch 接受 ownsearch_fetch 的字段,其中 url 为必填项。
curl -s http://127.0.0.1:8774/v1/search \
  -H 'content-type: application/json' \
  -d '{"query":"rust programming language","limit":5}'

调用成功时返回 200,并包含 MCP 工具返回的结构化内容。调用被拒绝时,若参数无效则返回 400,若 token 缺失或错误则返回 401,若策略拒绝则返回 403,若路由或资源不存在则返回 404,若方法错误则返回 405,若确认已过期则返回 409,若触发速率限制则返回 429,若上游失败则返回 502,若没有可用服务实例或正在关闭则返回 503,若发生超时则返回 504。响应正文采用 RFC 9457 application/problem+json 格式,包含 type、title、status、detail、instance 以及作为扩展成员的稳定字段 code 和 remedy,不包含任何内部细节。每次 REST 调用都会记录在账本中,并像 MCP 调用一样计入 /metrics。

任何远程使用场景都应在前面部署 Caddy。切勿暴露未进行身份验证的扫描器。

将 token 列表存储在操作系统的密钥链中,而非环境变量中:

printf '%s' "$TOKEN" | ownsearch config set-bearer-token

容器

docker build -t ownsearch .
docker run --rm -p 127.0.0.1:8774:8774 \
  -e OWNSEARCH_BEARER_TOKENS="$(openssl rand -hex 24)" \
  -v ownsearch-state:/home/ownsearch/.local/state/ownsearch \
  ownsearch

docker-compose.yml 保存了相同的配置,并包含 restart: unless-stopped、两个状态卷和健康检查。镜像设置了 OWNSEARCH_BIND=0.0.0.0:8774、位于 /home/ownsearch/.local/share/ownsearch/ledger 下的账本目录,以及 OWNSEARCH_BROWSER=false,因此容器不会渲染任何页面。运行时必须设置 OWNSEARCH_BEARER_TOKENS,否则服务会拒绝启动。添加 OWNSEARCH_ALLOWED_HOSTS 并填写客户端使用的名称,否则 Host 检查会拒绝所有 Host 不是 localhost 或绑定地址的请求。状态卷会在重启后保留数据库和快照;如果需要在重启后保留账本和 args.key,也请挂载账本目录。

本地文件与保留窗口

  • 数据库:${XDG_STATE_HOME}/ownsearch/instances.db,或 OWNSEARCH_STATE_DIR/instances.db。
  • 快照:同目录下的 instances.snapshot.json,每次发现运行、扫描、AI 更改以及引导导入后都会重新生成。
  • 发现历史:instances.events.jsonl,会按保留窗口裁剪。
  • 你创建的备份:backups/instances-<stamp>.db,使用 VACUUM INTO 写入,通过快速检查和外键检查验证,并像其他临时文件一样在保留窗口结束后删除。
  • 迁移前备份:pre-migration-<stamp>.db,会在保留窗口结束后删除。
  • 浏览器配置文件:状态目录下的 browser/profile-<pid>,仅所有者可访问,会在会话关闭时删除,并在启动时清理其所属进程已退出的配置文件。
  • 账本:calls.jsonl,在保留期限边界归档为 calls-<stamp>.jsonl,并删除超过保留窗口的归档。
  • 参数密钥:账本旁的 args.key。它用于参数哈希和账本链,因此会保留。

状态目录以模式 0700 创建,文件以模式 0600 创建。WAL 模式会生成 instances.db-wal 和 instances.db-shm。数据库行各自有保留窗口,由 ownsearch db maintenance 执行清理:探测记录保留 90 天,TLS 观测记录保留 90 天,能力快照保留 90 天,小时指标保留 180 天,集群快照保留 30 天,发现运行记录保留 180 天,生命周期事件保留 365 天。扫描器永远不会删除实例行。

数据库

数据库采用 WAL 模式的 SQLite,启用外键,使用 STRICT 表,并设有带校验和的迁移账本。一个迁移文件包含完整架构:表、外键、检查约束、索引和视图,因此开发构建始终可一步创建当前架构。列级架构位于 crates/ownsearch-core/src/db/migrations/0001_initial.sql;本页不再重复说明。

数据表包括:schema_migrations、application_metadata、discovery_sources、discovery_runs、instances、capability_snapshots、engines、categories、capability_engines、capability_categories、probes、tls_observations、hourly_probe_metrics、instance_quality、instance_events、fleet_snapshots、instance_policy_overrides 和 maintenance_runs。两个视图用于高频路径:active_fleet 和 scan_due。

ownsearch db verify 会检查文件完整性和外键,并显示架构版本。存储层在打开数据库时也会检查每个迁移的校验和。备份使用 VACUUM INTO 写入,并在使用前进行验证。

数据库命令

  • ownsearch db path
  • ownsearch db verify
  • ownsearch db backup [--out PATH]
  • ownsearch db export [--out PATH]
  • ownsearch db maintenance(WAL 检查点、压缩、数据过期处理和清理)
  • ownsearch db counts [--json]
  • ownsearch instances list [--status S] [--limit N] [--json]
  • ownsearch instances show [ID] [--url URL] [--json]
  • ownsearch instances add URL [--pin] [--json]
  • ownsearch instances pin ID、unpin ID、deny ID [--reason TEXT]、reset-status ID
  • ownsearch instances retire ID [--reason TEXT]、restore ID
你自己的实例

ownsearch instances add http://localhost:8888/ --pin 会存储你自行运行的 SearXNG 实例,无论它监听的是 localhost 端口、Docker 网络地址,还是任何其他私有地址。该实例初始状态为候选。扫描会像探测其他实例一样探测它,两次探测通过后便会将其提升为活动状态,之后搜索就会使用它。回环地址或私有主机不会进行 TLS 和证书检查,因为这些检查是针对公共主机的。地址规则仍然适用:设置 OWNSEARCH_ALLOW_PRIVATE_INSTANCES=true,并确保实例位于你控制的网络中,因为相同设置也会允许恶意发现文档将扫描器指向本地服务。

实例 CRUD 示例

创建实例:

ownsearch instances add http://127.0.0.1:8080/ --pin

读取实例:

ownsearch instances list --limit 10
ownsearch instances show 1
ownsearch instances show --url http://127.0.0.1:8080/

更新其策略:

ownsearch instances pin 1
ownsearch instances unpin 1
ownsearch instances deny 1 --reason "host is gone"
ownsearch instances reset-status 1

将其从实例集群中删除;这会将其退役,而不是删除该行:

ownsearch instances retire 1 --reason "replaced by another host"

恢复实例:

ownsearch instances restore 1

通过扫描将变更应用到实例集群:

ownsearch scan --instance 1 --force

实例永远不会被删除,因此其探测历史和事件始终可读。retire 是生命周期中的删除步骤,restore 会将已退役或缺失的实例恢复为候选状态。通过 MCP 使用 ownsearch_db_crud 也能执行相同操作,并采用预览和一次性令牌流程。

AI 辅助数据库变更

默认启用写入模式。每项变更仍需先预览,再单独调用应用操作并携带一次性令牌;OWNSEARCH_AI_DB_MODE=read-only 会拒绝所有变更。

  1. 客户端使用 dry_run: true 调用 ownsearch_db_crud。OwnSearch 会验证实体、字段允许列表、值类型和生命周期转换,然后返回变更前后的预览,以及一个带有有效期的一次性令牌。使用令牌时会强制执行应用操作之间的最短间隔。
  2. 客户端再次调用,设置 dry_run: false 并提供令牌。OwnSearch 会在一个事务中精确应用预览过的变更、追加一条生命周期事件、重新生成快照,并返回已提交的记录。
  3. 要添加实例,请使用相同工具,设置 operation: create、entity: instance,并将 url 设置为实例地址。预览和令牌流程相同,实例的存储方式与 ownsearch instances add 完全一致。
  4. 令牌过期、预览内容发生变化、令牌被重放、使用原始 SQL 字段、字段未知或处于只读模式时,都会返回带有解决方法的稳定错误;每次拒绝操作都会写入事件历史。

该工具可以创建或移除策略覆盖项、更新生命周期和策略字段、退役实例,或恢复已退役或缺失的实例。它无法删除实例行、改写探测记录或伪造事件。将 status 设为 active 需要通过硬性门槛检查。

开发

cargo fmt --all -- --check
cargo check --workspace --all-targets --all-features --locked
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
cargo test --workspace --all-features --locked
cargo test --workspace --all-features --locked --doc
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps --locked
cargo llvm-cov --workspace --all-features --locked --fail-under-lines 80
cargo run -p ownsearch -- sbom
tools/verify.sh
tools/smoke.sh http://127.0.0.1:8774

默认情况下,实时测试会被忽略,因为它需要访问公共网络:

cargo test -p ownsearch-core --test live -- --ignored --nocapture

故障排除

  • ownsearch.no_fleet:运行 ownsearch scan,然后检查 ownsearch instances list。
  • 所有搜索都没有结果,且 sources.failed 显示 ownsearch.policy_refused:所选实例拒绝 JSON 和 HTML。请从实例接受的网络运行,或检查 ownsearch instances list 中是否有已隔离的记录。
  • ownsearch.state_corrupted:运行 ownsearch db verify 并恢复最新备份。
  • ownsearch.write_disabled:设置 ai_db_mode = "read-write"。
  • ownsearch.confirmation_expired:再次调用该工具,并设置 dry_run: true。
  • 磁盘空间不足:降低用于账本归档、事件行和迁移前备份的 OWNSEARCH_KEEP_WINDOW,然后运行 ownsearch db maintenance 并查看其输出的警告。SQLite 行遵循“本地文件和保留窗口”部分所列的各表固定窗口。
  • 启动错误会指出设置名称及其取值范围。请修正该值,或移除该设置以使用默认值。
  • 进程以代码 75 退出:在 OWNSEARCH_WATCHDOG_SECS 时间内未取得进展,因此进程已停止。请检查日志中的最后一个请求,并让监管程序重新启动该进程。

隐私

查询会发送到你选择的公共实例以及这些实例背后的引擎。OwnSearch 不存储原始查询文本。账本会记录参数的带密钥哈希、工具名称、状态、上游 HTTP 状态类别、耗时、字节数、解析器和实例 ID。系统不会收集遥测数据。

安全

  • 整个工作区中没有任何 unsafe 代码。
  • 发现记录仅限公共地址,因此恶意文档无法将扫描器指向本地或内部服务。
  • 所有出站连接均使用 rustls,并严格验证证书。
  • 限制响应读取量和连接数,并设置请求截止时间。
  • 搜索结果是数据。每个字符串都会经过净化处理,移除不可见字符和控制字符;URL 必须使用 HTTP 或 HTTPS;过长的值会被截断,并附带可见标记。
  • 不会通过命令行接收、写入配置文件或由任何命令打印任何机密。
  • 浏览器在每个进程独立的配置文件下运行,仅所有者可访问;若浏览器挂起、进入空闲状态或超过最大运行时长,则会将其关闭。只会关闭由 OwnSearch 启动的浏览器。

请私下报告漏洞;SECURITY.md 说明了具体方式。

支持

如有疑问、报告错误或遇到安装问题,请写信至 [email protected]。请附上版本、运行的命令和输出。安全问题请按 SECURITY.md 中的说明处理,不要发送到此地址的常规支持队列。

运行手册位于 docs/operations.md:服务级别、检测、分诊、自愈行为和基线。

贡献

此代码库由一位维护者负责。开始大型工作前,请将补丁或提案发送至 [email protected],并在提交更改前运行 tools/verify.sh。完整门禁通过后,更改即可合并;RELEASING.md 列出了门禁运行的检查项。

分发

每个版本都包含 sha256.sum,涵盖所有归档、安装程序、formula 和 MCPB 包,并使用 minisign 签名。ownsearch sbom 可根据 Cargo.lock 按需生成 CycloneDX 1.7 软件物料清单。

发布渠道:

  • GitHub 发布归档和校验和,使用 minisign 签名。
  • Shell 和 PowerShell 安装程序。
  • 根据发布归档构建的 Homebrew formula。
  • npm 加载器 @devops-infinity/ownsearch。
  • crates.io 包 ownsearch-core 和 ownsearch。
  • MCP Registry 条目 io.github.devops-infinity/ownsearch。
  • 面向桌面客户端的 MCP 包(MCPB)。
  • ghcr.io/devops-infinity/ownsearch 镜像。

v* 标签会启动发布工作流,构建七个目标,然后创建并发布 GitHub 发布版本。标签生成前,门禁会通过 tools/verify.sh 在机器上运行,因此工作流不会重复运行这些检查。该工作流中的每个 action 都固定到某个提交,因此移动标签不会改变实际运行的内容。RELEASING.md 列出了按顺序执行的发布步骤及各步骤所需的凭据。

许可证

可自行选择 MIT 或 Apache-2.0。完整文本见 LICENSE-MIT 和 LICENSE-APACHE。HTML 解析器(scraper)引入了 MPL-2.0 组件(cssparser、selectors、dtoa-short),这些组件作为未经修改的依赖项使用;MPL-2.0 允许在采用其他许可证的更大作品中这样使用。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。