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.
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 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