WebVector MCP Server
WebVector
Дайте вашему ИИ-агенту настоящий веб-поиск одним вызовом инструмента: поиск → чтение полных страниц → ранжирование → цитируемые отрывки.
Поисковые инструменты передают модели заголовки и сниппеты по 150 символов, поэтому она додумывает остальное. Инструменты загрузки передают ей 40 КБ навигации и шаблонного кода, и она тонет. WebVector выполняет всю работу посередине: запускает поиск, загружает и очищает каждый результат (HTML, PDF, Markdown), разбивает его на отрывки, ранжирует эти отрывки по отношению к вопросу — семантически, когда доступна модель эмбеддингов, лексически (BM25), когда нет — и возвращает только те отрывки, которые отвечают на запрос, каждый со своим URL, заголовком, смещениями и оценкой.
Работает без API-ключей и без загрузки моделей: DuckDuckGo + BM25, установка ~12 МБ.
Подключайте любой поисковый бэкенд, провайдера эмбеддингов, векторное хранилище или реранкер (или напишите свой в одном файле).
Поставляется как библиотека, MCP-сервер (Claude Code, Claude Desktop, Cursor, Windsurf, …) и CLI.
Вежливый и безопасный по умолчанию: robots.txt, ограничение частоты запросов на хост, защита от SSRF, лимиты размера/редиректов/времени, без телеметрии.
npx -y webvector-cli search "what changed in the MCP spec in 2026?"# Web research: what changed in the MCP spec in 2026?
**[1]** Streamable HTTP — Model Context Protocol — <https://modelcontextprotocol.io/specification/2026-07-28/…> (score 1.00)
> ### Earlier Streamable HTTP Revisions
> Protocol versions 2025-03-26 through 2025-11-25 also used the Streamable HTTP transport, but in a
> different shape: servers could assign a session via the Mcp-Session-Id header … None of these
> mechanisms are part of this revision.
…
## Sources
- Streamable HTTP — Model Context Protocol — <https://…> [1]Оглавление
Требования: Node.js ≥ 22.12 (рекомендуется Node 24). macOS, Linux и Windows.
1. Попробуйте за 30 секунд
Без установки, без ключей:
npx -y webvector-cli search "how does reciprocal rank fusion work" --statsВы увидите отрывки, а затем строку статистики вроде search duckduckgo 957ms · pages 4/5 908ms · embed 0 chunks (none/bm25) · retrieve 10ms · total 1879ms. embed … none/bm25 означает, что вы в лексическом режиме (см. §5) — семантический режим включается автоматически, как только появляется среда выполнения модели или API-ключ для эмбеддингов.
Проверьте, что будет использовать ваша машина:
npx -y webvector-cli doctor2. Использование в качестве MCP-сервера
MCP-сервер предоставляет четыре инструмента — web_research (основной), web_fetch, web_search, webvector_status — любому MCP-клиенту.
Claude Code
claude mcp add webvector -- npx -y webvector-mcpClaude Desktop / Cursor / Windsurf / VS Code — добавьте в ваш MCP-конфиг (claude_desktop_config.json, ~/.cursor/mcp.json, …):
{
"mcpServers": {
"webvector": {
"command": "npx",
"args": ["-y", "webvector-mcp"],
"env": { "BRAVE_API_KEY": "optional — see §7" }
}
}
}Это лексический уровень. Для семантического поиска на устройстве установите рядом среду выполнения модели:
"args": ["-y", "-p", "@huggingface/transformers", "-p", "webvector-mcp", "webvector-mcp"]…или просто поместите ключ эмбеддингов в env (OPENAI_API_KEY, VOYAGE_API_KEY, GEMINI_API_KEY, COHERE_API_KEY) — и он обновится сам.
По HTTP (для агентных фреймворков): npx -y webvector-mcp --http --port 3333 → http://127.0.0.1:3333/mcp (Streamable HTTP, только localhost). Добавьте --token <secret> (или WEBVECTOR_MCP_TOKEN), чтобы требовать Authorization: Bearer <secret>; привязка к любому другому адресу требует --host 0.0.0.0 --allow-remote --token … и должна находиться за TLS/собственной аутентификацией. GET /health для проверки живости.
Каждый результат web_research возвращается и в виде компактного Markdown (для модели), и в виде structuredContent (для вашего приложения), с уведомлениями о ходе выполнения во время работы.
3. Использование в качестве библиотеки
npm i webvectorimport { WebVector } from 'webvector';
const wv = new WebVector(); // zero-config
const res = await wv.research('what is reciprocal rank fusion');
console.log(res.markdown); // ready to drop into a prompt
for (const p of res.passages) console.log(p.score, p.citation); // "[1] Title — https://…"
await wv.close();Настройка через передаваемые параметры (полный список см. в §6):
const wv = new WebVector({
search: { provider: 'brave' }, // reads BRAVE_API_KEY
embeddings: { provider: 'openai', model: 'text-embedding-3-small' },
retrieval: { topK: 8, rerank: 'cohere' },
store: { mode: 'session' }, // reuse pages across calls
});
const res = await wv.research('How does Node 24 handle AbortSignal.any?', {
relatedQueries: ['AbortSignal.any example'], // extra angles (also searched)
freshness: 'year', // day | week | month | year
domainsAllow: ['nodejs.org', 'developer.mozilla.org'],
sessionId: 'conversation-42', // pages already read this session are reused
onProgress: (p) => console.error(p.stage, p.message),
});Другие вызовы: wv.search(query) (только результаты), wv.fetch(url) (одна страница → Markdown), wv.fetchAndRetrieve(url, query) (одна страница → релевантные отрывки), wv.listSessions(), wv.clearSession(id).
Передайте его модели как инструмент — привязки для популярных SDK находятся в одном импорте:
// Vercel AI SDK
import { generateText, isStepCount } from 'ai';
import { webVectorTools } from 'webvector/ai-sdk';
await generateText({ model, tools: await webVectorTools(wv), stopWhen: isStepCount(5), prompt });
// Anthropic Messages API // OpenAI Responses API // LangChain.js
import { anthropicTools, runAnthropicTool } from 'webvector/anthropic';
import { openaiTools, runOpenAITool } from 'webvector/openai';
import { langchainTools } from 'webvector/langchain';
// Anything else: plain JSON Schema
import { webResearchToolDefinition } from 'webvector';Рабочие версии каждого примера находятся в examples/.
4. Использование из командной строки
npm i -g webvector-cli # or keep using npx -y webvector-cli …
webvector search "query" [-k 8] [-p 12] [--provider brave] [--embeddings openai] [--rerank local] [--json|--md] [--stats]
webvector fetch <url> [--query "…"] # one page as Markdown, or just the passages relevant to --query
webvector serp "query" # search results only
webvector doctor [--live] # config, dependencies, provider connectivity, active tier
webvector init # writes webvector.config.yaml + .env.example
webvector config # print resolved config (secrets redacted)
webvector providers # every provider and the env var it reads
webvector mcp [--http] # run the MCP server5. Два уровня: лексический и семантический
Одна ручка — embeddings.provider, по умолчанию auto — определяет, как ранжируются отрывки:
Уровень | Установка | Ранжирование | Выбирается, когда |
Лексический ( | ~12 МБ, без загрузок | BM25 по всем загруженным страницам + расширение запроса + разнообразие по источникам | Нет среды выполнения модели и нет ключа эмбеддингов (обычный путь |
Семантический ( | + | Гибрид: векторы + BM25, объединённые через RRF, разнообразие MMR, опциональный реранкер | Автоматически, как только доступно что-либо из этого |
Обновитесь в любой момент: npm i @huggingface/transformers рядом с пакетом или задайте ключ. webvector doctor показывает, какой уровень активен. Лексический режим — это поддерживаемый режим, а не запасной: результаты помечаются как stats.embed.provider: 'none' и не считаются «ухудшенными».
6. Конфигурация
Приоритет: код → файл конфигурации → переменные окружения → значения по умолчанию. Файлы конфигурации: webvector.config.{ts,js,mjs,json,yaml,yml}, .webvectorrc или ключ webvector в package.json; поиск выполняется подъёмом от рабочего каталога. ${VAR} / ${VAR:-default} внутри значений заполняются из окружения.
webvector init создаёт заготовку с комментариями; вот параметры, которые люди действительно меняют:
search:
provider: duckduckgo # duckduckgo | brave | serper | serpapi | google-cse | searxng | tavily | tavily-keyless | exa | perplexity | wikipedia
fallbackProviders: [tavily-keyless, wikipedia]
resultsPerQuery: 10
embeddings:
provider: auto # auto | none | local | openai | openai-compatible | gemini | voyage | cohere | mistral | jina | ollama
model: Xenova/all-MiniLM-L6-v2 # local aliases: minilm (fast) | granite (quality) | embeddinggemma (best) | bge-small | nomic …
store:
provider: memory # memory | chroma | qdrant | pgvector
mode: ephemeral # ephemeral (per call) | session (reuse by sessionId, TTL) | persistent (external store)
retrieval:
topK: 12
hybrid: true # BM25 + vectors fused with RRF (semantic tier)
queryExpansion: true # heuristic (no LLM); pass retrieval.llm in code for LLM multi-query
maxPerSource: 3
mmr: true
rerank: false # local | cohere | voyage | jina | llm
ingestion:
maxPages: 10
maxConcurrentFetches: 8
timeoutMs: 15000
totalDeadlineMs: 45000
respectRobotsTxt: true
chunkSize: 480 # tokens
output:
markdown: true
maxPassageChars: 1500
logging:
level: warnЭквиваленты в переменных окружения: WEBVECTOR_SEARCH_PROVIDER, WEBVECTOR_EMBEDDINGS_PROVIDER, WEBVECTOR_EMBEDDINGS_MODEL, WEBVECTOR_STORE_PROVIDER, WEBVECTOR_STORE_MODE, WEBVECTOR_TOP_K, WEBVECTOR_MAX_PAGES, WEBVECTOR_LOG_LEVEL, WEBVECTOR_MODEL_CACHE, а также ключи провайдеров ниже. Каждая опция со значением по умолчанию: docs/CONFIGURATION.md.
7. Провайдеры
Задайте переменную окружения, укажите провайдера — готово. Подробности и подводные камни по каждому провайдеру: docs/PROVIDERS.md.
Поиск | env | Эмбеддинги | env | Хранилища / Реранкеры | env |
| — |
| — |
| — |
|
|
| — |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| реранк | — |
|
|
|
| реранк |
|
|
|
|
| реранк |
|
|
|
|
| реранк |
|
| — | любая модель Vercel AI SDK | — | реранк | — |
Если основной поисковый провайдер выходит из строя или срабатывает ограничение частоты запросов, автоматически перебирается цепочка fallbackProviders, и каждая попытка записывается в stats.search.attempts.
8. Что вы получаете в ответ
interface ResearchResult {
query: string; queries: string[]; // the query + expansions actually used
passages: Passage[]; // ranked; each: text, url, title, score (0–1), cosine?, bm25?,
// rerankScore?, chunkIndex, startOffset, endOffset, publishedAt?,
// fetchedAt, matchedQueries, citation "[n] Title — url"
sources: SourceSummary[]; // one per page: status ok|failed|cached, chunks, bestScore, passageIndices, failure?
failures: Failure[]; // per-URL / per-stage problems with machine codes (never thrown)
stats: { search, ingest, embed, retrieve, totalMs, warnings }; // timings + counts per stage
markdown?: string; // the pre-rendered version above
degraded?: 'search_only' | 'partial'; // e.g. every fetch failed → search snippets returned instead
}9. Ошибки и сбои
Два вида, намеренно разделённых:
Сбои происходят на уровне страницы и никогда не прерывают выполнение:
FETCH_TIMEOUT,FETCH_HTTP_ERROR,FETCH_BLOCKED_ROBOTS,FETCH_BLOCKED_SSRF,FETCH_TOO_LARGE,TOO_MANY_REDIRECTS,UNSUPPORTED_CONTENT_TYPE,PARSE_EMPTY,PARSE_FAILED. Они попадают вresult.failures[]иsources[].failure. Если все страницы завершились сбоем, вы всё равно получаете поисковые сниппеты (degraded: 'search_only',ALL_FETCHES_FAILED).Ошибки выбрасываются как
WebVectorErrorс полямиcode,message,remediation,retryable,provider,stageиtoJSON(); секреты маскируются. Примеры:MISSING_API_KEY(«Задайте BRAVE_API_KEY … или используйте провайдера без ключа: duckduckgo»),MISSING_DEPENDENCY(«npm i @huggingface/transformers — или embeddings.provider: 'none'»),SEARCH_BLOCKED,PROVIDER_RATE_LIMITED(сretryAfterMs),EMBEDDING_DIMENSION_MISMATCH(называет обе модели; предлагаетstore.clear()или новую коллекцию),INVALID_CONFIG.
10. Безопасность и этикет
WebVector загружает URL-адреса, выбранные поисковой системой, — то есть контент, на который может влиять злоумышленник, — поэтому загрузчик по умолчанию защищён:
Защита SSRF: цели в приватных, loopback, link-local, CGNAT, multicast, зарезервированных диапазонах, IPv4-mapped-IPv6 и
localhost/*.internalотклоняются; ответы DNS проверяются и каждый переход редиректа перепроверяется. Отключить можно только для доверенных локальных конфигураций (ingestion.allowPrivateNetworks).Лимиты на редиректы (5), размер ответа (5 МБ), время запроса (15 с) и общий дедлайн всего запуска (45 с); ограниченная конкурентность глобально и на каждый хост.
Этикет: соблюдается robots.txt (включая
Crawl-delay), идентифицируемый User-Agent, минимальный интервал между запросами к хосту, учитываетсяRetry-After.Разбор без исполнения: HTML разбирается с помощью linkedom (без скриптов и загрузки подресурсов), PDF — с помощью pdf.js в режиме no-eval; вызывающий код всегда получает только Markdown/простой текст с вырезанными управляющими символами.
Секреты: читаются из окружения/конфигурации, никогда не попадают в логи; маскируются в ошибках, в
webvector configи в MCP-инструментеwebvector_status. На диск ничего не записывается, если вы не включите каталог кэша страниц.Никакой телеметрии. Вообще.
MCP over HTTP привязывается только к
127.0.0.1, проверяетHost/Origin(защита от DNS-rebind), поддерживает bearer token и отказывается привязываться к другому адресу без--allow-remoteи токена.DNS-rebinding закрывается при подключении: проверка SSRF выполняется внутри DNS-запроса, используемого для открытия сокета, поэтому проверяется именно тот адрес, к которому происходит подключение.
Примечание про DuckDuckGo: провайдер без ключа обращается к публичным HTML-эндпойнтам DuckDuckGo с браузероподобным User-Agent (официальный API отсутствует). Этот провайдер по своей сути ограничен по частоте и хрупок; при интенсивном или коммерческом использовании стоит перейти на провайдера с ключом (
brave,serper,tavily). Загрузка страниц всегда использует честный User-AgentWebVector/….
Нашли что-то? Пожалуйста, откройте приватный security advisory на GitHub, а не публичный issue.
11. Запуск из исходников (локальная разработка)
git clone https://github.com/rthomas24/web-vector
cd webvector
npm install # installs all workspaces (~1 min; includes the optional model runtime for tests)
npm run build # tsdown → packages/*/dist
# use the local build
node packages/cli/dist/cli.js search "reciprocal rank fusion" --stats
node packages/mcp/dist/bin.js # MCP server on stdio
node packages/mcp/dist/bin.js --http --port 3333 # …or HTTP
# point an MCP client at the local build
claude mcp add webvector-dev -- node /absolute/path/to/webvector/packages/mcp/dist/bin.js
# quality gates
npm test # unit tests, offline (mocked HTTP), ~5 s
npm run test:live # real network + local model + MCP stdio round-trip (~20 s)
npm run lint # biome
npm run typecheck # TypeScript 7Структура репозитория и куда добавлять код: docs/ARCHITECTURE.md.
Чтобы использовать локальную сборку в другом проекте без публикации: выполните npm pack в packages/core (и mcp/cli) и затем npm i ./webvector-0.1.0.tgz там, либо npm link.
12. Создание собственного адаптера
Каждый тип провайдера — это небольшой интерфейс в packages/core/src/types.ts — SearchProvider, EmbeddingProvider, VectorStore, ContentParser, Reranker. Реализуйте его, а затем либо передайте экземпляр в конфигурации, либо зарегистрируйте имя, чтобы файлы конфигурации могли использовать его:
import { customSearchProvider, registerSearchProvider, WebVector } from 'webvector';
const myIndex = customSearchProvider('my-index', async (query) => [
{ url: 'https://…', title: '…', snippet: '…' },
]);
new WebVector({ search: { instance: myIndex } });
// or: registerSearchProvider('my-index', (opts) => new MyProvider(opts)); → search.provider: my-indexwebvector/testing экспортирует конформные проверки (searchProviderConformance, embeddingProviderConformance, vectorStoreConformance), которые можно подключить в любой тестовый раннер.
13. Как это работает
research(query)
1. search provider chain (DuckDuckGo → fallbacks) → dedupe by canonical URL → domain filters → top N
2. ingest concurrent, polite fetch → HTML (Readability→Markdown) | PDF | text → page cache
3. chunk+embed markdown-aware recursive chunks with heading breadcrumbs → content-hash dedupe → embed (batched, cached)
4. retrieve query + expansions → vector top-k lists + BM25 top-k lists → weighted RRF → cosine cutoffs
→ near-duplicate removal → per-source cap → MMR → optional rerank → top-k
5. format passages with citations, sources, failures, per-stage stats, MarkdownТипичный запуск на ноутбуке: поиск ~1 с, 8 страниц загружены и разобраны ~1–2,5 с, извлечение < 50 мс → ~2 с лексический (lexical) / ~4 с семантический (semantic).
14. Дорожная карта
Хранилища LanceDB и Pinecone * адаптер headless-браузера для страниц, отрисованных JS-омлекционное извлечение (с обобщённым LLM контекстом фрагментов) как опциональная функция * отдельный бинарный файл без требования к установленному Node * Python-пакет, распространяющий фикстуры конформ- проверок.
Лицензия
MIT © Ryan Thomas
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
Web research for agents: quality-scored Google search, webpage extraction, and deep research.
LLM-ready web search + instant answers + URL-to-clean-text fetch for agents and RAG.
The best web search for your AI Agent
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/rthomas24/web-vector'
If you have feedback or need assistance with the MCP directory API, please join our Discord server