WebVector MCP Server
WebVector
Geben Sie Ihrem KI-Agenten echte Web-Recherche in einem einzigen Tool-Aufruf: suchen → die vollständigen Seiten lesen → ranken → zitierte Passagen.
Such-Tools geben einem Modell Titel und 150-Zeichen-Ausschnitte, sodass es den Rest errät. Fetch-Tools geben ihm 40 KB Navigation und Boilerplate, sodass es darin ertrinkt. WebVector erledigt die ganze Arbeit dazwischen: die Suche ausführen, jedes Ergebnis herunterladen und bereinigen (HTML, PDF, Markdown), in Passagen aufteilen, diese Passagen gegen die Frage ranken – semantisch, wenn ein Embedding-Modell verfügbar ist, lexikalisch (BM25), wenn nicht – und nur die Passagen zurückgeben, die die Anfrage beantworten, jeweils mit URL, Titel, Offsets und Score.
Funktioniert ohne API-Schlüssel und ohne Modell-Download: DuckDuckGo + BM25, ~12 MB Installation.
Schließen Sie jede Such-Backend, jeden Embedding-Anbieter, jeden Vektor-Store oder Reranker an (oder schreiben Sie Ihren eigenen in einer Datei).
Erhältlich als Bibliothek, MCP-Server (Claude Code, Claude Desktop, Cursor, Windsurf, …) und CLI.
Höflich und sicher standardmäßig: robots.txt, Raten-Limits pro Host, SSRF-Schutz, Größen-/Redirect-/Zeitlimits, keine Telemetrie.
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]Inhaltsverzeichnis
Anforderungen: Node.js ≥ 22.12 (Node 24 empfohlen). macOS, Linux und Windows.
Related MCP server: MyWebSearch MCP
1. In 30 Sekunden ausprobieren
Keine Installation, keine Schlüssel:
npx -y webvector-cli search "how does reciprocal rank fusion work" --statsSie sehen die Passagen, dann eine Statistikzeile wie search duckduckgo 957ms · pages 4/5 908ms · embed 0 chunks (none/bm25) · retrieve 10ms · total 1879ms. embed … none/bm25 bedeutet, dass Sie sich in der lexikalischen Stufe befinden (siehe §5) – die semantische Stufe schaltet sich automatisch ein, sobald eine Modell-Laufzeit oder ein Embedding-API-Schlüssel vorhanden ist.
Prüfen Sie, was Ihre Maschine verwenden wird:
npx -y webvector-cli doctor2. Als MCP-Server verwenden
Der MCP-Server stellt vier Tools bereit – web_research (das Haupttool), web_fetch, web_search, webvector_status – für jeden MCP-Client.
Claude Code
claude mcp add webvector -- npx -y webvector-mcpClaude Desktop / Cursor / Windsurf / VS Code – fügen Sie es zu Ihrer MCP-Konfiguration hinzu (claude_desktop_config.json, ~/.cursor/mcp.json, …):
{
"mcpServers": {
"webvector": {
"command": "npx",
"args": ["-y", "webvector-mcp"],
"env": { "BRAVE_API_KEY": "optional — see §7" }
}
}
}Das ist die lexikalische Stufe. Für semantische Suche auf dem Gerät installieren Sie die Modell-Laufzeit daneben:
"args": ["-y", "-p", "@huggingface/transformers", "-p", "webvector-mcp", "webvector-mcp"]…oder setzen Sie einfach einen Embedding-Schlüssel in env (OPENAI_API_KEY, VOYAGE_API_KEY, GEMINI_API_KEY, COHERE_API_KEY) und es aktualisiert sich selbst.
Über HTTP (für Agent-Frameworks): npx -y webvector-mcp --http --port 3333 → http://127.0.0.1:3333/mcp (Streamable HTTP, nur localhost). Fügen Sie --token <secret> (oder WEBVECTOR_MCP_TOKEN) hinzu, um Authorization: Bearer <secret> zu verlangen; das Binden an eine andere Adresse erfordert --host 0.0.0.0 --allow-remote --token … und gehört hinter TLS/Ihre eigene Authentifizierung. GET /health für Liveness.
Jedes web_research-Ergebnis kommt sowohl als kompaktes Markdown (für das Modell) als auch als structuredContent (für Ihre App) zurück, mit Fortschrittsbenachrichtigungen während des Laufs.
3. Als Bibliothek verwenden
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();Konfigurieren Sie durch Übergabe von Optionen (siehe §6 für die vollständige Liste):
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),
});Andere Aufrufe: wv.search(query) (nur Ergebnisse), wv.fetch(url) (eine Seite → Markdown), wv.fetchAndRetrieve(url, query) (eine Seite → relevante Passagen), wv.listSessions(), wv.clearSession(id).
Geben Sie es einem Modell als Tool – Bindings für die gängigen SDKs sind einen Import entfernt:
// 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';Lauffähige Versionen von jedem finden Sie in examples/.
4. Von der Kommandozeile aus verwenden
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. Die zwei Stufen: lexikalisch vs. semantisch
Ein Regler – embeddings.provider, Standard auto – entscheidet, wie Passagen gerankt werden:
Stufe | Installation | Ranking | Gewählt, wenn |
Lexikalisch ( | ~12 MB, keine Downloads | BM25 über die vollständig abgerufenen Seiten + Query-Erweiterung + Diversität pro Quelle | Keine Modell-Laufzeit und kein Embedding-Schlüssel vorhanden (der einfache |
Semantisch ( | + | Hybrid: Vektoren + BM25 fusioniert mit RRF, MMR-Diversität, optionaler Reranker | Automatisch, sobald eines von beiden verfügbar ist |
Jederzeit upgraden: npm i @huggingface/transformers neben dem Paket installieren oder einen Schlüssel setzen. webvector doctor zeigt, welche Stufe aktiv ist. Der lexikalische Modus ist ein unterstützter Modus, kein Fallback – Ergebnisse sind als stats.embed.provider: 'none' markiert und nicht „degradiert“.
6. Konfiguration
Priorität: Code → Konfigurationsdatei → Umgebungsvariablen → Standardwerte. Konfigurationsdateien: webvector.config.{ts,js,mjs,json,yaml,yml}, .webvectorrc oder ein webvector-Schlüssel in package.json, gefunden durch Aufwärtssuchen vom Arbeitsverzeichnis. ${VAR} / ${VAR:-default} innerhalb von Werten werden aus der Umgebung gefüllt.
webvector init schreibt einen kommentierten Starter; hier sind die Regler, die Leute tatsächlich ändern:
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: warnUmgebungsäquivalente: 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, plus die Anbieterschlüssel unten. Jede Option mit ihrem Standard: docs/CONFIGURATION.md.
7. Anbieter
Setzen Sie die Umgebungsvariable, benennen Sie den Anbieter, fertig. Details und Stolperfallen pro Anbieter: docs/PROVIDERS.md.
Suche | env | Embeddings | env | Stores / Reranker | env |
| — |
| — |
| — |
|
|
| — |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| rerank | — |
|
|
|
| rerank |
|
|
|
|
| rerank |
|
|
|
|
| rerank |
|
| — | jedes Vercel-AI-SDK-Modell | — | rerank | — |
Wenn der primäre Suchanbieter fehlschlägt oder ratenbegrenzt ist, wird die fallbackProviders-Kette automatisch versucht und jeder Versuch wird in stats.search.attempts aufgezeichnet.
8. Was Sie zurückbekommen
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. Fehler und Ausfälle
Zwei Arten, bewusst getrennt:
Ausfälle sind pro Seite und brechen einen Lauf nie ab:
FETCH_TIMEOUT,FETCH_HTTP_ERROR,FETCH_BLOCKED_ROBOTS,FETCH_BLOCKED_SSRF,FETCH_TOO_LARGE,TOO_MANY_REDIRECTS,UNSUPPORTED_CONTENT_TYPE,PARSE_EMPTY,PARSE_FAILED. Sie landen inresult.failures[]undsources[].failure. Wenn jede Seite fehlschlägt, erhalten Sie trotzdem die Suchausschnitte (degraded: 'search_only',ALL_FETCHES_FAILED).Fehler werden als
WebVectorErrorgeworfen mitcode,message,remediation,retryable,provider,stageundtoJSON(); Geheimnisse werden redigiert. Beispiele:MISSING_API_KEY(„Setzen Sie BRAVE_API_KEY … oder verwenden Sie einen schlüssellosen Anbieter: duckduckgo"),MISSING_DEPENDENCY(„npm i @huggingface/transformers – oder embeddings.provider: 'none'"),SEARCH_BLOCKED,PROVIDER_RATE_LIMITED(mitretryAfterMs),EMBEDDING_DIMENSION_MISMATCH(nennt beide Modelle; schlägtstore.clear()oder eine neue Sammlung vor),INVALID_CONFIG.
10. Sicherheit und Etikette
WebVector ruft URLs ab, die von einer Suchmaschine ausgewählt wurden – also Inhalte, die ein Angreifer beeinflussen kann – daher ist der Fetcher standardmäßig defensiv:
SSRF-Schutz: private, loopback, link-local, CGNAT, multicast, reserved, IPv4-mapped-IPv6 und
localhost/*.internal-Ziele werden abgelehnt; DNS-Antworten werden geprüft und jeder Redirect-Schritt wird erneut geprüft. Opt-out nur für vertrauenswürdige lokale Setups (ingestion.allowPrivateNetworks).Obergrenzen für Redirects (5), Antwortgröße (5 MB), Zeit pro Anfrage (15 s) und Gesamtlaufzeit (45 s); begrenzte Parallelität global und pro Host.
Etikette: robots.txt wird beachtet (einschließlich
Crawl-delay), identifizierbarer User-Agent, Mindestintervall pro Host,Retry-Afterwird respektiert.Parsen ohne Ausführung: HTML wird mit linkedom geparst (keine Skripte, kein Laden von Unterressourcen), PDFs mit pdf.js im No-Eval-Modus; Aufrufer erhalten immer nur Markdown/Plain-Text mit entfernten Steuerzeichen.
Geheimnisse: aus Umgebung/Konfiguration gelesen, niemals protokolliert; in Fehlern, in
webvector configund im MCP-Toolwebvector_statusgeschwärzt. Es wird nichts auf die Festplatte geschrieben, es sei denn, Sie aktivieren das Seiten-Cache-Verzeichnis.Keine Telemetrie, niemals.
MCP über HTTP bindet nur an
127.0.0.1, validiertHost/Origin(DNS-Rebinding-Schutz), unterstützt ein Bearer-Token und weigert sich, ohne--allow-remoteund ein Token an anderer Stelle zu binden.DNS-Rebinding wird beim Verbindungsaufbau geschlossen: Die SSRF-Prüfung läuft innerhalb der DNS-Auflösung, die zum Öffnen des Sockets verwendet wird, sodass die geprüfte Adresse die angewählte Adresse ist.
Hinweis zu DuckDuckGo: Der schlüssellose Anbieter spricht mit den öffentlichen HTML-Endpunkten von DuckDuckGo mit einem browserähnlichen User-Agent (es gibt keine offizielle API). Er ist von Natur aus ratenbegrenzt und fragil; starke oder kommerzielle Nutzung sollte auf einen schlüsselbasierten Anbieter umsteigen (
brave,serper,tavily). Seitenabrufe verwenden immer den ehrlichenWebVector/…User-Agent.
Etwas gefunden? Bitte öffnen Sie ein privates Sicherheits-Advisory auf GitHub anstatt ein öffentliches Issue.
11. Aus dem Quellcode ausführen (lokale Entwicklung)
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 7Repo-Struktur und wo Dinge hinzugefügt werden: docs/ARCHITECTURE.md.
Um den lokalen Build aus einem anderen Projekt ohne Veröffentlichung zu verwenden: npm pack in packages/core (und mcp/cli) und dort npm i ./webvector-0.1.0.tgz ausführen, oder npm link.
12. Eigene Adapter schreiben
Jeder Anbietertyp ist ein kleines Interface in packages/core/src/types.ts — SearchProvider, EmbeddingProvider, VectorStore, ContentParser, Reranker. Implementieren Sie es und übergeben Sie entweder eine Instanz in der Konfiguration oder registrieren Sie einen Namen, damit Konfigurationsdateien es verwenden können:
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 exportiert Konformitätsprüfungen (searchProviderConformance, embeddingProviderConformance, vectorStoreConformance), die Sie in jeden Test-Runner einfügen können.
13. So funktioniert es
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, MarkdownTypischer Lauf auf einem Laptop: Suche ~1 s, 8 Seiten abgerufen + geparst ~1–2,5 s, Abruf < 50 ms → ~2 s lexikalisch / ~4 s semantisch.
14. Roadmap
LanceDB- und Pinecone-Stores · ein Headless-Browser-Fetch-Adapter für JS-gerenderte Seiten · kontextuelles Retrieval (LLM-zusammengefasster Chunk-Kontext) als Opt-in · eine eigenständige Binärdatei ohne Node-Anforderung · Python-Paket, das die Konformitäts-Fixtures teilt.
Lizenz
MIT © Ryan Thomas
This server cannot be deployed
Maintenance
Related MCP Connectors
Scrape, crawl and search the web for AI agents via MCP.
Live AI-native web search with citations. One tool for every MCP client. Flat per-request pricing.
Web search, fetch, extract, and research for AI agents. Markdown output + AI-synthesized answers.
Web search, scraping, RAG answers with citations, and translation as MCP tools.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to perform grounded web research with injection resistance, claim verification, and cost-aware routing through MCP tools like web_search, fetch_url, extract_claims, and check_grounding.MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to perform unified web research through a single MCP server, including search, page fetching, recursive crawling, document parsing, YouTube transcript extraction, and deep multi-query research.3-
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to perform live web searches across 9 engines, scrape web pages into clean formats, and run agentic research with citations via MCP.98 PyPI3MIT
- AlicenseBqualityBmaintenanceEnables AI agents to perform web searches and extract full-text content from web pages via standard MCP tools, with fallback search and semantic reranking.22MIT