webshift について
WebShiftは、ウェブ情報を必要とするエージェント向けのRustライブラリ兼MCPサーバーです。検索と取得にHTMLの整理、再ランキング、出力サイズ制限を組み合わせます。
主な機能
- 01複数バックエンドでの検索と取得
- 02出力サイズを制限したHTML整理
- 03BM25による検索結果の再ランキング
- 04任意のLLM検索拡張と要約
- 05構造を保ったHTMLテキストの書き換え
活用シーン
- 01AIエージェントに簡潔なウェブ検索結果を提供
- 02Rustの処理フローでウェブコンテンツを整理
- 03マークアップを保ってHTMLを翻訳・書き換え
- 04ダウンロード量と結果の長さを制限
MCP 対応
MCP stdio経由でwebshift_query、webshift_fetch、webshift_onboardingを公開し、検索、ページ取得、内容整理を提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
WebShift
WebShift とは
WebShift は、ノイズの多い Web ページを LLM が扱いやすい適切なサイズのテキストに変換する Rust ライブラリおよび MCP サーバーです。
生の HTML のほとんどは不要な要素です。スクリプト、広告、ナビゲーションメニュー、Cookie バナー、トラッキングピクセルなどが含まれています。これをそのまま LLM に渡すと、役に立たないトークンが数万個もコンテキストウィンドウを埋め尽くし、推論する余地がなくなります。WebShift はこうしたノイズをすべて取り除き、テキストを無害化して厳密なサイズ上限を適用することで、モデルが重要なコンテンツだけを受け取れるようにします。
利用できる機能
有効にする機能に応じて、WebShift は次の 4 つの用途で利用できます。
| 用途 | クレート | 機能フラグ | 機能 |
|---|---|---|---|
| HTML ノイズ除去 | webshift | default-features = false | clean() — 純粋な Rust による HTML からテキストへの変換パイプラインです。ノイズ要素を除去し、Unicode/BiDi を無害化し、空白を圧縮します。ネットワーク接続も設定も不要です。LLM 向けの Web コンテンツを処理する Rust プロジェクトに、そのまま組み込めます。 |
| HTML テキスト書き換え | webshift | features = ["text-map"] | extract_text_nodes() + replace_text_nodes() — HTML から個々のテキストノードを抽出して操作(翻訳、書き換え、簡略化など)し、構造を保ったまま HTML を再構築します。タグ、属性、リンクには一切触れません。 |
| Web コンテンツクライアント | webshift | default または features = ["llm"] | fetch() + query() — サイズ上限付きのストリーミング HTTP フェッチャーです。8 種類の検索バックエンド、BM25 リランキング、オプションの LLM クエリ拡張と要約を備えています。検索クエリから構造化された結果まで、パイプライン全体を提供します。 |
| MCP サーバー | webshift-mcp | すべての機能 | MCP stdio 経由で webshift_query、webshift_fetch、webshift_onboarding を公開するネイティブバイナリ(mcp-webshift)です。静的バイナリ 1 つで動作し、ランタイム依存関係はありません。 |
WebShift を使用する場面
- Web 検索が必要な AI エージェントを構築しており、生の HTML ではなく、クリーンで予算を制御できるテキストが必要な場合。
- Rust のパイプラインで Web ページを処理しており、実際のコンテンツを失わずにノイズを除去する、信頼性の高い HTML からテキストへの変換ツールが必要な場合。
- HTML 内のテキストを、マークアップを壊さずに LLM で翻訳、書き換え、簡略化したい場合。text-map を使えば、安全に元の形式へ戻せます。
- 単一のバイナリで動作する MCP Web 検索サーバーが必要な場合。Python、pip、venv、Docker は不要です(必要であれば使用できます)。
- 出力サイズを確実に制限したい場合。ページごとの上限、合計予算の上限、ストリーミングダウンロードの上限を設定できます。
WebShift を使用しない場面
- JavaScript を多用する SPA をレンダリングするヘッドレスブラウザーが必要な場合。WebShift は静的 HTML を解析しますが、JS は実行しません。
- ページの視覚的なレイアウトを保ったまま、レンダリングやスクリーンショットの撮影を行いたい場合。WebShift は HTML の構造を処理しますが、CSS のレンダリングやレイアウトの計算は行いません。(注:
text-mapはテキスト書き換え用途で DOM 構造を保持します。) - ページ間の移動、フォームへの入力、認証フローへの対応が必要な Web スクレイパーを構築する場合。
仕組み
Question
|
+- (optional) LLM query expansion -> multiple search variants
|
+- Search via backend (SearXNG, Brave, Tavily, Exa, SerpAPI, Google, Bing, HTTP)
|
+- Deduplicate + filter binary URLs
|
+- Streaming fetch with per-page size cap
|
+- HTML cleaning -> plain text (noise elements, scripts, nav removed)
|
+- Unicode/BiDi sterilization
|
+- BM25 deterministic reranking
| +- (optional) LLM-assisted tier-2 reranking
|
+- Budget-aware truncation across all sources
|
+- (optional) LLM Markdown summary with inline citations
|
+- Structured JSON output
各パイプラインの段階、BM25 パラメーター、適応型の予算割り当て、実際の圧縮指標について詳しくは、内部の仕組みをご覧ください。設定の全項目(TOML、環境変数、CLI 引数)については、設定をご覧ください。すぐに使える例については、ユースケースをご覧ください。
インストール
バイナリ(MCP サーバー)
cargo install webshift-mcp
バイナリ名は mcp-webshift です。
ソースから
cargo install --path crates/webshift-mcp
ライブラリとして
# Full pipeline (search + fetch + clean + rerank)
webshift = "0.2"
# Cleaner + fetcher only (no search backends)
webshift = { version = "0.2", default-features = false }
# Text-map only (extract/replace text nodes in HTML)
webshift = { version = "0.2", default-features = false, features = ["text-map"] }
# Everything including LLM features
webshift = { version = "0.2", features = ["llm"] }
クイックスタート
1. 検索バックエンドをセットアップする
最も簡単な方法は SearXNG です。無料でセルフホスト可能、API キーも不要です。
docker run -d -p 8080:8080 searxng/searxng
Docker を使わない場合は、クラウドバックエンドを使用してください。検索バックエンドをご覧ください。
2. MCP クライアントを設定する
{
"mcpServers": {
"webshift": {
"command": "mcp-webshift",
"args": ["--default-backend", "searxng"]
}
}
}
これで完了です。エージェントは webshift_query、webshift_fetch、webshift_onboarding を利用できるようになります。
クライアントごとのセットアップ方法は、docs/integrations/をご覧ください。
MCP ツール
| ツール | 説明 |
|---|---|
webshift_query | 検索パイプライン全体:検索 + 取得 + クリーニング + 再ランク付け +(任意で)要約 |
webshift_fetch | 単一ページの取得とクリーニング |
webshift_onboarding | エージェント向けの JSON ガイド(予算、バックエンド、ヒント)を返します |
webshift_query のパラメーター
| パラメーター | 型 | デフォルト | 説明 |
|---|---|---|---|
queries | 文字列またはリスト | 必須 | 検索クエリ、またはクエリのリスト |
num_results_per_query | 整数 | 5 | クエリごとの検索結果数 |
lang | 文字列 | なし | 言語フィルター(例:"en") |
backend | 文字列 | 設定のデフォルト | 検索バックエンドを上書きします |
設定
解決の優先順位(上が最優先):
- CLI 引数 —
--default-backend、--brave-api-keyなど - 環境変数 —
WEBSHIFT_*プレフィックス - 設定ファイル —
webshift.toml(カレントディレクトリ、次に~/webshift.toml) - 組み込みのデフォルト値
設定ファイル
[server]
max_query_budget = 32000 # total char budget across all sources
max_result_length = 8000 # per-page char cap
max_total_results = 20 # hard cap on results per call
max_download_mb = 1 # streaming cap per page (MB)
search_timeout = 8 # seconds
results_per_query = 5
oversampling_factor = 2
adaptive_budget = "auto" # "auto" | "on" | "off" — budget allocation mode
[backends]
default = "searxng"
[backends.searxng]
url = "http://localhost:8080"
[backends.brave]
api_key = "BSA-..."
[backends.tavily]
api_key = "tvly-..."
[backends.exa]
api_key = "..."
[backends.serpapi]
api_key = "..."
engine = "google" # google | bing | duckduckgo | yandex
[backends.google]
api_key = "..."
cx = "..." # Custom Search Engine ID
[backends.bing]
api_key = "..."
market = "en-US"
[backends.http]
url = "https://my-search.example.com/api/search"
query_param = "q"
count_param = "limit"
results_path = "data.items" # dot-path to results array in JSON response
title_field = "title"
url_field = "link"
snippet_field = "description"
[backends.http.headers]
"Authorization" = "Bearer my-token"
[llm]
enabled = false
base_url = "http://localhost:11434/v1" # OpenAI-compatible
api_key = ""
model = "gemma3:27b"
timeout = 60
expansion_enabled = true
summarization_enabled = true
llm_rerank_enabled = false
すべての設定項目について、3 種類の設定方法(TOML、環境変数、CLI 引数)と平易な説明をご覧になるには、設定リファレンス全文をご覧ください。
すぐに使える設定例は、ユースケースとexamples/にあります。
主な環境変数
WEBSHIFT_DEFAULT_BACKEND=searxng
WEBSHIFT_SEARXNG_URL=http://localhost:8080
WEBSHIFT_BRAVE_API_KEY=BSA-xxx
WEBSHIFT_GOOGLE_API_KEY=xxx
WEBSHIFT_GOOGLE_CX=xxx
WEBSHIFT_BING_API_KEY=xxx
WEBSHIFT_LLM_ENABLED=true
WEBSHIFT_LLM_BASE_URL=http://localhost:11434/v1
WEBSHIFT_LLM_MODEL=gemma3:27b
検索バックエンド
| バックエンド | 認証 | 備考 |
|---|---|---|
| SearXNG | なし | セルフホスト可能、無料。デフォルト:http://localhost:8080 |
| Brave | API キー | 無料枠あり。brave.com/search/api |
| Tavily | API キー | AI 向け。tavily.com |
| Exa | API キー | ニューラル検索。exa.ai |
| SerpAPI | API キー | 複数の検索エンジンのプロキシ(Google、Bing、DDG...)。serpapi.com |
| API キー + CX | カスタム検索。無料枠:1 日 100 リクエスト。programmablesearchengine.google.com | |
| Bing | API キー | ウェブ検索 API。無料枠:月 1,000 リクエスト。Microsoft Azure |
| HTTP | 設定可能 | 汎用 REST バックエンド — コード不要、TOML のみで設定可能 |
LLM 機能(オプション)
すべてオプトイン方式です。デフォルトでは無効で、有効にしない限りデータがマシンの外部に送信されることはありません。
| 機能 | 内容 |
|---|---|
| クエリ拡張 | 1 つのクエリから、相互に補完する N 個の検索バリエーションを生成します |
| 要約 | [1] [2] の引用をインラインで含む Markdown レポートを作成します |
| LLM による再ランキング | 決定論的な BM25 の上に、第 2 層の再ランキングを適用します |
言語横断の正規化(ボーナス機能): BM25 の再ランキングで外国語(中国語、日本語、アラビア語など)のページが表示された場合でも、LLM 要約機能はプロンプトの言語で最終レポートを生成します。ソースページに複数の言語が混在していても、エージェントは読みやすく整理された出力を受け取れます。
OpenAI 互換 API(OpenAI、Ollama、vLLM、LM Studio など)であれば、どれでも動作します。
[llm]
enabled = true
base_url = "http://localhost:11434/v1"
model = "gemma3:27b"
過剰なデータ取得を防ぐ保護機能
常に有効で、コアとなる価値を提供します。
| 保護機能 | 説明 |
|---|---|
max_download_mb | ストリーミング上限。レスポンス全体をバッファーに格納することはありません |
max_result_length | クリーンアップ後の各ページの文字数にハード上限を設定します |
max_query_budget | すべてのソースを対象とする合計文字数の上限です |
max_total_results | 1 回の呼び出しで取得できる結果数にハード上限を設定します |
| バイナリーフィルター | .pdf、.zip、.exe などを、ネットワークリクエストの前にフィルタリングします |
| Unicode の無害化 | BiDi 制御文字とゼロ幅文字を削除します |
ライブラリの使用方法
use webshift::{Config, clean, fetch, query};
// Clean raw HTML — cap output at 8000 chars
let result = clean("<html><body><p>Hello world</p></body></html>", 8000);
println!("{}", result.text);
// Pass 0 to disable the per-page cap entirely (no truncation)
let full = clean("<html><body><p>Hello world</p></body></html>", 0);
assert!(!full.truncated);
// Fetch and clean a single page
let config = Config::default();
let page = fetch("https://example.com", &config).await?;
// Full search pipeline
let results = query(&["rust async programming"], &config).await?;
for source in &results.sources {
println!("[{}] {} — {} chars", source.id, source.title, source.content.len());
}
// Backend partial failures (CAPTCHA, rate-limits, engine outages) are surfaced
// in `warnings` rather than as Err. Empty sources + non-empty warnings means
// "all backends blocked" — distinct from a legitimate "no matches found".
if results.sources.is_empty() && !results.warnings.is_empty() {
eprintln!("all backends failed: {:?}", results.warnings);
}
Text-map:マークアップを壊さずに HTML コンテンツを書き換える
テキストノードを抽出して操作(翻訳、書き換え、簡略化など)した後、構造、属性、リンクを維持したまま HTML を再構築します。
use webshift::{extract_text_nodes, replace_text_nodes, TextReplacement};
let html = r#"<p>Hello <a href="https://example.com">world</a></p>"#;
let map = extract_text_nodes(html);
// map.nodes = [(0, "Hello"), (1, "world")]
let replacements = vec![
TextReplacement { id: 0, text: "Ciao".into() },
TextReplacement { id: 1, text: "mondo".into() },
];
let result = replace_text_nodes(html, &replacements).unwrap();
// → <p>Ciao <a href="https://example.com">mondo</a></p>
// href untouched, tags intact, only text changed.
features = ["text-map"] が必要です。翻訳の完全な例については、ユースケース #11 を参照してください。
機能フラグ
| 機能 | デフォルト | 有効になる機能 |
|---|---|---|
backends | オン | すべての検索バックエンドとクエリパイプライン |
llm | オフ | LLM クライアント、クエリ拡張、要約、LLM による再ランキング |
text-map | オフ | extract_text_nodes() と replace_text_nodes() — コンテンツ書き換えのための DOM ラウンドトリップ |
インテグレーション
| プラットフォーム | ガイド |
|---|---|
| Claude Desktop、Claude Code、Cursor、Windsurf、VS Code | IDE インテグレーション |
| Zed — 自動ダウンロードと「サーバーを設定」モーダルを備えたネイティブ拡張機能 | Zed 拡張機能 |
| Gemini CLI、Claude CLI、カスタムエージェント | エージェントとのインテグレーション |
ベータステータス
WebShift はベータ版です。コア機能は安定しており、サーバーは日常的に使用されていますが、1.0 より前に API の仕様が変更される可能性があります。
フィードバックをお待ちしています。 期待どおりに動作しない、挙動がおかしい、またはまだ対応されていないユースケースがある場合は、ぜひお知らせください。
バグ報告、設定に関する質問、機能リクエストはいずれも、今後のロードマップの策定に役立ちます。
貢献
貢献を歓迎します。詳しいガイドラインについては、CONTRIBUTING.md をご覧ください。
- 開発環境のセットアップとワークフロー
- コードスタイルと規約
- テスト要件
- ドキュメントの基準
- プルリクエストの手順
ライセンス
MIT ライセンス — 詳細については LICENSE をご覧ください。
リンク
- GitHub リポジトリ — ソースコードと課題
- Docs.rs — API ドキュメント
- MCP レジストリ — Model Context Protocol レジストリ上の WebShift
- MCP プロトコル — Model Context Protocol の仕様
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。