WebVector MCP Server
WebVector
한 번의 도구 호출로 AI 에이전트에 실제 웹 리서치를 제공하세요: 검색 → 전체 페이지 읽기 → 순위 지정 → 인용된 구절.
검색 도구는 모델에게 제목과 150자 분량의 스니펫만 넘겨주므로, 모델은 나머지를 추측해야 합니다. 가져오기(fetch) 도구는 40KB 분량의 내비게이션과 상용구를 넘겨주므로, 모델은 그 속에서 파묻힙니다. WebVector는 그 중간의 모든 작업을 처리합니다: 검색 실행, 모든 결과(HTML, PDF, Markdown) 다운로드 및 정리, 구절로 분할, 질문에 대한 구절 순위 지정 — 임베딩 모델이 있으면 의미론적으로, 없으면 어휘적으로(BM25) — 그리고 쿼리에 답하는 구절만 각각의 URL, 제목, 오프셋, 점수와 함께 반환합니다.
API 키와 모델 다운로드 없이 작동합니다: DuckDuckGo + BM25, ~12 MB 설치.
모든 검색 백엔드, 임베딩 제공자, 벡터 스토어 또는 리랭커를 연결할 수 있습니다(또는 한 파일로 직접 작성).
라이브러리, 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에서 지원됩니다.
Related MCP server: MyWebSearch MCP
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용 바인딩은 import 한 번이면 됩니다:
// 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. 두 가지 계층: 어휘 vs 의미론
embeddings.provider(기본값 auto)라는 단 하나의 설정이 구절 순위 지정 방식을 결정합니다:
계층 | 설치 | 순위 지정 방식 | 선택되는 조건 |
어휘( | ~12 MB, 다운로드 없음 | 가져온 전체 페이지 대상 BM25 + 쿼리 확장 + 소스별 다양성 | 모델 런타임과 임베딩 키가 모두 없는 경우(일반 |
의미론( | + | 하이브리드: RRF로 융합된 벡터 + BM25, MMR 다양성, 선택적 리랭커 | 둘 중 하나라도 사용 가능하면 자동으로 |
언제든 업그레이드할 수 있습니다: 패키지와 함께 npm i @huggingface/transformers를 설치하거나 키를 설정하세요. webvector doctor는 현재 활성화된 계층을 표시합니다. 어휘 모드는 폴백이 아니라 지원되는 모드입니다 — 결과는 stats.embed.provider: 'none'으로 표시되며 "저하된" 상태가 아닙니다.
6. 설정
우선순위: 코드 → 설정 파일 → 환경 변수 → 기본값. 설정 파일(webvector.config.{ts,js,mjs,json,yaml,yml}, .webvectorrc, 또는 package.json의 webvector 키)은 작업 디렉터리에서 위로 거슬러 올라가며 찾습니다. 값 안의 ${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 |
| — |
| — |
| — |
|
|
| — |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| rerank | — |
|
|
|
| rerank |
|
|
|
|
| rerank |
|
|
|
|
| rerank |
|
| — | 모든 Vercel AI SDK 모델 | — | rerank | — |
기본 검색 제공자가 실패하거나 속도 제한에 걸리면 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. 오류와 실패
두 가지 종류를 의도적으로 구분합니다:
실패(Failures)는 페이지별로 발생하며 실행을 중단하지 않습니다:
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).오류(Errors)는
WebVectorError로 던져지며code,message,remediation,retryable,provider,stage,toJSON()을 포함합니다. 비밀 값은 마스킹됩니다. 예시:MISSING_API_KEY("BRAVE_API_KEY를 설정하세요 … 또는 키가 필요 없는 제공자를 사용하세요: duckduckgo"),MISSING_DEPENDENCY("npm i @huggingface/transformers — 또는 embeddings.provider: 'none'"), `SESSRF 가드: private, loopback, link-local, CGNAT, multicast, reserved, IPv4-mapped-IPv6 및
localhost/*.internal대상은 거부됩니다. DNS 응답을 확인하고 모든 리디렉션 홉을 다시 확인합니다. 신뢰할 수 있는 로컬 설정(ingestion.allowPrivateNetworks)에서만 선택 해제할 수 있습니다.상한: 리디렉션(5회), 응답 크기(5MB), 요청당 시간(15초), 전체 실행 마감(45초)이 있으며, 전역 및 호스트별 동시성에 제한이 있습니다.
예의: robots.txt를 준수하고(
Crawl-delay포함), 식별 가능한 User-Agent를 사용하며, 호스트별 최소 간격을 지키고,Retry-After를 존중합니다.실행 없는 파싱: HTML은 linkedom으로 파싱되고(스크립트나 하위 리소스 로딩 없음), PDF는 no-eval 모드의 pdf.js로 파싱됩니다. 호출자는 제어 문자가 제거된 Markdown/일반 텍스트만 받습니다.
비밀: 환경/설정에서 읽으며, 로그에 기록하지 않고, 오류,
webvector config, MCPwebvector_status도구에서 모두 삭제됩니다. 페이지 캐시 디렉터리를 활성화하지 않는 한 디스크에 아무것도 기록하지 않습니다.원격 측정 없음, 절대.
HTTP를 통한 MCP는
127.0.0.1에만 바인딩하고,Host/Origin을 검증하며(DNS 리바인딩 보호), 베어러 토큰을 지원하고,--allow-remote및 토큰 없이는 다른 곳에 바인딩을 거부합니다.DNS 리바인딩은 연결 시점에 차단됩니다: SSRF 검사는 소켓을 여는 데 사용되는 DNS 조회 내에서 실행되므로, 검사된 주소는 실제로 연결되는 주소입니다.
DuckDuckGo 참고: 키 없는 공급자는 브라우저와 유사한 User-Agent로 DuckDuckGo의 공개 HTML 엔드포인트와 통신합니다(공식 API는 없음). 본질적으로 속도 제한이 있고 취약합니다. 대규모 또는 상업적 사용은 키 기반 공급자(
brave,serper,tavily)로 전환해야 합니다. 페이지 가져오기는 항상 정직한WebVector/…User-Agent를 사용합니다.
문제를 발견하셨나요? 공개 이슈 대신 GitHub에서 비공개 보안 권고를 열어 주세요.
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.
로컬 빌드를 다른 프로젝트에서 게시 없이 사용하려면: packages/core(및 mcp/cli)에서 npm pack을 실행하고 해당 프로젝트에서 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초, 검색 < 50ms → ~2초 어휘 / ~4초 의미론적.
14. 로드맵
LanceDB 및 Pinecone 저장소 · JS 렌더링 페이지용 헤드리스 브라우저 가져오기 어댑터 · 상황별 검색(LLM 요약 청크 컨텍스트)을 선택 사항으로 · Node 요구 사항이 없는 독립 실행형 바이너리 · 적합성 픽스처를 공유하는 Python 패키지.
라이선스
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