OwnSearch について
OwnSearchは、品質評価した公開SearXNGインスタンス群を使うセルフホスト可能なMCP・HTTP検索サービスです。検索処理を管理するユーザー向けに、ローカルSQLiteでの状態管理、インスタンス切り替え、障害時の切り替え、結果統合を行います。
主な機能
- 01公開SearXNGインスタンスの検出と調査
- 02ローカルのインスタンス群を評価・管理
- 03インスタンスのローテーションと障害時切り替え
- 04出典情報を保った検索結果の統合
- 05ページ取得と本文抽出
活用シーン
- 01複数のSearXNGインスタンスを使ったウェブ検索
- 02インスタンス障害時の検索継続
- 03ページをMarkdownまたはテキストで取得
- 04インスタンスの健全性と機能の確認
MCP 対応
MCPサーバーとしてstdioまたはStreamable HTTPでクライアントに接続し、検索、ページ取得、インスタンス管理、状態照会のツールを公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
OwnSearch
スコアリングした複数の公開 SearXNG インスタンスを利用する、セルフホスト可能な MCP および HTTP 検索サービスです。
mcp-name: io.github.devops-infinity/ownsearch
ステータス:プレリリース、ワークスペースのバージョンは 0.2.0 です。
OwnSearch は searx.space から公開 SearXNG インスタンスを検出し、低頻度でプローブしてスコアリングし、ローカルの SQLite データベースにインスタンス群を保持します。検索の開始インスタンスをローテーションし、障害が発生したインスタンスを再試行して、次に正常なインスタンスから結果を返します。各検索結果には、その結果を提供したソースが含まれます。ソースのインスタンスと、判明している場合はエンジンも示されます。標準入出力または Streamable HTTP 経由の Model Context Protocol(MCP)サーバーとして動作し、HTTP ポートでは 2 つの REST 呼び出しにも応答します。
オーナー:Md. Sazzad Hossain Sharkar。
参考資料:インスタンスのポリシーについては docs/scanner-policy.md、運用手順書については docs/operations.md、リリース手順については RELEASING.md、報告ポリシーについては SECURITY.md を参照してください。
目次
- 機能
- デフォルトで有効な機能
- 対応していない機能
- 要件
- ビルドとインストール
- クイックスタート
- MCP クライアントを接続する
- ツール
- 検索の動作
- スキャナーポリシー
- 品質モデル
- 設定
- HTTP モード
- コンテナー
- ローカルファイルと保持期間
- データベース
- データベースコマンド
- AI を利用したデータベースの変更
- 開発
- トラブルシューティング
- プライバシー
- セキュリティ
- サポート
- コントリビューション
- 配布
- ライセンス
機能
https://searx.space/data/instances.jsonから公開 HTTPS SearXNG インスタンスを検出します。初回実行時には、ネットワークに接続する前に、埋め込みスナップショットに含まれる 67 件のインスタンスをインポートします。- 各スキャンで候補をそれぞれ 1 回プローブします。ホストを解決して TLS チェーンと証明書の日付を検証し、
/configを読み取り、JSON 検索を 1 回実行します。JSON が拒否された場合に限り HTML 検索を行い、そのインスタンスが該当エンジンを公開していて、JSON 検索が成功した場合に限り、Google の完全一致検索を行います。 - スコアリングの前にハードゲートを適用します。そのため、証明書の有効期限が近い場合、アナリティクストラッカーがある場合、または
/configを読み取れない場合、そのインスタンスは稼働中のインスタンス群に入りません。 - サイズ上限、ネットワークごとの上限、ヒステリシスを設けて稼働中のインスタンス群を選択するため、スキャンで一度問題が発生しても、正常に動作しているインスタンスが除外されません。
- 検索のたびに開始インスタンスをローテーションします。ネットワークエラーまたは
5xxが発生した場合は、インスタンスごとに最大 3 回試行し、障害が続くインスタンスをクールダウンさせます。検索が成功するか期限に達するまで、次のインスタンスに切り替えます。 - 複数のインスタンスからの結果を統合し、各ソースの観測情報をすべて保持して、部分的な網羅を明示します。
429は再試行せず、プルーフ・オブ・ワークも実行せず、人間のブラウザーを装うこともありません。運用者がOWNSEARCH_CAPSOLVER_KEYを設定している場合に限り、レンダリング後のページにのみ表示されるチャレンジを、CapSolver サービスでそのページに限って解決できます。
デフォルトで有効な機能
これらの機能はデフォルトで有効です。それぞれ、Configurationで指定した設定によって制御されます。
- HTML 検索フォールバック:オン。インスタンスが JSON に対して
403、その他の4xxまたは5xx、あるいは JSON 以外の本文を返した場合、OwnSearch は通常の HTML 結果ページを読み取ります。401、429、チャレンジページの場合は HTML で再試行せず、隔離とクールダウンのルールに従います。 - ラウンドロビン選択:オン。検索ごとに、異なる正常なインスタンスから開始します。
- フェイルオーバー:オン。失敗したインスタンスは、設定された回数だけ再試行された後、クールダウンに入り、検索は次のインスタンスに移ります。
- 選択したインスタンスで有効なすべての検索エンジン:オン。OwnSearch はデフォルトではエンジンのフィルターを送信しないため、Google、Bing、DuckDuckGo、Brave、その他そのインスタンスが稼働させているすべてのエンジンを利用できます。対象を絞るには、呼び出し時に
enginesを設定してください。 - SearXNG のすべてのカテゴリ:オン。OwnSearch はデフォルトではカテゴリのフィルターを送信しません。
- Google 完全一致プローブ:オン。インスタンスが
googleエンジンを広告している場合に有効です。 - ページ抽出:オン。
ownsearch_fetchは公開ページを取得し、タイトルとサイズ上限を付けて、Markdown、プレーンテキスト、またはクリーニング済み HTML として返します。 - JavaScript レンダリング:オン。ページが空のシェルの場合、または呼び出しで
render: "always"が設定されている場合、ヘッドレス Chrome がページをレンダリングします。使用中はブラウザーが開いたままになり、アイドル時、ヘルスチェックへの応答が2回連続で得られなかったとき、または最大稼働時間に達したときに閉じます。 - 同一ホストのクロール:オン。
ownsearch_fetchは、指定したページから最大max_pages - 1件(上限7件)のリンクをたどり、それぞれをpagesの下に返します。same_host_onlyのデフォルトは true なので、許可しない限り別のサイトに移動することはありません。 - 結果の帰属情報、フィールドプリセット、レスポンスキャッシュ、セッション統計、型付きデータベース変更(プレビューと1回限りのトークン付き)は、追加フラグなしで利用できます。
対応していないこと
- 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 ベアラートークンで、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 リダイレクトは最大 3 ホップまでたどり、各ホップで最初のリクエストと同じ公開アドレスチェックを行います。また、応答には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のインスタンス名は、entity: "capabilities"を指定したownsearch_db_queryから取得されます。ownsearch_instance_health:ハードゲートの結果、証明書の残存日数、TLS プロトコルとグレード、検索時間の中央値、クールダウン、連続失敗回数、直近のライフサイクルイベントを返します。ownsearch_scan:検出情報を更新し、インスタンスをプローブして再スコアリングし、フリートを再選択します。デフォルトはdry_run: trueです。1 つのプロセス内では、書き込みを行うスキャンは状態データベースごとに一度に 1 つだけ実行され、実行間にはOWNSEARCH_SCAN_MIN_INTERVAL_SECSの間隔を空けます。また、呼び出しでforceが設定されていない限り、まだ実行時期に達していない名前付きインスタンスの処理を拒否します。ownsearch_session:ローカルの呼び出し回数、キャッシュ状態、台帳の長さと先頭、フリートのサイズを返します。ネットワーク呼び出しは行いません。ownsearch_db_query:インスタンス、品質、ポリシーのオーバーライド、機能スナップショット、イベント、スナップショット、検出実行に対する、上限付きの読み取り専用クエリです。各エンティティには個別のフィルターが適用され、選択したエンティティが適用できないフィルターは無視せず拒否されます。イベントは SQL でページ分割されるため、任意のオフセットを指定できます。SQL は受け付けません。ownsearch_db_crud:型指定されたライフサイクルまたはポリシーの変更を 1 つ実行します。書き込みモード、理由、ドライランプレビューで発行される使い捨ての確認トークンが必要です。インスタンス行は削除できません。
すべてのツールは structuredContent と 1 行のテキスト概要を返します。すべての入力スキーマで additionalProperties: false が設定されています。プリセットによって出力から省略される可能性があるフィールドは、公開される出力スキーマですべて任意項目になっています。
検索の動作
モードによって、1 つのクエリに回答するインスタンスの数が決まります。
fastは 1 つのインスタンスを対象にします。- デフォルトの
balancedは 3 つを対象にします。 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 がないページだけです。
ラウンドロビンでは、健全なインスタンスの上位ウィンドウ内で開始位置を切り替えるため、連続する 2 回の検索が常に同じインスタンスから始まることはありません。スコア順を厳密に優先する場合は、OWNSEARCH_ROUND_ROBIN=false にして無効にしてください。
フリートのスコアを算出するスキャンがまだ実行されていない場合、またはスコア算出済みのすべてのインスタンスがクールダウン中の場合、検索は ownsearch.no_fleet で失敗するのではなく、ハードゲートに失敗していない検出済みインスタンスのうち、最もランクの高いものにフォールバックし、その旨を warnings で示します。レスポンスに実在しない結果が追加されることはありません。すべての試行が拒否またはレート制限された場合、sources.failed に各インスタンス、そのコード、およびその応答内容が記録されます。sources.fallbacks には、JSON の代わりに HTML パーサーから回答を得た各インスタンスが記録されます。
フィールドプリセットによってペイロードのサイズが決まります。minimal にはタイトル、URL、ランク、スコア、ソース ID が含まれます。standard では、スニペット、エンジン、公開日、およびソースの全リストが追加されます。full にはすべてが含まれます。
スキャナーポリシー
- 組み込みのスケジューラーは、起動時と各検出ウィンドウ(
OWNSEARCH_DISCOVERY_REFRESH_SECS)で検出情報を更新します。ドキュメントのレコード数は500件までです。その後、ジッター遅延を挟んで、スキャン間隔ごとに期限が来たインスタンスを一度に1件ずつプローブします。 - ピン留めされたインスタンスは、スコアが下がっても選択対象に残ります。ピン留めはスコア順、ヒステリシス、ネットワークごとの上限、Google の要件を上書きし、候補レコードや欠落レコードをフリートに追加できるようにします。ただし、ハードゲートに失敗したインスタンスは引き続き除外されます。
- ホストがループバック、プライベート、リンクローカル、ドキュメント用、または予約済みのアドレスに解決される検出レコードはスキップされます。また、拒否、無効化、廃止、またはクールダウン中のインスタンスを明示的にスキャンしようとしても拒否されます。
- 実行ごとに、インスタンスあたり種類ごとにプローブを1回実行します。
- デフォルトでは、ジッターを挟んで同時に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を解析できること。OWNSEARCH_GOOGLE_REQUIRED=trueの場合に限り、正確な Google が存在すること。
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 です。次の3つのキーはこのパターンに従いません:OWNSEARCH_BROWSER_PATH は browser_executable に対応し、OWNSEARCH_BEARER_TOKENS と OWNSEARCH_PROFILE にはプロファイルキーがありません。プロファイルにのみ存在するキーは2つです: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:stdio の代わりに Streamable HTTP を使用してサービスを提供します。デフォルトは false です。OWNSEARCH_BIND:HTTP のバインドアドレスです。デフォルトは127.0.0.1:8774です。OWNSEARCH_BEARER_TOKENS:カンマ区切りのベアラートークンです。各トークンは 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 です。1 回のプローブは、この値の 5 倍が経過すると停止します。OWNSEARCH_SCAN_DEADLINE_SECS:スキャン全体の期限です。デフォルトは 600 で、30~7200 の範囲です。期限を過ぎると、警告を出してスキャンを停止します。OWNSEARCH_SCAN_MIN_INTERVAL_SECS:同じ状態データベースに対する書き込みスキャン間の最小間隔です。デフォルトは 30 で、0~3600 の範囲です。0 にすると間隔が無効になります。プロセス内では常に一度に 1 つのスキャンのみ実行されます。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 の範囲です。2 回連続で応答がない場合、ブラウザーを終了します。OWNSEARCH_BROWSER_MAX_LIFETIME_SECS:置き換えられるまでの 1 回のブラウザーセッションの最大時間です。デフォルトは 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 で報告されます。同じ状態データベースを使用する2つのプロセスは、ロックファイルを介して交互に処理するため、スイープが二重に実行されることはありません。ファイルを削除できない場合、実行ログには手動での修復コマンドとして 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:1回の呼び出しで変更できるフィールド数です。デフォルトは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です。 - ベアラートークンを設定せずにループバック以外にバインドすると、起動時に拒否されます。
- トークンは 32 文字以上である必要があり、比較は定時間で行われます。
Hostはループバックの許可リスト、またはOWNSEARCH_ALLOWED_HOSTSに照らして確認されます。Originヘッダーは、OWNSEARCH_ALLOWED_ORIGINSと一致しない限り拒否されます。- リクエストボディの上限は 1 MiB、ヘッダーの受信期限は 10 秒で、同時リクエスト数にも上限があります。
GET /healthzは稼働状態を確認します。GET /startupzはリクエストごとに簡易的なデータベースチェックを実行し、チェックに失敗している間は 503 を返します。GET /readyzはリクエストごとに低コストな稼働確認用の読み取りを実行し、シャットダウン中は失敗するため、監視処理がデータベース全体のスキャンを待つことはありません。GET /metricsは呼び出しカウンター、ツールごとの回数、レイテンシーの合計と最大値を含むルートごとの HTTP 件数を報告します。- ミドルウェアは外側から順に実行されます。ボディの期限、リクエスト ID、オリジンチェック、ホストチェック、ベアラーチェック、同時実行ゲート、ボディサイズ制限、トレースレイヤー、メトリクス、ルートの順です。セキュリティヘッダーはルーター全体をラップします。トレースレイヤーはメソッド、パス、ステータス、レイテンシーをログに記録します。
- シャットダウン時は、まずレディネスを無効にし、その後、期限内に進行中の呼び出しを完了させます。
- スーパーバイザーの配下では、応答しなくなったプロセスは置き換えられます。
OWNSEARCH_WATCHDOG_SECSは、終了コード 75 で終了するまで停止できる時間を制限します。また、docker-compose.ymlではrestart: unless-stoppedと 30 秒の停止猶予期間を設定しています。
REST エンドポイント
同じエンジンが、HTTP ポート上で 2 つの JSON エンドポイントに応答します。MCP ストリームと同じベアラーチェック、オリジンチェック、ホストチェック、ボディサイズ制限が適用されます。
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}'
成功した呼び出しは、MCP ツールが返す構造化コンテンツとともに 200 を返します。拒否された呼び出しは、不正な引数の場合は 400、トークンがないか正しくない場合は 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 を前段に配置してください。匿名スキャナーには決して公開しないでください。
環境変数の代わりに、トークンリストを OS のキーリングに保存します。
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、2 つの状態ボリューム、ヘルスチェックを含む同じ設定が記述されています。イメージでは OWNSEARCH_BIND=0.0.0.0:8774、/home/ownsearch/.local/share/ownsearch/ledger 配下の台帳ディレクトリ、OWNSEARCH_BROWSER=false が設定されているため、コンテナーはページをレンダリングしません。実行時には OWNSEARCH_BEARER_TOKENS が必須で、設定されていないとサーバーは起動を拒否します。クライアントが使用する名前を OWNSEARCH_ALLOWED_HOSTS に追加してください。追加しない場合、localhost またはバインドアドレスを指定しないリクエストはすべて Host チェックで拒否されます。状態ボリュームは再起動後もデータベースとスナップショットを保持します。台帳と 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 日です。インスタンスの行がスキャナーによって削除されることはありません。
データベース
データベースは SQLite の WAL モードで、外部キーが有効になっており、STRICT テーブルとチェックサム付きマイグレーション台帳を使用します。1 つのマイグレーションファイルに、テーブル、外部キー、チェック、インデックス、ビューを含むスキーマ全体が格納されるため、開発ビルドでは常に 1 ステップで現在のスキーマが作成されます。列レベルのスキーマは 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 の 2 つのビューを使用します。
ownsearch db verify はファイルの整合性と外部キーをチェックし、スキーマのバージョンを表示します。ストアは起動時に各マイグレーションのチェックサムも検証します。バックアップは VACUUM INTO で書き込まれ、使用前に検証されます。
データベースコマンド
ownsearch db pathownsearch db verifyownsearch 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 IDownsearch instances retire ID [--reason TEXT]、restore ID
自分のインスタンス
ownsearch instances add http://localhost:8888/ --pin を実行すると、自分で運用する SearXNG インスタンスを登録できます。localhost のポート、Docker ネットワークアドレス、その他のプライベートアドレスのいずれで待ち受けていても登録できます。インスタンスは候補として登録されます。スキャンでは他のインスタンスと同様にプローブが行われ、2 回連続でプローブに合格するとアクティブに昇格し、それ以降は検索に使用されます。ループバックまたはプライベートのホストでは、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 に設定すると、すべての変更が拒否されます。
- クライアントは
dry_run: trueを指定してownsearch_db_crudを呼び出します。OwnSearch はエンティティ、フィールドの許可リスト、値の型、ライフサイクルの遷移を検証し、変更前後のプレビューと有効期間付きの一度限りのトークンを返します。適用間の最小間隔は、トークンの使用時に適用されます。 - クライアントはトークンを指定し、
dry_run: falseでもう一度呼び出します。OwnSearch はプレビューされた変更のみを単一のトランザクションで適用し、ライフサイクルイベントを追加し、スナップショットを再生成して、コミット済みのレコードを返します。 - インスタンスを追加するには、同じツールを
operation: create、entity: instance、およびインスタンスのアドレスを設定したurlを指定して呼び出します。プレビューとトークンのフローは同じで、インスタンスはownsearch instances addとまったく同じように保存されます。 - トークンの期限切れ、プレビューの変更、トークンの再使用、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 にあります。サービスレベル、検出、トリアージ、自己修復の動作、ベースラインを記載しています。
貢献
リポジトリのメンテナーは1名です。大規模な作業に着手する前に [email protected] へパッチまたは提案を送り、変更を送る前に tools/verify.sh を実行してください。すべてのゲートに合格した変更が取り込まれます。ゲートで実行される内容は RELEASING.md に記載されています。
配布
各リリースには sha256.sum が含まれ、すべてのアーカイブ、インストーラー、フォーミュラ、MCPB バンドルを対象としています。また、minisign で署名されています。ownsearch sbom は、必要に応じて Cargo.lock から CycloneDX 1.7 の部品表を生成します。
リリースチャネルは次のとおりです。
- minisign で署名された GitHub リリースアーカイブとチェックサム。
- シェルおよび PowerShell インストーラー。
- リリースアーカイブからビルドされた Homebrew フォーミュラ。
- npm ローダー
@devops-infinity/ownsearch。 - crates.io パッケージ
ownsearch-coreとownsearch。 - MCP Registry のエントリー
io.github.devops-infinity/ownsearch。 - デスクトップクライアント向けの MCP バンドル(MCPB)。
ghcr.io/devops-infinity/ownsearchイメージ。
v* タグを作成するとリリースワークフローが開始され、7つのターゲットをビルドした後、GitHub リリースを作成して公開します。タグ作成前に、マシン上で tools/verify.sh を通じてゲートを実行するため、ワークフローではその処理を繰り返しません。このワークフローの各アクションはコミットに固定されているため、タグが移動しても実行内容は変わりません。公開手順の順序と各手順で必要な認証情報は RELEASING.md に記載されています。
ライセンス
MIT OR Apache-2.0。お好きな方を選べます。ライセンス全文は LICENSE-MIT と LICENSE-APACHE にあります。HTML パーサー(scraper)には MPL-2.0 のコンポーネント(cssparser、selectors、dtoa-short)が含まれます。これらは変更されていない依存関係として使用しており、MPL-2.0 では、別のライセンスのもとにあるより大きな著作物内での使用が認められています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。