Search Memory について
Search Memoryは、ウェブ検索、ページ抽出、ローカルメモリ、引用可能なナレッジベースを組み合わせたアシスタント向けMCPサーバーです。キャッシュ、インデックス、メモリ、モデルはローカルで動作し、基本検索にAPIキーは不要です。
主な機能
- 01複数のウェブ検索プロバイダーをフォールバック検索
- 02ページを整形済みMarkdownとして抽出
- 03引用付きキーワード・セマンティック検索用にソースを索引化
- 04セッションメモの保存と呼び出し
- 05検索・引用・ページ索引をまとめて行うリサーチ
活用シーン
- 01ウェブ検索の発見を後で使えるよう保存
- 02ページや文書から検索可能なコーパスを作成
- 03ウェブと索引済みソースで質問を調査
- 04アシスタントのセッションをまたいでメモを呼び出し
MCP 対応
MCPクライアントに検索、取得、リサーチ、索引作成、ナレッジベース、セッションメモリのツールを公開します。ウェブ検索、ローカルソースの検索、メモの保存に対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y search-memory-mcpSEARCH_PROVIDERSComma-separated search provider order, for example duckduckgo,marginalia,bingCACHE_DB_PATHPath of the local SQLite database for cache, memory, and indexINGEST_ALLOWED_DIRSComma-separated directories whose files ingest_document may read; local file reading is off when unsetSEARXNG_BASE_URLBase URL of a SearXNG instance with JSON output, used by the searxng providerBRAVE_SEARCH_API_KEYシークレットOptional Brave Search API key; the brave provider then uses the official API instead of scrapingTAVILY_API_KEYシークレットOptional Tavily API key; adds the tavily provider with news-topic search and publish datesEXA_API_KEYシークレットOptional Exa API key; adds the exa provider with neural (semantic) web searchREADER_FALLBACK_URLOptional reader service (for example https://markdown.new/) used when a page cannot be fetched directly; sends the page URL to that serviceローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Search Memory MCP
AI アシスタントのための無料ウェブ検索と長期記憶。API キーは不要です。データはお使いのマシンに保存されます。
Claude Desktop、Claude Code、Cursor、Windsurf、その他あらゆる MCP クライアントで動作します。
Search Memory MCP を選ぶ理由
- 🔎 無料でウェブ検索できます。 DuckDuckGo、Bing、Brave、Google に対応し、自動で切り替えます。API キーもサブスクリプションも不要です。
- 📄 あらゆるページを読みやすい Markdown として読み取れます。 GitHub、RSS、静的ページには高速な処理方法を用意しています。PDF、DOCX、EPUB のリンクはテキストに変換されます。ページの閲覧に必要な場合にのみ、実際のブラウザーを使用します。
- 🧠 セッションをまたいで記憶できます。 アシスタントはメモを保存し、後から呼び出せます。
- 📚 プライベートなナレッジベースを構築できます。 ページやドキュメントをインデックス化し、キーワード検索とセマンティック検索で検索して、引用付きの回答を取得できます。
- 🔁 記憶を活用したリサーチ。 1 回の
research呼び出しで、インデックス済みの情報を確認し、ウェブを検索し、上位のページを読み、引用付きで回答し、次回のためにページを保存します。すべての情報源に、公開時期(ページまたは PDF のメタデータから取得)と取得またはインデックス作成の時期が表示されるため、回答がどれほど新しいかを確認できます。 - 🔒 ローカル優先。 キャッシュ、メモリー、インデックス、モデルはすべてお使いのマシン上で動作します。
- 🛡️ 信頼できないページにも、より安全に対応。 取得したページから隠しテキストや不可視文字を削除し、ウェブコンテンツをデータとしてマークすることで、その中の指示に従わないようアシスタントに伝えます。詳しくは SECURITY.md をご覧ください。
クイックスタート
MCP クライアントの設定(例:claude_desktop_config.json または .cursor/mcp.json)に以下を追加します。
{
"mcpServers": {
"search-memory": {
"command": "npx",
"args": ["-y", "search-memory-mcp@latest"]
}
}
}
クライアントを再起動し、「最新の Node.js リリースをウェブで検索して、バージョン番号を覚えておいて」と尋ねます。
検索とほとんどのページは、すぐに利用できます。実際のブラウザーが必要なページでは、Playwright Chromium を使用します(約 180 MB)。インストール中、またはパッケージマネージャーによってインストールスクリプトがスキップされた場合は初回使用時にダウンロードされるため、最初のリクエストには数分かかることがあります。あらかじめダウンロードするには、
npx playwright install chromiumを実行してください。モデルを使用する機能では、初回使用時に小さなローカルモデルがダウンロードされます。
Node.js 20.9~25 が必要です(Node 24 を推奨)。Node のバージョンがこれより新しい場合や、npm によってインストールスクリプトがスキップされた場合、サーバーの起動時に正確な対処方法が表示されます。マシンに Docker 以外何もインストールせずに、Docker で実行することもできます。
Docker で実行する(ローカル環境のセットアップ不要)
Docker には Node 24、SQLite モジュール、Chromium が同梱されているため、お使いの Node のバージョンに関係なく動作します。公開イメージを MCP クライアントに指定します(linux/amd64 および linux/arm64 に対応)。
{
"mcpServers": {
"search-memory": {
"command": "docker",
"args": ["run", "-i", "--rm", "-v", "search-memory-data:/app/data", "-v", "search-memory-models:/root/.cache/huggingface", "ghcr.io/kefyusuf/search-memory-mcp:latest"]
}
}
}
初回起動時に Docker がイメージをダウンロードします。更新するには docker pull ghcr.io/kefyusuf/search-memory-mcp:latest を実行するか、1 つのリリースを使い続けるには :1.0 などのバージョンタグを指定してください。代わりに自分でイメージをビルドするには、クローンしたリポジトリ内で docker build -t search-memory-mcp . を実行し、イメージ名として search-memory-mcp を指定します。
名前付きボリュームにより、キャッシュ、メモリー、ナレッジベース、ダウンロード済みモデルが実行間で保持されます。ingest_document でローカルファイルを読み取るには、フォルダーをマウントして許可します。たとえば、"-v", "/home/me/notes:/notes:ro", "-e", "INGEST_ALLOWED_DIRS=/notes" と指定します。
特長
検索と取得
- 永続的な Playwright ブラウザーインスタンスを使用したブラウザーコンテキストのプーリング。
- 設定可能なプロバイダーと、ヘルス状態の追跡および優先順位に基づくフォールバックによるウェブ検索。対応するスクレイパー:DuckDuckGo、Bing、Brave、Google、Yahoo、Marginalia。
SEARXNG_BASE_URLによる SearXNG メタ検索プロバイダー(セルフホストまたは信頼できるパブリックインスタンス)、BRAVE_SEARCH_API_KEYによる Brave Search API、TAVILY_API_KEYによる Tavily(公開日付きのニューストピック検索)、EXA_API_KEYによる Exa(ニューラル/セマンティック検索)を任意で利用できます。 - 検索レスポンスには、試行したプロバイダーと、失敗、結果なし、またはスキップとなった理由が報告されます(構造化出力では
providerAttempts、テキスト出力では短い「プロバイダーメモ」行)。 - 検索結果のキャッシュ期間はクエリの種類に応じます:ニュースは 15 分、ショッピング、ローカル、一般検索は 1 時間、技術、調査、ナビゲーション検索は 24 時間です。
fetch_contentとindex_urlは、コンテンツタイプ、または一般的なバイナリレスポンスの場合は拡張子から判定して、PDF、DOCX、EPUB のレスポンスからテキストを抽出します。ドキュメントあたり最大 25 MB まで対応し、ブラウザーは開きません。- URL の正規化、プロバイダー間の重複排除、逆順位融合(RRF)によるプロバイダー横断検索。
- オプトイン方式のインテント対応検索ルーティング(
strategy=auto)。ヒューリスティック、ローカル分類器へのフォールバック、バージョン管理されたプロバイダープロファイルを使用します。 - ドメインフィルター(
domain)および日付範囲フィルター(from_date/to_date)。 - ローカルインデックス検索のクエリ書き換え、およびオプトイン方式のウェブ複数クエリ展開(
expand_query=true):略語の展開、質問の正規化、ニュース検索の年の補正。 - クロスエンコーダーによる再ランキング(
ENABLE_RERANKER)を任意で利用できます。 - 段落/文単位の用語スコアリング、ストップワードのフィルタリング、ソースごとの引用を用いたディープサーチの回答。
- 機械可読な検索結果と回答のための構造化 JSON 出力(
format: "json")。web_search、search_index、server_statusも MCPoutputSchemaを宣言し、成功したすべての呼び出しでstructuredContentを返します。
ローカルナレッジベース(RAG)
- ドキュメントのチャンク分割(段落優先、オーバーラップあり)。
- ハイブリッド検索:FTS5 キーワード検索と
sqlite-vecセマンティック検索を RRF で統合します。埋め込みを利用できない場合は、FTS のみにフォールバックします。 - 引用可能なローカルコーパスを構築するための
ingest_document、index_url、search_index、list_indexツール。 - インデックス化されたドキュメントを対象とするエンティティグラフと
find_related(関連ドキュメントおよび共起するエンティティ)。
メモリと可観測性
- トピック、タグ、セッションスコープに対応したセッションメモリ(
remember/recall/forget)。 - 検索ごとの実行トレース(ステージ、処理時間、キャッシュ)。最近の検索は
server_statusに表示されます。TRACE_SEARCHES=trueを設定すると、詳細なトレースをログに記録します。 npm run eval:retrievalによる検索評価ハーネス(recall@k、precision@k、MRR)。
安全性とインフラストラクチャ
- HTTP 優先のページ取得。GitHub Raw と RSS の高速処理に加え、Playwright にフォールバックします。
- localhost とプライベートネットワークの宛先をブロックする、
fetch_contentとindex_urlの SSRF 保護。 - 検索ツールと取得ツールのトークンバケット方式レート制限。
- SQLite と
sqlite-vecを使用したセマンティックキャッシュ。実行戦略/プランごとに名前空間を分離します。
要件
- Node.js 20.9.0 以降。
- Node.js 24 は開発時の基準バージョン(
.nvmrc)であり、CI でも同じバージョンを使用します。Node のバージョンを切り替えた後は、better-sqlite3などのネイティブモジュールが使用中のランタイムに適合するよう、依存関係を再インストールしてください。 - npm。
- npm パッケージ、Playwright Chromium、初回実行時のモデルのダウンロードに必要な、インストール中のネットワークアクセス。
インストール
npm install
npm run build
postinstall スクリプトは Playwright Chromium をダウンロードします。モデルを利用する機能を初めて使用するとき、Transformers.js は必要なモデルファイルをローカルの Hugging Face キャッシュにダウンロードします。モデルを読み込む最初のリクエストには時間がかかる場合がありますが、以降のリクエストではローカルキャッシュが再利用されます。初回の実行をできるだけ軽くするには、ENABLE_CROSSLINGUAL=false と ENABLE_RERANKER=false を維持してください。明確な strategy=auto の意図は、意図分類器を読み込まずにヒューリスティックで解決されます。曖昧な自動クエリでは、初回実行時に分類器のダウンロードが発生する場合があります。
MCP クライアントの設定
ビルド済みサーバーを MCP クライアントの設定に追加します。
パッケージ名、コマンド、MCP サーバーの識別名は search-memory-mcp です。以下の設定には、実際のチェックアウトパスを使用してください。絶対パスの build/index.js を指定して node を起動する既存のクライアントでは、チェックアウトディレクトリ名が以前のままでも、そのパスを引き続き使用できます。再ビルド後は、MCP 接続を再起動して更新されたサーバーの識別名を読み込んでください。保存済みデータを保持するには、既存の CACHE_DB_PATH の値を維持してください。
{
"mcpServers": {
"websearch": {
"command": "node",
"args": ["path/to/search-memory-mcp/build/index.js"],
"env": {
"RATE_LIMIT_SEARCH_PER_MIN": "10",
"RATE_LIMIT_FETCH_PER_MIN": "20",
"ENABLE_CROSSLINGUAL": "false"
}
}
}
}
パッケージをグローバルにインストールする場合、またはパッケージランナー経由で使用する場合は、バイナリーのエントリーポイントを使用してください。
{
"mcpServers": {
"websearch": {
"command": "search-memory-mcp",
"args": [],
"env": {
"ENABLE_CROSSLINGUAL": "false"
}
}
}
}
Brave Search API を使用するには、同じ env オブジェクトに "BRAVE_SEARCH_API_KEY": "<your key>" を追加します。デフォルトの順序(キーがある場合は brave,duckduckgo,marginalia,bing)を適用するには、SEARCH_PROVIDERS を未設定のままにしてください。SEARCH_PROVIDERS を明示的に指定すると、デフォルトの順序は置き換えられます。Windows では、Claude Desktop は %APPDATA%\Claude\claude_desktop_config.json を読み込みます。編集後はアプリを完全に再起動してください。
パッケージランナーを使用するクライアントでは、クイックスタート の npx 設定を使用してください。
ツール
| ツール | 説明 |
|---|---|
web_search | ウェブを検索し、ランキング順の結果を返します。strategy(fallback/aggregate/auto)、domain、from_date/to_date、format(text/json)、およびソースに基づく回答を得るための deep=true に対応しています。 |
fetch_content | URL を取得し、コンテンツのキャッシュ、文字セットの処理、GitHub Raw の高速パス、RSS フィードの抽出、Playwright へのフォールバックを利用して、整形済みの Markdown を返します。 |
research | 1 回の呼び出しで質問を調査します。ローカルのナレッジベースを確認し、ウェブを検索して、上位ページ(デフォルトは 3 件の max_sources)を読み取り、両方からの引用を含む回答を返します。また、読み取ったページをナレッジベースに追加します(スキップするには index=false を指定します。すでにインデックスに登録されているソースは再追加されません)。 |
server_status | プロバイダーの利用可否、キャッシュの統計情報、ナレッジインデックスの統計情報、メモリーの統計情報、エンティティグラフの統計情報、最近の検索トレース、ブラウザーの状態、ルーティングプロファイルのメタデータ、機能フラグ、稼働時間を返します。 |
ingest_document | ドキュメントをチャンクに分割し、ローカルのナレッジベース(FTS + ベクトル)とエンティティグラフにインデックス登録します。content、または INGEST_ALLOWED_DIRS 内にあるローカルの PDF、DOCX、EPUB、HTML、テキストファイルへの path を渡します。 |
index_url | URL を取得し、その Markdown をローカルのナレッジベースとエンティティグラフにインデックス登録します。 |
search_index | ローカルのナレッジベースを対象に、キーワード検索とセマンティック検索を組み合わせて実行し、ソースの引用付きチャンクを返します。format: "json" に対応しています。 |
list_index | ローカルのナレッジベースに保存されたドキュメントを一覧表示します。 |
remember | 短い事実やメモをセッションメモリーに保存します。 |
recall | セッションメモリーのメモを検索または一覧表示します。 |
forget | ID を指定してセッションメモリーのメモを削除します。 |
find_related | エンティティ名を指定し、関連ドキュメントや共起するエンティティをエンティティグラフから調べます。 |
検索戦略
| 戦略 | 動作 | セマンティッククエリキャッシュ |
|---|---|---|
fallback (デフォルト) | 設定済みプロバイダーを順番に試し、利用可能な結果セットが最初に得られた時点で停止します。 | 有効(名前空間:fallback) |
aggregate | 現在利用可能な設定済みプロバイダーすべてに並列でクエリを送信し、URL を重複排除して、RRF でランキングを統合します。 | 有効(名前空間:aggregate) |
auto | 意図を検出し、プロファイル v2 に基づいてルーティング計画を作成したうえで、既存の fallback/aggregate 実行処理に委譲します。 | 有効(名前空間:auto:{profile}:{intent}:{providers}) |
セマンティッククエリキャッシュのキーは実行戦略(および auto の場合は計画のフィンガープリント)ごとに名前空間が分けられるため、キャッシュされた fallback の結果が aggregate や別の auto 計画で再利用されることはありません。ディープ検索のページコンテンツには、通常のコンテンツキャッシュが引き続き使用されます。
ドメインと日付の範囲は、セマンティッククエリの類似性とは分離された、厳密なキャッシュ制約です。プロバイダー候補はキャッシュされ、キャッシュヒットのたびに、ディープページ取得の前も含め、要求されたドメイン/日付フィルターが再適用されます。条件に合う候補がないキャッシュエントリーでは、プロバイダーが実行されます。名前空間のフィルタリングはベクトルストアの結果上限が適用される前に行われるため、無関係な戦略の結果が条件に合うエントリーを押し出すことはありません。
SEARCH_PROVIDERS は、設定済みプロバイダーの集合であると同時に許可リストでもあります。自動ルーティングで、SEARCH_PROVIDERS に含まれていないプロバイダーが有効になることはありません。ルーティングプロファイルで変更されるのは、順序と、設定済みプロバイダーのうちプライマリ候補として選択する数だけです。
aggregate を使う自動プロファイルでは、選択されたすべてのプライマリプロバイダーから利用可能な結果が返されなかった場合に限り、設定済みのセカンダリプロバイダーに問い合わせます。プライマリから一部でも結果が得られた場合は、結果数を増やすためだけにリクエスト対象を広げず、その結果を採用します。これにより、スクレイピング負荷を抑え、不要なブロックや CAPTCHA に遭遇するリスクを軽減します。
現在のルーティングプロファイル:v3。
| 意図 | 実行方式 | 優先順 | プライマリ目標数 |
|---|---|---|---|
technical | aggregate | searxng, brave, duckduckgo, bing, google | 2 |
research | aggregate | exa, tavily, searxng, duckduckgo, brave, bing, google | 3 |
news | aggregate | tavily, duckduckgo, searxng, brave, bing, google | 3 |
commercial | aggregate | searxng, brave, duckduckgo, bing, google | 3 |
shopping | aggregate | searxng, duckduckgo, brave, bing, google | 2 |
local | aggregate | searxng, duckduckgo, brave, bing, google | 2 |
navigational | fallback | searxng, duckduckgo, brave, bing, google | 設定済みのすべて |
general | fallback | 既存の設定順 | 設定済みのすべて |
プロファイル v3 では、オプトイン方式の公式 API を、その能力が実測で確認された領域に配置しています(P1-04 3 日間ライブマトリックス、2026 年 10 月:449/450 回の試行 — evals/providers/ および ADR 0003 を参照)。Tavily のニューストピックとプロバイダー報告の公開日を news の優先項目とし、Exa のニューラル検索を research の優先項目としています。それ以外の行では、v2 の信頼性に基づく順序を維持しています。この順序では、セルフホスト可能な SearXNG と Brave Search API は安定して応答し、DuckDuckGo は一貫して応答する唯一のスクレイパーでした。一方、Bing と Google はスクレイピングを行うクライアントをほとんどブロックしていました。これらの優先設定は、品質を恒久的に保証するものではありません。バージョン管理することで、サーバー内にルーティング条件分岐を散在させずに、決定論的評価とライブ評価の結果に基づいて、以降のリリースで調整できます。プランナーは優先設定を SEARCH_PROVIDERS と照合するため、キーのないプロバイダーが有効になることはなく、キーがない場合の動作も変わりません。
例:意図を考慮した検索
{
"query": "PostgreSQL connection pooling best practices",
"strategy": "auto",
"max_results": 5
}
domain は、react.dev や github.com などを対象とした検索に使用します。意図の検出には常に元のクエリが渡され、プロバイダーでの実行時にのみ site:<domain> が追加されます。
{
"query": "server components reference",
"domain": "react.dev",
"strategy": "auto",
"max_results": 5
}
from_date / to_date(YYYY-MM-DD 形式、両端を含む)を使用すると、タイトルとスニペットで検出された公開日で絞り込めます。日付を検出できない結果は、デフォルトで保持されます。
クライアントがサーバーに上位ページを取得させ、ページ本文から可能性の高い回答を抽出させる必要がある場合にのみ、deep=true を使用してください。回答には、取得した URL に対応するソースごとの引用([Source N])が含まれます。最終的な推論と要約は、引き続き MCP クライアントの LLM が担います。
検出された日付が古い検索スニペットには、クライアントが古い情報源を慎重に扱えるよう、短い鮮度に関する警告が含まれます。
例:フェデレーション検索
{
"query": "postgres connection pooling strategies",
"strategy": "aggregate",
"max_results": 5
}
例:複数クエリ検索
{
"query": "how to configure db backup",
"strategy": "auto",
"expand_query": true,
"max_results": 5
}
expand_query のデフォルトは false です。有効にすると、サーバーは元のクエリと最大 2 つのバリエーションで検索し、URL を重複排除した後、RRF でクエリのランキングを統合して再ランキングします。これにより、プロバイダーへのリクエスト数が最大 3 倍になることがあります。Brave、Tavily、Exa などのキーを使う API プロバイダーでは、課金対象のリクエスト数も同様に増加します。セマンティックキャッシュにヒットした場合、プロバイダーへの問い合わせは発生しません。意図とロケールは元のクエリで決定され、すべてのバリエーションでドメイン制限と同じプロバイダープランが適用されます。日付フィルターは統合後の結果に適用されます。拡張検索には専用のキャッシュ名前空間が使用され、キャッシュにヒットすると、すべてのプロバイダーへのリクエストが省略されます。
例:構造化 JSON 出力
{
"query": "postgres pooling",
"format": "json",
"max_results": 5
}
query、resultCount、results[](タイトル、URL、スニペット、ソース、任意のスコア)、meta を含む、安定したペイロードを返します。
例:ローカルナレッジベース
{ "content": "PgBouncer multiplexes PostgreSQL connections...", "title": "PgBouncer Guide", "source": "https://example.com/pgbouncer" }
続いて、検索します。
{ "query": "connection pooler", "max_results": 5 }
または、エンティティグラフを探索します。
{ "entity": "PgBouncer" }
fetch_content はブラウザーを開く前に、ソースに応じた高速な方法を使用します。
- GitHub のリポジトリ、blob、tree、raw の URL は、可能な場合
raw.githubusercontent.comから読み取ります。 - RSS または Atom フィードの URL、および一般的なブログ/ニュースのフィードパスは、最近の項目を並べた Markdown リストに変換します。
- 通常の HTML ページでは、引き続き HTTP を優先した Readability 解析を行い、必要に応じて Playwright にフォールバックします。
設定
| 変数 | デフォルト | 説明 |
|---|---|---|
RATE_LIMIT_SEARCH_PER_MIN | 10 | 1 分あたりの web_search リクエストの最大数です。無効な値または 0 以下の値を指定すると、レート制限は無効になります。 |
RATE_LIMIT_FETCH_PER_MIN | 20 | 1 分あたりの fetch_content リクエストの最大数です。無効な値または 0 以下の値を指定すると、レート制限は無効になります。 |
SEARCH_PROVIDERS | duckduckgo,marginalia,bing(BRAVE_SEARCH_API_KEY が設定されている場合は brave,duckduckgo,marginalia,bing) | 使用を許可するプロバイダーと優先順位をカンマ区切りで指定します。対応する値は duckduckgo、bing、brave、google、yahoo、marginalia、searxng、tavily、exa です。キーが必要なプロバイダー(brave、tavily、exa)は、キーが未設定の場合、リストから除外されます。 |
READER_FALLBACK_URL | 未設定 | 直接 HTTP とブラウザーの両方が失敗した場合に fetch_content、index_url、research で使用する任意のリーダーサービスです。<READER_FALLBACK_URL><page url> の形式で呼び出されます(例:https://markdown.new/)。ページ URL がこのサードパーティーに送信されるため、デフォルトでは無効です。 |
BRAVE_SEARCH_API_KEY | 未設定 | Brave Search API 用の任意のキーです。設定すると、brave プロバイダーはウェブサイトをスクレイピングする代わりに公式 API を呼び出し、スクレイピングを妨げるレート制限を回避します。 |
TAVILY_API_KEY | 未設定 | Tavily Search API 用の任意のキーです。設定すると、tavily プロバイダーで公開日付きのニューストピック検索が利用できるようになり、ニュースを意図したクエリには Tavily のニューストピックが使用されます。料金はリクエストごとに発生します。 |
EXA_API_KEY | 未設定 | Exa Search API 用の任意のキーです。設定すると、type: auto によるニューラル(セマンティック)ウェブ検索が exa プロバイダーで利用できるようになります。料金はリクエストごとに発生します。 |
SEARXNG_BASE_URL | 未設定 | JSON 形式が有効になっている SearXNG インスタンスのベース URL です(例:https://searx.example.com)。searxng プロバイダーに必要です。API キーは使用しません。 |
ENABLE_CROSSLINGUAL | false | 言語検出と多言語横断検索のサポートを有効にします。初回実行時にローカルモデルのダウンロードが発生することがあります。無効の場合でも、クエリのヒューリスティクスによってトルコ語などの対応ロケールが推定されます。 |
ENABLE_RERANKER | false | ローカルの Transformers.js モデルを使用した、web_search の検索結果の任意のクロスエンコーダーによる再ランキングを有効にします。初回使用時にモデルがダウンロードされます。 |
TRACE_SEARCHES | false | 検索ごとの簡潔な実行トレース(ステージ、所要時間、キャッシュ)を標準エラー出力に記録します。最近の検索は常に server_status から確認できます。 |
MEMORY_MAX_NOTES | 500 | 保持するセッションメモリのメモの最大数です。古いメモから削除されます。 |
FETCH_WAIT_UNTIL | networkidle | Playwright の待機方法です。レンダリング済みページへのフォールバックを高速化するには domcontentloaded を使用してください。 |
CHROMIUM_INSTALL_TIMEOUT_MS | 600000 | 初回使用時の Chromium 自動ダウンロードに許可する最大時間です。ダウンロードが停止した場合はこの時間が経過すると中止され、次のブラウザーリクエストで再試行されます。 |
FORCE_PLAYWRIGHT | 未設定 | true に設定すると、HTTP を優先する取得処理をスキップし、常に Playwright を使用します。 |
CACHE_DB_PATH | ~/.search-memory-mcp/websearch_cache.db(作業ディレクトリに websearch_cache.db がすでにある場合は、そのファイルが維持されます) | セマンティックキャッシュ、コンテンツキャッシュ、ナレッジインデックス、セッションメモリ、エンティティグラフで使用する SQLite データベースのパスです。 |
INGEST_ALLOWED_DIRS | (空:無効) | ingest_document がファイルを読み取れるディレクトリをカンマ区切りで指定します(例:~/Documents/notes,~/Papers)。シンボリックリンクは先に解決されるため、リンク先をこれらのディレクトリの外にすることはできません。隠しファイルおよび隠しフォルダー(.ssh や .env など)内のファイルは読み取られません。25 MB を超えるファイルは拒否されます。 |
CACHE_CLEANUP_INTERVAL_HOURS | 24 | 期限切れのコンテンツキャッシュをクリーンアップする間隔です。 |
ファイルベースの SQLite ストアでは、synchronous=FULL の WAL ジャーナリングを使用します。:memory: データベースはメモリ内に保持されます。書き込み可能なローカルデータディレクトリを使用してください。WAL には同一ホスト上の共有メモリが必要なため、ネットワークファイルシステム上で共有されるデータベースには適していません。サーバーの実行中は、-wal ファイルと -shm ファイルもデータベースの一部です。.db ファイルだけをコピーしても、一貫性のあるライブバックアップにはなりません。SQLite の WAL ドキュメントと、使い捨てのバックアップ/復元リハーサルを参照してください。本番環境のバックアップ操作は、これらのローカル回帰テストとは別に行います。 |
Docker
GitHub Actions ワークフロー(.github/workflows/docker.yml)はイメージをビルドし、stdio 経由でそのイメージに対して MCP スモークテストを実行し、linux/amd64 および linux/arm64 向けの ghcr.io/kefyusuf/search-memory-mcp を公開します。:latest と :sha-<commit> は main から、semver タグは v* タグから公開されます。任意のイメージに対してローカルでスモークテストを実行するには、次のコマンドを使用します:SMOKE_DOCKER_IMAGE=<image> npm run smoke:mcp。
npm run docker:build
npm run docker:up
オプションの SearXNG
プロバイダーの信頼性は実測値にばらつきがあるため(トラブルシューティングを参照)、compose ファイルには、2 つ目の信頼できる情報源として、オプションのセルフホスト型 SearXNG サービスが含まれています。このサービスは searxng プロファイルを指定した場合にのみ起動し、compose ネットワーク内からのみアクセスできます:
SEARXNG_SECRET=$(openssl rand -hex 32) \
SEARCH_PROVIDERS=searxng,duckduckgo \
SEARXNG_BASE_URL=http://searxng:8080 \
docker compose --profile searxng up
docker/searxng/settings.yml では、このサーバーが読み取る JSON API を有効にし、SearXNG の公開レート制限を無効にしています。Docker イメージのワークフローでは、このサービスを CI で起動し、JSON 検索への応答を確認します。
Docker Compose は SQLite キャッシュを /app/data にマウントされた名前付きボリュームに保存し、Hugging Face モデルは別の名前付きボリュームに保存します。コンテナーでは CACHE_DB_PATH=/app/data/websearch_cache.db が設定されます。
Docker の両ステージでは Node 24 を使用しており、.nvmrc および CI と一致しています。ランタイムでは、ライフサイクルスクリプトを無効にして依存関係をインストールした後、ネイティブ SQLite バインディングを明示的に初期化します。使い捨てのデータベースでコンパイル済みの stdio インターフェイスを確認するには、リポジトリのルートから次を実行します:
docker compose -p search-memory-mcp-check run --rm -T \
-v "${PWD}/scripts:/app/scripts:ro" \
-e CACHE_DB_PATH=/tmp/search-memory-mcp-smoke.db \
search-memory-mcp node scripts/smoke-mcp.mjs
docker compose -p search-memory-mcp-check down --volumes --remove-orphans
スモークテストでは、初期化、ツールの検出、ステータス、メモリの保存/想起/削除、引数の検証、ループバックのブロックを確認します。実際の検索プロバイダーやモデルの推論は評価しません。開発用データボリュームを分離しておくため、確認には個別の Compose プロジェクト名を使用してください。
信頼された TLS 検査プロキシがブラウザーのダウンロードを傍受する場合は、オプションの BuildKit build_ca シークレットとして、公開 CA 証明書を指定してください:
docker build --secret id=build_ca,src=/path/to/trusted-ca.pem -t search-memory-mcp:latest .
証明書は依存関係のインストール時にのみ使用され、イメージにはコピーされません。ランタイムの HTTPS 信頼設定は別の構成上の問題です。TLS 検証は有効なままにしてください。
開発
リリース範囲、本番環境での課題、測定可能なリリース判定基準については、本番環境向けロードマップと分野別比較を参照してください。
npm run build
npm run typecheck
npm test
npm run smoke:mcp
npm run eval:retrieval
npm audit --audit-level=moderate
npm pack --dry-run --json
npm run e2e は、MCP SDK クライアントを介して、コンパイル済みサーバーに対するユーザーシナリオを実行します。メモリ、ローカルの PDF/DOCX の取り込み(隠しファイルや範囲外のファイルの拒否も含む)、ナレッジ検索、エンティティグラフ、続いてウェブ検索、ページと PDF の取得、リサーチを行います。ウェブ検索を利用できない場合、ウェブ関連の手順は SKIP として報告されるため、ローカルでの手順はどこでも実行できます。全体をテストするには、通常のネットワーク環境で実行してください。手順が失敗すると、終了コード 1 を返します。
npm run smoke:mcp は、コンパイル済みサーバーを stdio 経由で起動し、web_search の戦略値(fallback、aggregate、auto)を検証し、ナレッジ/メモリツールを確認して、server_status のルーティング診断を検証し、fetch_content が localhost をブロックすることを確認します。検索エンジンの HTML やネットワークの利用可否に CI が左右されないよう、実際のプロバイダー検索は実行しません。
npm run eval:retrieval は、evals/retrieval/cases.jsonl のフィクスチャを使用して、ナレッジインデックスに対するオフラインの FTS のみの検索ベースライン(recall@k、precision@k、MRR)を実行します。取り込みと検索の両方で埋め込みが無効になるため、評価時にモデルが読み込まれたりダウンロードされたりすることはありません。セマンティック検索/ハイブリッド検索の品質は測定しません。
npm run benchmark:providers(ビルド後に実行)は、evals/providers/queries.jsonl の実際のクエリ(さまざまなインテントにわたる EN/TR の 16 件)を、SEARCH_PROVIDERS の各プロバイダーに対して一度に 1 つずつ送信し、プロバイダーごとに成功、結果なし、エラー、p50/p95 レイテンシを出力します。クエリ数を減らすには --limit N、リクエスト間の待機時間を指定するには --delay MS(既定値は 1500)、生の試行結果を保存するには --json PATH を使用してください。結果がない、または失敗した試行の生レスポンスを保存するには --dump DIR を使用します(ブロックページや同意ページが原因か、結果のマークアップが変更されたかを確認するのに便利です)。実際の検索エンジンに接続するため、CI では実行しません。結果は、実行時のネットワーク環境と検索エンジンによるブロック状況によって異なります。
ビルド後に node scripts/eval-local-quality.mjs を実行すると、より幅広い合成 FTS/エンティティ特性評価の結果が JSON で出力されます。フィクスチャのラベルと制限事項を参照してください。生成されたレポートは無視対象の .cache/ に保存してください。この診断によってランタイムの動作が変わったり、リリースしきい値が適用されたりすることはありません。
決定論的な TR/EN ルーティングフィクスチャは evals/search-routing/queries.jsonl にあり、通常の Vitest スイートで実行されます。実際の分類器を読み込んだりプロバイダーに接続したりせずに、インテントの網羅性、保守的なヒューリスティックの動作、曖昧なケースでの処理保留、プロバイダー許可リストの適用を検証します。
トラブルシューティング
- ページでブラウザーが必要になると、サーバーは初回に Chromium を自動でダウンロードします。ダウンロードに失敗したり停止したりする場合(オフラインやプロキシ経由など)は、
CHROMIUM_INSTALL_TIMEOUT_MSの時間が経過すると停止します。手動でnpx playwright install chromiumを実行してください。 - サーバーが SQLite モジュール(
better-sqlite3)を読み込めなかったと表示した場合は、表示される手順に従ってください。Node 24(.nvmrcに記載されているバージョン)を使用します。npm 11 がインストールスクリプトをスキップした場合は、npm install-scripts approve better-sqlite3を実行し、その後npm rebuild better-sqlite3を実行してください。または、Docker で実行する(ローカル環境のセットアップ不要)方法もあります。 - モデルを利用する最初のリクエストに時間がかかる場合は、Transformers.js のモデルのダウンロードが完了するまで待ってから、再試行してください。
- 検索結果が返されない場合は、
SEARCH_PROVIDERSの順序や設定を変更するか、fetch_contentに直接 URL を指定してみてください。 - キーが必要なプロバイダーで
HTTP 401が返される場合、キーが無効です。HTTP 429(および Tavily の432)は、レート制限またはクォータの超過を意味します。試行結果は空の結果ではなく、プロバイダーエラーとして報告され、設定されている他のプロバイダーは引き続き応答します。 - プロバイダーの信頼性はネットワークによって異なります。2026 年 10 月の実行時(
npm run benchmark:providers)では、DuckDuckGo はすべてのクエリに応答しました。Bing は通常のクエリに対して「結果なし」ページを返すことがあり、ソフトブロックのように見えました。Brave は HTTP 429 を返し、Google はすべてのリクエストに JavaScript が必要なページを返しました(現在はエラーとして報告されます)。duckduckgoを先頭に置き、2 つ目の信頼できる情報源が必要な場合は、セルフホスト可能な SearXNG(SEARXNG_BASE_URL)を追加してください。npm run benchmark:providersを実行して、ご利用のネットワークで測定してください。 - 集約モードが遅すぎる場合や、プロバイダーによるブロックが発生する場合は、デフォルトの
fallback戦略を使用してください。 autoが用途に対して広すぎる検索プランを選ぶ場合は、明示的にfallbackまたはaggregateを使用してください。明示的な戦略では、自動プランナーを経由しません。- Docker で Chromium が見つからない場合は、
npm run docker:buildでイメージを再ビルドしてください。 - プロジェクトのルートディレクトリにキャッシュファイルが作成される場合は、
CACHE_DB_PATHを専用のデータディレクトリに設定してください。 - ナレッジ検索でキーワードしかヒットしない場合、埋め込みのインデックス作成中である可能性があります。ベクトルの準備が整うまで、
search_indexは FTS のみを使用します。
既知の制限事項
- デフォルトの検索は主に DuckDuckGo に依存しています。 検索エンジンはスクレイピングを行うクライアントをブロックします。私たちの測定では、Brave は HTTP 429 を返し、Google は JavaScript のみのページを表示するため、どちらもプロバイダーのエラーとして表示されるようになりました。Bing がクライアントをブロックすると、通常の「検索結果なし」ページを返すため、実際に検索結果が空の場合と区別できません。Yahoo はブラウザー以外からのすべてのリクエストに対し、ヘッダーに関係なく空の HTTP 500 を返すため、オプトインの
yahooプロバイダーはほとんど機能しません。Marginalia はクライアントに待機を求めることがあります。プロバイダーはこれに対応しますが、それでも4件中3件のクエリにしか応答しませんでした。安定した結果を得るには、BRAVE_SEARCH_API_KEYを設定するか、セルフホスト可能な SearXNG(SEARXNG_BASE_URL)を2つ目のソースとして追加してください。トラブルシューティングも参照してください。 - スクレイピングによる検索では、ニューラル検索や鮮度が保証されたニュースには対応できません。 キーワードインデックスは「X のドキュメント」や「エラー Y」には適していますが、曖昧な意味的クエリやごく最近の報道には、それらに特化したインデックスが必要です。有料 API の利用を許容するユーザーは、オプトインの
TAVILY_API_KEY(ニューストピック、公開日)とEXA_API_KEY(ニューラル検索)でこの差を補えます。キーがない場合、情報の鮮度は引き続きスクレイピングした検索エンジンのインデックスと、可能な範囲での日付検出に依存します。 - 非表示コンテンツのフィルタリングは可能な範囲で行われます。
hidden属性、aria-hidden、<template>、またはインラインスタイルによって非表示になっている要素は削除されます。外部スタイルシートやスクリプトによって非表示になっているコンテンツは削除されません。ウェブコンテンツは<untrusted_web_content>マーカーで囲まれますが、クライアントのモデルは引き続きこれをデータとして扱う必要があります。 - スキャンされた PDF は読み取れません。 PDF のテキストは OCR なしで抽出されるため、画像のみのページからテキストは得られません。
- 初回実行時にモデルとブラウザーがダウンロードされます。 埋め込みモデルと Playwright Chromium は初回使用時に取得されます。オフラインのマシンでは、事前にインストールしておくか、Docker イメージを使用する必要があります。
- ローカルユーザーは1人のみです。 サーバーは1つのローカルクライアント向けに stdio 経由で動作します。認証機能はなく、共有 HTTP エンドポイントもまだありません。
- ウェブ関連のステップには、外部ネットワークへの接続が必要です。 検索エンジンに接続できない場合、
npm run e2eはウェブ関連のステップを SKIP として報告します。
npm パッケージング
npm パッケージには build/、README.md、LICENSE、SECURITY.md のみが含まれます。npm pack は prepack を通じて npm run build を実行するため、パッケージにはローカルの計画ファイル、テスト、キャッシュ、ソースのみのアーティファクトではなく、コンパイル済みの JavaScript が含まれます。
リリースは v* タグがプッシュされたときに .github/workflows/release.yml によって公開されます。このワークフローは provenance 付きで npm パッケージを公開し、MCP Registry にサーバーを登録します。docker.yml は同じタグの Docker イメージを公開します。npm の公開には trusted publishing(GitHub OIDC)を使用するため、npm トークンは保存されません。タグを付ける前に、package.json と server.json の両方のバージョンを設定してください。
セキュリティ
報告方法と現在の依存関係監査に関するメモについては、SECURITY.md を参照してください。
ライセンス
ISC
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。