Department Web-Search MCP Gateway
部署 Web-Search MCP ゲートウェイ
部門全体で共有できるセルフホスト型ウェブ検索サービスです。単一のログインブラウザセッション(共有サービスアカウント)を再利用するため、イントラネット / SSO / 同意画面ログインは一度だけ処理されます。すべてのクライアントは web_search ツールを呼び出すだけで、ユーザーごとのログインや API キーは不要です。
任意の MCP クライアントが1つの URL に接続します:
Chatbox (≥1.14)
OpenCode — ローカル、共有サーバー上、または vscode-remote 経由
Claude Code(および MCP を話す他のコーディングエージェント)
これは調査ノートの T1「集中検索ゲートウェイ」 です:1台の内部マシン + 1つの共有 Chrome プロファイル + 1つの HTTP MCP エンドポイント。
仕組み
Chatbox / OpenCode(local|server|vscode-remote) / Claude Code
│ remote MCP (Streamable HTTP, /mcp) — same URL for everyone
▼
┌──────────────────────────────────────────────┐
│ Gateway (this service, Node + Express) │
│ • Bearer token (optional) + Host validation │
│ • MCP tools: web_search / read_webpage │
└──────────────────────────────────────────────┘
│ connectOverCDP / launchPersistentContext
▼
┌──────────────────────────────────────────────┐
│ Chrome (persistent profile, shared account) │ ← logged in ONCE via `npm run login`
│ • per-request new tab (isolation) │
│ • concurrency cap + timeouts │
└──────────────────────────────────────────────┘
│ optional fallback
▼
SearXNG (if SEARXNG_URL set) — public-search fallback when browser returns nothingcreateMcpHandler は、同じ /mcp エンドポイントで 2025 年世代と 2026 年世代の両方の MCP クライアント を提供するため、クライアントのトランスポート互換性は問題になりません。
ヘッドレス Linux サーバー + ログイン用 Windows PC
サーバーには GUI がありませんが、人間が Windows PC でログインできます。.env でモードを選択します(BROWSER_MODE)— コードは同じで、設定のみが異なります。
⚠️ Windows Chrome の プロファイル ディレクトリを Linux にコピーしないでください。 Chromium は Cookie を OS にバインドされたキー(Windows では DPAPI、Linux ではキーリング/"peanuts")で暗号化するため、コピーしたプロファイルは静かにログインを失います。以下のクロス OS セーフなモードのいずれかを使用してください。
モード C — BROWSER_MODE=cdp(推奨):Linux ゲートウェイが Windows ブラウザに接続
Windows PC(常時オン):共有アカウントで一度ログインし、ローカルのみのデバッグポートで Chrome を起動したままにします:
chrome --remote-debugging-port=9222 --remote-debugging-address=127.0.0.1 ^ --user-data-dir=C:\dept-search-profileそのポートを SSH リバーストンネル で Linux サーバーに安全に転送します(Windows PC で実行;Win10/11 には OpenSSH が同梱):
ssh -R 9222:127.0.0.1:9222 linuxuser@gateway.serverLinux サーバー:
.env→BROWSER_MODE=cdp、CDP_ENDPOINT=http://127.0.0.1:9222(サーバー上でローカル、Windows ブラウザにトンネル経由で戻る)。その後npm start。ログインはライブのまま(ブラウザが使用されるにつれて Cookie が更新されます);プロファイルのコピーは不要;認証されていない CDP ポートはネットワーク上に公開されません。欠点:Windows PC がオフになると、復帰するまで検索が失敗します(それが許容できない場合はモード B を使用)。
モード B — BROWSER_MODE=storagestate:スナップショット、Linux 自己完結型
Windows PC:
npm run login(ヘッドあり)を実行し、ログインし、Enter キーを押す →auth.json(OS に依存しない Cookie + localStorage の JSON)が書き込まれます。auth.jsonを Linux サーバーにコピーし、BROWSER_MODE=storagestate、STORAGE_STATE_FILE=./auth.jsonを設定し、npm startを実行します。Linux はスナップショットを読み込んだ独自のヘッドレスブラウザを実行します — トンネル不要、Windows PC がオフでも動作します。トレードオフ:凍結されたスナップショット — SSO Cookie の有効期限が切れたら再エクスポート;Cookie + localStorage のみを保持(IndexedDB/クライアント証明書は不可)— ほとんどの SSO で十分です。
モード A — BROWSER_MODE=persistent:Windows PC がすべてを実行
予備の Windows PC を常時稼働のサービスホストとして使用できる場合:そこで
npm run loginを実行(プロファイルをシード)、その後BROWSER_MODE=persistentでnpm startを実行します。Linux サーバーは
http://<windows-pc>:8787/mcpを指す純粋なクライアントになります。すべての中で最もシンプル — トンネルもスナップショットの手順も不要。
クライアントのオンボーディングはすべてのモードで同じです:クライアントはゲートウェイの MCP URL を指します;ゲートウェイは設定されたブラウザモードと通信します。
立ち上げ手順書 — モード C(Linux ゲートウェイ + Windows ブラウザ)
確認済みのセットアップ:Linux サーバー がゲートウェイを実行;常時稼働の Windows PC が実際の Chrome(一度ログイン)と SSH リバーストンネルを実行します。Linux サーバーにはブラウザはダウンロードされません(playwright-core のみ)。
Windows PC(一度実行し、その後は起動したまま)— windows/README.md を参照
windows\start-browser.ps1→ 専用の Chrome を127.0.0.1:9222で起動、プロファイルC:\dept-search-profile。共有アカウント(SSO/2FA)でサインイン。開いたままにします。$env:GATEWAY_SSH = "linuxuser@gateway.server"; windows\start-tunnel.ps1→ssh -R 9222:127.0.0.1:9222 gatewayを維持、自動再接続。両方をタスクスケジューラ(起動時 / ログオン時、ユーザーのログオン状態に関わらず実行)に設定し、PC を自己修復型ブラウザアプライアンスにします。
Linux ゲートウェイサーバー(このマシン)
cd dept-web-search-gateway
cp .env.example .env
# edit .env:
# BROWSER_MODE=cdp (default)
# CDP_ENDPOINT=http://127.0.0.1:9222 (the tunneled port, local on this server)
# HOST=0.0.0.0
# ALLOWED_HOSTS=search.internal,localhost # hostnames clients will use
# GATEWAY_TOKEN=... (optional; else rely on network ACL)
npm install # lean — playwright-core, no Chromium download
npm run build # typecheck
npm start # dev (tsx); or `npm run build && npm run start:prod`
curl http://127.0.0.1:8787/health # {"ok":true,...}クライアントを http://<this-server>:8787/mcp に向けます(クライアントオンボーディングを参照)。
トンネルの健全性確認
Linux サーバー上で:
curl -s http://127.0.0.1:9222/json/version # Chrome's JSON → tunnel + Chrome are up空 / 接続拒否 → Windows Chrome またはリバーストンネルがまだ実行されていません;web_search は実行されるまで失敗します。
セットアップ(一度だけ)
cd dept-web-search-gateway
npm install # also runs `playwright install chromium`
cp .env.example .env # then edit .env (see knobs below)1) 共有ログインをシードする(核心)
ディスプレイがあるマシン(または xvfb-run -a 下)で一度だけ実行:
npm run login
# or, for an internal portal:
LOGIN_START_URL=https://wiki.internal npm run login実際の Chrome ウィンドウが開きます。共有サービスアカウント(SSO / 2FA)でサインインし、検索エンジン / ポータルにログインしたことを確認してから、ウィンドウを閉じます。セッションは BROWSER_PROFILE_DIR(デフォルト ./.profile)に保存され、今後ヘッドレスゲートウェイによって再利用されます。
サーバーはヘッドレスですか? Windows PC で
npm run login手順を実行し、上記の 「ヘッドレス Linux サーバー + ログイン用 Windows PC」 で説明されているようにモード B(auth.jsonを Linux にコピー)またはモード C(CDP を SSH トンネルで Linux に転送)を選択します。SSO セッションの有効期限が切れた場合の更新:モード A/B →npm run loginを再実行(B の場合はauth.jsonを再コピー);モード C → Windows Chrome で再ログインするだけです。
2) ゲートウェイを実行
npm start # dev (tsx)
# or production:
npm run build && npm run start:prod次のように表示されるはずです:
[server] MCP gateway on http://0.0.0.0:8787/mcp (engine=bing)
[server] profile=./.profileクライアントオンボーディング(これを同僚に渡す)
search.internal / 8787 をゲートウェイのホスト/ポートに置き換えます。全員が同じ URL を使用します。
Chatbox (≥1.14)
設定 → MCP → サーバーを追加 → リモート / URL を選択:
URL:
http://search.internal:8787/mcp(
GATEWAY_TOKENが設定されている場合)クライアントがサポートしていればヘッダーAuthorization: Bearer <TOKEN>を追加;そうでなければネットワーク ACL で保護します。
ワンクリックディープリンク(イントラネットページに配置):
chatbox://mcp/install?server=<base64 of {"name":"websearch","url":"http://search.internal:8787/mcp"}>OpenCode — 3つのフレーバーすべて
opencode.json(プロジェクト)または ~/.config/opencode/opencode.json(グローバル)に追加:
{
"mcp": {
"websearch": {
"type": "remote",
"url": "http://search.internal:8787/mcp",
"enabled": true
}
}
}ローカル opencode:同じスニペット、ホスト =
127.0.0.1またはゲートウェイホスト。サーバー opencode:プロセスはサーバー上で実行 → ゲートウェイの内部 URL を直接指します(サーバーは内部ネットワーク経由で到達可能である必要があります)。
vscode-remote opencode:プロセスはリモートホスト上で実行 → ゲートウェイの内部 URL を指します(そのホストから到達可能)。ゲートウェイが内部ネットワーク上にあるため、トンネリングは不要です。
確認:
opencode mcp list。
Claude Code
claude mcp add --transport http websearch http://search.internal:8787/mcp
# with a token:
claude mcp add --transport http --header "Authorization: Bearer <TOKEN>" \
websearch http://search.internal:8787/mcpCline / Cursor / その他
リモート MCP をサポートしている場合は、同じ URL を指します。stdio のみの場合は、HTTP ゲートウェイを呼び出す小さなローカルシム(20行のラッパー)を実行します — ここには含まれていませんが、追加は簡単です。
公開ツール
ツール | 引数 | 戻り値 |
|
|
|
|
|
|
Chatbox/OpenCode/Claude Code のエージェントは、新しい情報が必要なときに web_search を呼び出し、特定のページを読むために read_webpage を呼び出します — 追加の配線は不要です。
設定ノブ(.env)
変数 | デフォルト | 意味 |
|
| バインドアドレス。 |
| — | クライアントが使用するホスト名のカンマ区切りリスト(Host ヘッダー検証を有効化)。0.0.0.0 にバインドする場合は設定 |
|
| リッスンポート |
| — | 設定されている場合、 |
|
|
|
|
| cdp モード:接続先ブラウザの CDP URL(通常はトンネルされたポート) |
|
| storagestate モード:Windows でエクスポートされ、ここにコピーされたログインスナップショット |
|
| persistent モード:共有ログインを保持する Chrome プロファイル |
|
| デバッグ時のみ |
|
| 同時実行数の上限(1つの Chrome、分離されたタブ) |
|
| ページごとのハードタイムアウト |
|
|
|
| — |
|
|
| クエリあたりの結果数 |
| — | オプションの公開検索フォールバック(アウトバウンドインターネットが必要)(例: |
カスタム内部ポータル抽出器の追加
src/tools.ts の extractBing は Bing の DOM に合わせて調整されています。内部ポータルの場合は、extractPortal(page, count) を追加し、searchWithBrowser 内のエンジン名で選択します。汎用の extractGeneric は、未知の DOM に対するパス可能なフォールバックとして、アンカーリンクと近くのテキストをすでに返します。
セキュリティと運用に関する注意
バインドと公開:ゲートウェイは内部ネットワーク上に保持することを推奨します。
0.0.0.0にバインドする場合は、ALLOWED_HOSTSを設定し、ファイアウォール / ネットワーク ACL を使用するか、GATEWAY_TOKENを設定するか、SSO リバースプロキシの背後に配置します。共有プロファイル = 共有 ID:すべての検索は共有アカウントに帰属します。部門サービスアカウントには問題ありませんが、ターゲットがユーザーごとに監査したりクォータがある場合は確認してください。
セッション更新:SSO の有効期限が切れたら
npm run loginを再実行します。リマインダーをメールで送信する週次 cron、またはログインウォールを検出するヘルスプローブ(read_webpageで既知のログイン必須 URL を呼び出し、ログインページのテキストが返されるか確認)を検討してください。同時実行性 / スケール:1つの Chrome と分離されたタブで小規模な部門を処理できます。飽和する場合は、ブラウザプール(N 個の永続コンテキスト)に拡張します —
withPageの継ぎ目が変更する唯一の場所です。Linux 上のヘッドレス Chrome:
--no-sandbox --disable-dev-shm-usageはすでに設定されています(コンテナフレンドリー)。
開発とテスト
プローブは
scripts/にあり、../dist/からインポートするため、最初にビルドします:npm run build。scripts/probe-search.mjs "<query>"— 共有ブラウザを直接操作します(MCP をバイパス);CDP アタッチと Bing 抽出器を検証します。scripts/probe-mcp.mjs <url> "<query>"— 実行中のゲートウェイに Streamable HTTP 経由で接続し(実際のクライアントパス)、ツールを一覧表示し、web_searchを呼び出します。最初にゲートウェイを起動します:node --env-file=.env dist/server.js。
開発モード(
npm start→ tsx):npm 11 では、tsxの推移的なesbuildの postinstall がデフォルトでallow-scriptsによってブロックされます。一度承認するか(npm approve-scripts)、またはすべての場所でコンパイル済みパスを使用します:npm run build && node --env-file=.env dist/server.js。
ステータス
これはレビュー可能なPoC / スケルトンです — v2 MCP SDK API
(@modelcontextprotocol/server 2.x, createMcpHandler / createMcpExpressApp
/ requireBearerAuth / toNodeHandler) および Playwright の永続コンテキストAPI
に対して検証済みです。本番環境では、依存関係のバージョンを固定し、テストを追加し、信頼できる内部ネットワークの外に公開する場合は認証レイヤーを強化(静的トークンの代わりにJWT / イントロスペクション)してください。
設計コンテキスト(Mode A/B/C トポロジー、OS間のCookie暗号化の落とし穴、 SearXNGの境界)は、上記の「Headless Linux servers + a Windows PC for login」 セクションにあります。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.
Multi-engine search for AI agents. Trust scoring, local corpus, MCP-native. Self-hostable, BYOK.
Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/yangsheng6810/web-search-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server