Department Web-Search MCP Gateway
MCP-шлюз веб-поиска отдела
Самодостаточный веб-поисковый сервис, которым может пользоваться весь отдел. Он использует один сеанс браузера с выполненным входом (общая служебная учётная запись), поэтому вход в интранет / SSO / страницы с согласием обрабатывается один раз — каждый клиент просто вызывает инструмент web_search, без отдельного входа или API-ключа.
Любой MCP-клиент подключается к одному URL:
Chatbox (≥1.14)
OpenCode — локально, на общем сервере или через vscode-remote
Claude Code (и другие агенты программирования, поддерживающие MCP)
Это T1 «централизованный поисковый шлюз» из исследовательских заметок: одна внутренняя машина + один общий профиль Chrome + одна 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, поэтому совместимость транспортного протокола клиента не имеет значения.
Серверы без графического интерфейса + ПК с Windows для входа
На серверах нет графического интерфейса, но человек может войти на ПК с Windows. Выберите режим в .env (BROWSER_MODE) — код одинаков, отличается только конфигурация.
⚠️ НЕ копируйте каталог профиля Windows Chrome на Linux. Chromium шифрует файлы cookie с помощью ключей, привязанных к ОС (DPAPI в Windows, keyring/«peanuts» в Linux), поэтому скопированный профиль незаметно теряет файлы cookie. Используйте один из безопасных для разных ОС режимов ниже.
Режим C — BROWSER_MODE=cdp (рекомендуется): шлюз Linux подключается к браузеру Windows
ПК с Windows (остаётся включённым): войдите один раз с общей учётной записью, затем оставьте Chrome запущенным с локальным отладочным портом:
chrome --remote-debugging-port=9222 --remote-debugging-address=127.0.0.1 ^
--user-data-dir=C:\dept-search-profileПередайте этот порт на сервер Linux безопасно с помощью обратного SSH-туннеля (запускается на ПК с Windows; в Win10/11 встроен OpenSSH):
ssh -R 9222:127.0.0.1:9222 linuxuser@gateway.serverСервер Linux:
.env→BROWSER_MODE=cdp,CDP_ENDPOINT=http://127.0.0.1:9222(локально на сервере, туннелирован обратно в браузер Windows). Затемnpm start.Сеанс остаётся активным (файлы cookie обновляются при использовании браузера); копирование профиля не требуется; неаутентифицированный порт CDP никогда не находится в сети. Недостаток: если ПК с Windows выключен — поиск не работает, пока он не включится (используйте Режим B, если это неприемлемо).
Режим B — BROWSER_MODE=storagestate: снимок, Linux самодостаточен
ПК с Windows:
npm run login(с графическим интерфейсом), войдите, нажмите Enter → записываетсяauth.json(независимый от ОС JSON с файлами cookie + localStorage).Скопируйте
auth.jsonна сервер Linux, установитеBROWSER_MODE=storagestate,STORAGE_STATE_FILE=./auth.json, запуститеnpm start. Linux запускает собственный безголовый браузер, загружающий снимок — без туннеля, работает даже при выключенном ПК с Windows.Компромисс: замороженный снимок — повторно экспортируйте, когда истечёт срок действия SSO-куки; содержит только файлы cookie + localStorage (не IndexedDB/клиентские сертификаты) — подходит для большинства SSO.
Режим A — BROWSER_MODE=persistent: ПК с Windows запускает всё
Если есть запасной ПК с Windows, который может быть постоянно включённым хостом сервиса: выполните
npm run loginна нём (создаётся профиль), затемnpm startсBROWSER_MODE=persistent.Серверы Linux — это просто клиенты, указывающие на
http://<windows-pc>:8787/mcp.Самый простой вариант — без туннеля, без церемоний со снимками.
Подключение клиента одинаково во всех режимах: клиенты указывают на URL MCP-шлюза; шлюз взаимодействует с выбранным режимом браузера.
Инструкция по запуску — Режим C (шлюз Linux + браузер Windows)
Подтверждённая настройка: сервер Linux запускает шлюз; постоянно включённый ПК с Windows запускает настоящий Chrome (один раз выполнен вход) и обратный SSH-туннель. Браузер не загружается на сервер Linux (только playwright-core).
ПК с Windows (один раз, затем оставить работающим) — см. 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, автоматически переподключается.Сделайте оба запланированными задачами (При запуске / При входе в систему, выполнять независимо от того, выполнен ли вход пользователя), чтобы ПК был самовосстанавливающимся браузерным устройством.
Сервер шлюза 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Пусто / соединение отклонено → Chrome на Windows или обратный туннель ещё не запущены; 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) и будет использоваться безголовым шлюзом в дальнейшем.
Серверы без графического интерфейса? Выполните шаг
npm run loginна ПК с Windows, затем выберите Режим B (скопируйтеauth.jsonна Linux) или Режим C (SSH-туннель CDP на Linux), как описано в разделе «Серверы без графического интерфейса + ПК с Windows для входа» выше. Обновление при истечении сеанса SSO: Режим A/B → повторно запуститеnpm run login(и повторно скопируйтеauth.jsonдля B); Режим C → просто повторно войдите в Chrome на Windows.
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 — все три варианта
Добавьте в 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: URL CDP подключённого браузера (обычно туннелированный порт) |
|
| режим storagestate: снимок входа, экспортированный на Windows, скопирован сюда |
|
| режим persistent: профиль Chrome, хранящий общий сеанс входа |
|
|
|
|
| ограничение параллельности (один Chrome, изолированные вкладки) |
|
| жёсткий таймаут на страницу |
|
|
|
| — | пользовательский URL с плейсхолдером |
|
| результатов на запрос |
| — | дополнительный запасной публичный поиск (требует исходящий интернет), например |
Добавление пользовательского извлекателя для внутреннего портала
extractBing в src/tools.ts настроен на DOM Bing. Для внутреннего портала добавьте extractPortal(page, count) и выберите его по имени движка в searchWithBrowser. Универсальный extractGeneric уже возвращает ссылки на якоря + близлежащий текст как приемлемый запасной вариант для неизвестных DOM.
Заметки по безопасности и эксплуатации
Привязка и доступ: предпочтительно оставлять шлюз во внутренней сети. Если вы привязываетесь к
0.0.0.0, установитеALLOWED_HOSTSи используйте брандмауэр / сетевой ACL, или установитеGATEWAY_TOKEN, или поместите за обратный прокси с SSO.Общий профиль = общая идентичность: каждый поиск приписывается общей учётной записи. Нормально для служебной учётной записи отдела; проверьте, если целевая система отслеживает пользователей или имеет квоту.
Обновление сеанса: повторно запустите
npm run login, когда истечёт SSO. Рассмотрите еженедельный cron, отправляющий напоминание по электронной почте, или проверку работоспособности, которая обнаруживает страницу входа (read_webpageна известном URL, требующем входа, возвращает текст страницы входа).Параллельность / масштабирование: один Chrome с изолированными вкладками справляется с небольшим отделом. Для увеличения масштаба используйте пул браузеров (N постоянных контекстов), если он насыщается — место для изменения — это только
withPage.Безголовый Chrome на Linux:
--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 транзитивныйesbuildотtsxблокируетсяallow-scriptsпо умолчанию. Разрешите один раз (npm approve-scripts) или используйте скомпилированный путь везде:npm run build && node --env-file=.env dist/server.js.
Статус
Это обозреваемый PoC / скелет — проверенный на соответствие API v2 MCP SDK
(@modelcontextprotocol/server 2.x, createMcpHandler / createMcpExpressApp
/ requireBearerAuth / toNodeHandler) и API постоянного контекста Playwright.
Перед производством: зафиксируйте точные версии зависимостей, добавьте тесты и
укрепите уровень аутентификации (JWT / интроспекция вместо статического токена),
если вы выставляете его за пределы доверенной внутренней сети.
Дизайн-контекст (топологии режимов A/B/C, межплатформенная проблема шифрования cookie, границы SearXNG) находится в разделе «Безголовые серверы Linux + ПК с Windows для входа» выше.
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