Department Web-Search MCP Gateway
Department Web-Search MCP Gateway
Ein selbst gehosteter Web-Suchdienst, den die gesamte Abteilung nutzen kann. Er verwendet eine einzelne angemeldete Browsersitzung (einen gemeinsamen Dienst-Account) wieder, sodass Intranet-/SSO-/Zustimmungs-Logins einmalig behandelt werden – jeder Client ruft einfach ein web_search-Tool auf, ohne Login pro Benutzer oder API-Schlüssel.
Jeder MCP-Client verbindet sich mit einer URL:
Chatbox (≥1.14)
OpenCode – lokal, auf einem gemeinsamen Server oder via vscode-remote
Claude Code (und andere Coding-Agenten, die MCP sprechen)
Es ist das T1 „zentralisierte Such-Gateway“ aus den Forschungsnotizen: eine interne Maschine + ein gemeinsames Chrome-Profil + ein HTTP-MCP-Endpunkt.
Wie es funktioniert
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 bedient sowohl MCP-Clients der 2025-Ära als auch der 2026-Ära am selben /mcp-Endpunkt, sodass die Kompatibilität des Client-Transports kein Problem darstellt.
Headless-Linux-Server + ein Windows-PC für den Login
Server haben keine GUI, aber ein Mensch kann sich an einem Windows-PC anmelden. Wählen Sie einen Modus in .env (BROWSER_MODE) – der Code ist identisch, nur die Konfiguration unterscheidet sich.
⚠️ Kopieren Sie KEIN Windows-Chrome-Profil-Verzeichnis nach Linux. Chromium verschlüsselt Cookies mit betriebssystemgebundenen Schlüsseln (DPAPI unter Windows, Keyring/„peanuts“ unter Linux), sodass ein kopiertes Profil den Login stillschweigend verliert. Verwenden Sie einen der unten stehenden betriebssystemübergreifend sicheren Modi.
Modus C – BROWSER_MODE=cdp (empfohlen): Linux-Gateway verbindet sich mit dem Windows-Browser
Windows-PC (bleibt eingeschaltet): Einmal mit dem gemeinsamen Account anmelden, dann Chrome mit einem lokalen Debug-Port laufen lassen:
chrome --remote-debugging-port=9222 --remote-debugging-address=127.0.0.1 ^ --user-data-dir=C:\dept-search-profileTragen Sie diesen Port sicher mit einem SSH-Reverse-Tunnel zum Linux-Server (auf dem Windows-PC ausführen; Win10/11 hat OpenSSH an Bord):
ssh -R 9222:127.0.0.1:9222 linuxuser@gateway.serverLinux-Server:
.env→BROWSER_MODE=cdp,CDP_ENDPOINT=http://127.0.0.1:9222(lokal auf dem Server, zurück zum Windows-Browser getunnelt). Dannnpm start.Der Login bleibt aktiv (Cookies werden aktualisiert, während der Browser verwendet wird); kein Profil-Kopieren; der nicht authentifizierte CDP-Port ist nie im Netzwerk. Nachteil: Windows-PC aus → Suchanfragen schlagen fehl, bis er wieder an ist (verwenden Sie Modus B, falls das nicht akzeptabel ist).
Modus B – BROWSER_MODE=storagestate: Snapshot, Linux autark
Windows-PC:
npm run login(mit GUI), anmelden, Enter drücken → schreibtauth.json(betriebssystemunabhängiges JSON mit Cookies + localStorage).Kopieren Sie
auth.jsonauf den Linux-Server, setzen SieBROWSER_MODE=storagestate,STORAGE_STATE_FILE=./auth.json, führen Sienpm startaus. Linux startet seinen eigenen Headless-Browser, der den Snapshot lädt – kein Tunnel, überlebt, wenn der Windows-PC aus ist.Nachteil: ein eingefrorener Snapshot – erneut exportieren, wenn das SSO-Cookie abläuft; enthält nur Cookies + localStorage (nicht IndexedDB/Client-Zertifikate) – für die meisten SSOs ausreichend.
Modus A – BROWSER_MODE=persistent: Windows-PC führt alles aus
Falls ein freier Windows-PC als ständig laufender Dienst-Host dienen kann:
npm run logindort (legt das Profil an), dannnpm startmitBROWSER_MODE=persistent.Linux-Server sind reine Clients, die auf
http://<windows-pc>:8787/mcpzeigen.Am einfachsten von allen – kein Tunnel, keine Snapshot-Zeremonie.
Das Onboarding der Clients ist in jedem Modus identisch: Clients zeigen auf die MCP-URL des Gateways; das Gateway spricht mit dem konfigurierten Browser-Modus.
Inbetriebnahme-Runbook – Modus C (Linux-Gateway + Windows-Browser)
Das bestätigte Setup: Ein Linux-Server betreibt das Gateway; ein ständig eingeschalteter Windows-PC betreibt einen echten Chrome (einmal angemeldet) und einen SSH-Reverse-Tunnel. Es wird kein Browser auf dem Linux-Server heruntergeladen (nur playwright-core).
Windows-PC (einmalig, dann laufen lassen) – siehe windows/README.md
windows\start-browser.ps1→ dedizierter Chrome auf127.0.0.1:9222, ProfilC:\dept-search-profile. Mit dem gemeinsamen Account anmelden (SSO/2FA). Offen lassen.$env:GATEWAY_SSH = "linuxuser@gateway.server"; windows\start-tunnel.ps1→ hältssh -R 9222:127.0.0.1:9222 gatewayaufrecht, automatische Wiederverbindung.Beide als Geplante Aufgaben einrichten (Beim Start / Bei Anmeldung, ausführen, ob Benutzer angemeldet oder nicht), sodass der PC ein selbstheilendes Browser-Gerät ist.
Linux-Gateway-Server (diese Maschine)
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,...}Weisen Sie Clients auf http://<dieser-server>:8787/mcp (siehe Client-Onboarding).
Tunnel auf Richtigkeit prüfen
Auf dem Linux-Server:
curl -s http://127.0.0.1:9222/json/version # Chrome's JSON → tunnel + Chrome are upLeer / Verbindung abgelehnt → der Windows-Chrome oder der Reverse-Tunnel läuft noch nicht; web_search wird fehlschlagen, bis er läuft.
Einrichtung (einmalig)
cd dept-web-search-gateway
npm install # also runs `playwright install chromium`
cp .env.example .env # then edit .env (see knobs below)1) Gemeinsamen Login einrichten (der Kernpunkt)
Einmalig auf einer Maschine mit Bildschirm (oder unter xvfb-run -a) ausführen:
npm run login
# or, for an internal portal:
LOGIN_START_URL=https://wiki.internal npm run loginEin echtes Chrome-Fenster öffnet sich. Mit dem gemeinsamen Dienst-Account anmelden (SSO / 2FA), bestätigen, dass Sie bei der Suchmaschine / dem Portal angemeldet sind, dann das Fenster schließen. Die Sitzung wird in BROWSER_PROFILE_DIR (Standard ./.profile) gespeichert und von nun an vom Headless-Gateway wiederverwendet.
Server sind headless? Führen Sie den Schritt
npm run loginauf dem Windows-PC aus, wählen Sie dann Modus B (kopieren Sieauth.jsonnach Linux) oder Modus C (SSH-Tunnel CDP nach Linux), wie oben unter „Headless-Linux-Server + ein Windows-PC für den Login“ beschrieben. Erneuerung, wenn die SSO-Sitzung abläuft: Modus A/B →npm run loginerneut ausführen (und für Bauth.jsonerneut kopieren); Modus C → einfach im Windows-Chrome erneut anmelden.
2) Gateway starten
npm start # dev (tsx)
# or production:
npm run build && npm run start:prodSie sollten sehen:
[server] MCP gateway on http://0.0.0.0:8787/mcp (engine=bing)
[server] profile=./.profileClient-Onboarding (diese Informationen an Ihre Kollegen weitergeben)
Ersetzen Sie search.internal / 8787 durch Ihren Gateway-Host/Port. Alle verwenden die gleiche URL.
Chatbox (≥1.14)
Einstellungen → MCP → Server hinzufügen → Remote / URL wählen:
URL:
http://search.internal:8787/mcp(falls
GATEWAY_TOKENgesetzt ist) einen HeaderAuthorization: Bearer <TOKEN>hinzufügen, wo der Client dies unterstützt; andernfalls mit Netzwerk-ACL schützen.
Ein-Klick-Deep-Link (auf Ihre Intranet-Seite setzen):
chatbox://mcp/install?server=<base64 of {"name":"websearch","url":"http://search.internal:8787/mcp"}>OpenCode – alle drei Varianten
Zu opencode.json (Projekt) oder ~/.config/opencode/opencode.json (global) hinzufügen:
{
"mcp": {
"websearch": {
"type": "remote",
"url": "http://search.internal:8787/mcp",
"enabled": true
}
}
}Lokales opencode: gleicher Ausschnitt, Host =
127.0.0.1oder der Gateway-Host.Server opencode: der Prozess läuft auf dem Server → direkt auf die interne URL des Gateways zeigen (der Server muss sie über das interne Netzwerk erreichen können).
vscode-remote opencode: der Prozess läuft auf dem entfernten Host → auf die interne URL des Gateways zeigen (von diesem Host aus erreichbar). Kein Tunnel nötig, da das Gateway im internen Netzwerk ist.
Überprüfen:
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 / andere
Wenn sie Remote-MCP unterstützen, auf die gleiche URL zeigen. Wenn sie nur stdio unterstützen, einen kleinen lokalen Shim ausführen, der das HTTP-Gateway aufruft (ein 20-zeiliger Wrapper) – hier nicht enthalten, aber trivial hinzuzufügen.
Verfügbare Tools
Tool | Argumente | Rückgabe |
|
| Liste von |
|
|
|
Der Agent in Chatbox/OpenCode/Claude Code wird web_search aufrufen, wenn er aktuelle Informationen benötigt, und read_webpage, um eine bestimmte Seite zu lesen – keine zusätzliche Verkabelung nötig.
Konfigurationsoptionen (.env)
Variable | Standard | Bedeutung |
|
| Bind-Adresse. |
| — | Komma-getrennte Liste von Hostnamen, die Clients verwenden (ermöglicht Host-Header-Validierung). Setzen, wenn 0.0.0.0 gebunden wird |
|
| Lauschport |
| — | Falls gesetzt, |
|
|
|
|
| CDP-Modus: die CDP-URL des angehängten Browsers (normalerweise ein getunnelter Port) |
|
| Storagestate-Modus: auf Windows exportierter Login-Snapshot, hierher kopiert |
|
| Persistent-Modus: Chrome-Profil, das den gemeinsamen Login enthält |
|
|
|
|
| Parallelitätsgrenze (ein Chrome, isolierte Tabs) |
|
| Hartes Timeout pro Seite |
|
|
|
| — | Benutzerdefinierte URL mit |
|
| Ergebnisse pro Abfrage |
| — | Optionaler öffentlicher Such-Fallback (benötigt ausgehenden Internetzugang), z.B. |
Hinzufügen eines benutzerdefinierten Extractors für ein internes Portal
extractBing in src/tools.ts ist auf Bings DOM abgestimmt. Für ein internes Portal fügen Sie extractPortal(page, count) hinzu und wählen es über den Engine-Namen in searchWithBrowser aus. Der generische extractGeneric gibt bereits Anker-Links + umgebenden Text als brauchbaren Fallback für unbekannte DOMs zurück.
Sicherheits- & Betriebshinweise
Binden & freigeben: Bevorzugen Sie, das Gateway im internen Netzwerk zu belassen. Wenn Sie
0.0.0.0binden, setzen SieALLOWED_HOSTSund verwenden Sie eine Firewall / Netzwerk-ACL, oder setzen SieGATEWAY_TOKEN, oder stellen Sie es hinter einen SSO-Reverse-Proxy.Gemeinsames Profil = gemeinsame Identität: Jede Suche wird dem gemeinsamen Account zugeschrieben. Für einen Abteilungs-Dienst-Account in Ordnung; prüfen Sie, ob das Ziel pro Benutzer prüft oder ein Kontingent hat.
Sitzungsverlängerung: Führen Sie
npm run loginerneut aus, wenn das SSO abläuft. Erwägen Sie einen wöchentlichen Cron-Job, der eine Erinnerung per E-Mail sendet, oder eine Health-Probe, die eine Login-Wand erkennt (read_webpageauf einer bekannten Login-erforderlichen URL gibt den Text der Login-Seite zurück).Parallelität / Skalierung: Ein Chrome mit isolierten Tabs bewältigt eine kleine Abteilung. Wachsen Sie zu einem Browser-Pool (N persistente Kontexte), wenn es gesättigt ist – die
withPage-Nahtstelle ist der einzige Ort, der geändert werden muss.Headless Chrome unter Linux:
--no-sandbox --disable-dev-shm-usagesind bereits gesetzt (containerfreundlich).
Entwicklung & Testen
Probes befinden sich in
scripts/und importieren aus../dist/, also zuerst bauen:npm run build.scripts/probe-search.mjs "<Abfrage>"– treibt den gemeinsamen Browser direkt an (umgeht MCP); validiert CDP-Attach + den Bing-Extractor.scripts/probe-mcp.mjs <url> "<Abfrage>"– verbindet sich mit einem laufenden Gateway über Streamable HTTP (der echte Client-Pfad), listet Tools auf, ruftweb_searchauf. Starten Sie zuerst das Gateway:node --env-file=.env dist/server.js.
Dev-Modus (
npm start→ tsx): Unter npm 11 wird das transitiveesbuild-Postinstall vontsxstandardmäßig durchallow-scriptsblockiert. Einmal genehmigen (npm approve-scripts) oder einfach den kompilierten Pfad überall verwenden:npm run build && node --env-file=.env dist/server.js.
Status
Hierbei handelt es sich um ein überprüfbares PoC / Skelett — abgestimmt auf die v2 MCP SDK API
(@modelcontextprotocol/server 2.x, createMcpHandler / createMcpExpressApp
/ requireBearerAuth / toNodeHandler) und Playwrights persistent-context
API. Vor dem Produktionseinsatz: exakte Abhängigkeitsversionen festlegen, Tests hinzufügen und die
Authentifizierungsschicht (JWT / Introspection anstelle eines statischen Tokens) absichern, falls Sie sie
über ein vertrauenswürdiges internes Netzwerk hinaus freigeben.
Der Designkontext (Mode A/B/C-Topologien, die betriebssystemübergreifende Cookie-Verschlüsselungsfalle, SearXNG-Grenzen) befindet sich im obigen Abschnitt „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