Skip to main content
Glama
rthomas24

WebVector MCP Server

by rthomas24

WebVector

npm: webvector npm: webvector-mcp npm: webvector-cli CI License: MIT

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

  1. In 30 Sekunden ausprobieren

  2. Als MCP-Server verwenden (Claude Code, Claude Desktop, Cursor…)

  3. Als Bibliothek verwenden

  4. Von der Kommandozeile aus verwenden

  5. Die zwei Stufen: lexikalisch vs. semantisch

  6. Konfiguration

  7. Anbieter

  8. Was Sie zurückbekommen

  9. Fehler und Ausfälle

  10. Sicherheit und Etikette

  11. Aus dem Quellcode ausführen (lokale Entwicklung)

  12. Eigene Adapter schreiben

  13. So funktioniert es

  14. Roadmap · Lizenz

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" --stats

Sie 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 doctor

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

Claude 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 3333http://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 webvector
import { 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 server

5. Die zwei Stufen: lexikalisch vs. semantisch

Ein Regler – embeddings.provider, Standard auto – entscheidet, wie Passagen gerankt werden:

Stufe

Installation

Ranking

Gewählt, wenn

Lexikalisch (none)

~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 npx-Pfad)

Semantisch (local, openai, …)

+ @huggingface/transformers (~230 MB, Modell 23 MB, vollständig offline) oder ein beliebiger Embedding-API-Schlüssel

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: CodeKonfigurationsdateiUmgebungsvariablenStandardwerte. 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: warn

Umgebungsä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

duckduckgo (Standard)

none (BM25)

memory (Standard)

brave

BRAVE_API_KEY

local (Transformers.js)

chroma

CHROMA_URL

serper (Google)

SERPER_API_KEY

openai

OPENAI_API_KEY

qdrant

QDRANT_URL

serpapi

SERPAPI_API_KEY

openai-compatible (LM Studio, vLLM, …)

OPENAI_COMPATIBLE_BASE_URL

pgvector

DATABASE_URL

tavily / tavily-keyless

TAVILY_API_KEY

gemini

GEMINI_API_KEY

rerank local

exa

EXA_API_KEY

voyage

VOYAGE_API_KEY

rerank cohere

COHERE_API_KEY

perplexity

PERPLEXITY_API_KEY

cohere

COHERE_API_KEY

rerank voyage

VOYAGE_API_KEY

searxng (selbst gehostet)

SEARXNG_URL

mistral / jina / ollama

MISTRAL_API_KEY / JINA_API_KEY / OLLAMA_HOST

rerank jina

JINA_API_KEY

wikipedia

jedes Vercel-AI-SDK-Modell

rerank llm (Ihre Funktion)

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 in result.failures[] und sources[].failure. Wenn jede Seite fehlschlägt, erhalten Sie trotzdem die Suchausschnitte (degraded: 'search_only', ALL_FETCHES_FAILED).

  • Fehler werden als WebVectorError geworfen mit code, message, remediation, retryable, provider, stage und toJSON(); 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 (mit retryAfterMs), EMBEDDING_DIMENSION_MISMATCH (nennt beide Modelle; schlägt store.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-After wird 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 config und im MCP-Tool webvector_status geschwä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, validiert Host/Origin (DNS-Rebinding-Schutz), unterstützt ein Bearer-Token und weigert sich, ohne --allow-remote und 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 ehrlichen WebVector/… 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 7

Repo-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.tsSearchProvider, 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-index

webvector/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, Markdown

Typischer 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

-
license - not tested
-
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

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

View all MCP Connectors

Latest Blog Posts

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