researcher
Integrates DuckDuckGo as a fallback search engine for web crawling when SearXNG is unavailable.
Recommended LLM backend using Google Gemini 2.5 Flash for fast and cost-effective research.
Supports Ollama as a local LLM backend, allowing use of models like Qwen2.5 for the research pipeline.
Supports OpenAI-compatible endpoints, allowing use of models like GPT-4.1-mini for the research pipeline.
Uses SearXNG as the primary metasearch engine for web crawling, running as a Docker container.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@researcherResearch the latest advances in fusion energy"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Researcher
Fast AI research agent in Rust — plans sub-questions, searches the web, scrapes sources in parallel, and writes a comprehensive markdown report.
query → planner (LLM) → search+scrape×N → quality filter → dedup → rerank → summarize×M → report (LLM)Why Rust? No GIL — true parallel scraping, concurrent LLM summarization, ~5MB static binary, zero LangChain.
Features
Multi-stage pipeline — LLM-driven query planning, parallel web crawling, concurrent summarization, final report synthesis
Any OpenAI-compatible LLM — local (llama.cpp, Ollama, vLLM) or cloud (OpenAI, Anthropic via LiteLLM)
Dual-model routing — optionally route different pipeline stages to different model backends
Semantic deduplication — TEI embeddings + cosine similarity drop near-duplicate sources before summarization
Cross-encoder reranking —
ms-marco-MiniLMscores and reranks sources by relevance, authority, and content qualityDomain profiles — pin searches to curated source lists (tech-news, academic, llm-news, shopping, travel, news)
6 MCP tools —
research,research_person,research_company,research_code,search_jobs,market_insightStreaming HTTP API — SSE token stream for the web UI; blocking JSON for MCP and programmatic use
Job search — finds remote jobs matching your
profiles.tomlpreferences, with optional deep company briefs
Related MCP server: Gemini DeepSearch MCP
Architecture
topic
│
▼
Planner (LLM) ──── generates N sub-questions
│
▼
Crawler (parallel per query)
├─ SearXNG search (→ DuckDuckGo fallback)
└─ scrape URLs concurrently (reqwest + scraper crate)
│
▼
Quality filter ──── min word count, text density
│
▼
Dedup (TEI embed → cosine sim) ──── optional, requires EMBED_BASE_URL
│
▼
Cross-encoder rerank (TEI) ──── optional, requires RERANK_BASE_URL
│
▼
Summarizer (LLM, join_all — all calls concurrent)
│
▼
Publisher (LLM) ──── final markdown report / streaming tokensTwo binaries:
researcher— HTTP server (POST /research,POST /research/stream,GET /) + CLI (--query)researcher-mcp— MCP stdio server for Claude Desktop / Claude Code
Requirements
Component | Required | Notes |
Rust 1.80+ | For building from source |
|
Docker + Compose | For the full stack | v2.20+ recommended |
LLM backend | One of below | |
└ NVIDIA GPU | For local llama.cpp | Any CUDA-capable card with ≥8GB VRAM |
└ AMD GPU | For ROCm llama.cpp | RDNA2/RDNA3, kernel 6.x |
└ OpenAI API key | Cloud alternative | No GPU needed |
└ Ollama | Local alternative | CPU or GPU |
SearXNG | Bundled in infra stack | Private metasearch engine |
TEI (optional) | For dedup + reranking | CPU-only images work fine |
Quick Start
Option A — Full local stack (NVIDIA GPU)
# 1. Clone and configure
git clone https://github.com/your-org/researcher.git
cd researcher
cp .env.example .env
cp infra/.env.example infra/.env
# Edit infra/.env: set LLAMA_MODELS_PATH to where your GGUF files live
# 2. Download a model (Qwen3.5-4B — ~3GB VRAM, works great)
huggingface-cli download unsloth/Qwen3.5-4B-GGUF \
--include "Qwen3.5-4B-Q4_K_M.gguf" \
--local-dir /path/to/your/models/unsloth/Qwen3.5-4B-GGUF/
# 3. Start infrastructure (llama-cpp + SearXNG + TEI embed + TEI rerank)
make infra-up
# 4. Start the researcher service
make up
# 5. Research something
curl -X POST http://localhost:33100/research \
-H 'Content-Type: application/json' \
-d '{"query": "What are the latest advances in fusion energy?"}'Web UI with token streaming: http://localhost:33100/
Option B — OpenAI
cp .env.example .env
# Edit .env:
# LLM_BASE_URL=https://api.openai.com/v1
# LLM_MODEL=gpt-4.1-mini
# LLM_API_KEY=sk-...
# LLM_FAST_BASE_URL= (leave empty — use same backend for all stages)
# Start infra (SearXNG only; llama-cpp is not required)
make infra-up
make up
curl -X POST http://localhost:33100/research \
-H 'Content-Type: application/json' \
-d '{"query": "Impact of quantum computing on cryptography"}'Option C — CLI (no Docker)
cargo build --release
# Run against a local llama.cpp + SearXNG
LLM_BASE_URL=http://localhost:8080/v1 \
SEARXNG_URL=http://localhost:4000 \
RUST_LOG=info \
./target/release/researcher --query "Rust async runtime internals"
# Save report to file
./target/release/researcher --query "..." --output report.mdOption D — Ollama
# In .env:
LLM_BASE_URL=http://host.docker.internal:11434/v1
LLM_MODEL=qwen2.5:7b
LLM_API_KEY=ollama
LLM_FAST_BASE_URL= # empty = same model for all stagesOption E — Vertex AI (ADC auth)
cp .env.example .env
# Edit .env:
# LLM_PROVIDER=vertex
# LLM_MODEL=gemini-2.5-flash
# VERTEX_PROJECT=sp-mrv-gemini-dev
# VERTEX_LOCATION=eu
# LLM_BASE_URL=https://aiplatform.googleapis.com/v1beta1
# LLM_FAST_PROVIDER=vertex # optional; empty = inherit primary providerAuthenticate locally:
gcloud auth application-default loginThen run:
make infra-up # for SearXNG / optional TEI services
make upMCP Server
researcher-mcp exposes the full pipeline as MCP tools over stdio. Use with Claude Desktop, Claude Code, or any MCP client.
cargo build --release --bin researcher-mcp
# → target/release/researcher-mcp (~6MB)Claude Desktop (~/.config/claude/claude_desktop_config.json)
{
"mcpServers": {
"researcher": {
"command": "/path/to/researcher-mcp",
"env": {
"LLM_BASE_URL": "http://localhost:8080/v1",
"LLM_MODEL": "Qwen3.5-4B-Q4_K_M",
"SEARXNG_URL": "http://localhost:4000",
"STRIP_THINKING_TOKENS": "true",
"EMBED_BASE_URL": "http://localhost:30082",
"RERANK_BASE_URL": "http://localhost:30083"
}
}
}
}Claude Code (.mcp.json)
{
"mcpServers": {
"researcher": {
"command": "/path/to/researcher-mcp",
"env": {
"LLM_BASE_URL": "http://localhost:8080/v1",
"SEARXNG_URL": "http://localhost:4000"
}
}
}
}MCP Tools
Tool | Parameters | Description |
|
| General web research → markdown report |
|
| Meeting prep brief (career, voice, interests, hooks). |
|
| Company brief (what they do, size, news, culture, strategy) |
|
| Library research: bugs, changelog, community sentiment |
|
| Remote job search matched to your |
|
| Stock/crypto/macro research. |
Research modes: quick (snippets), summary (bullets), report (full markdown, default), deep (thorough)
HTTP API
POST /research
Blocking — waits for the full report.
curl -X POST http://localhost:33100/research \
-H 'Content-Type: application/json' \
-d '{
"query": "Rust async runtimes compared",
"mode": "report",
"max_queries": 4,
"max_sources": 4
}'Response:
{
"topic": "Rust async runtimes compared",
"queries": ["What is Tokio?", "..."],
"source_count": 14,
"report": "# Research Report\n\n..."
}POST /research/stream
SSE token stream — progress events then report tokens.
curl -X POST http://localhost:33100/research/stream \
-H 'Content-Type: application/json' \
-d '{"query": "history of the internet"}' \
--no-bufferEvents:
data: {"type":"progress","message":"🔍 Planning research queries..."}
data: {"type":"progress","message":"📋 Generated 4 search queries","data":{"queries":[...]}}
data: {"type":"progress","message":"🌐 Crawling 4 queries in parallel..."}
data: {"type":"token","token":"# Research Report\n\n"}
...
event: complete
data: {"type":"complete","topic":"...","report":"# Research Report\n\n..."}GET /health
Returns 200 ok.
Configuration
All settings are environment variables. Copy .env.example to .env and edit.
LLM
Variable | Default | Description |
|
|
|
|
| Any OpenAI-compatible endpoint; for Vertex use |
|
| Model name sent in requests |
|
| Set to |
|
| Max tokens per LLM call |
|
| Generation temperature |
|
| Strip |
| `` | Required when |
|
| Vertex AI region |
Dual-model routing (optional)
Route different pipeline stages to a second model backend. Leave LLM_FAST_BASE_URL empty to use a single backend for everything (the default and recommended setup).
Variable | Default | Description |
| `` (disabled) | Fast LLM endpoint; empty = use heavy backend |
|
| Model name for fast LLM |
| `` | Fast provider override; empty = inherit |
| `` | Fast LLM API key; empty = inherit |
|
| Max tokens for fast model |
|
| Pipeline stages routed to fast LLM |
Valid stage names: planner, summarizer, publisher
Search & crawling
Variable | Default | Description |
|
| SearXNG instance URL |
| `` | Brave Search API key (empty = disabled; default fallback for all profiles) |
| `` | Tavily API key — used for |
| `` | Exa API key — used for |
|
| Results fetched per sub-question |
|
| Sub-questions the planner generates |
|
| Pages scraped per query |
|
| Max characters extracted per page |
Embeddings & reranking (optional)
Both are disabled when their *_BASE_URL is empty — the pipeline skips those stages gracefully.
Variable | Default | Description |
| `` (disabled) | TEI embed endpoint (e.g. |
|
| Cosine similarity cutoff for deduplication |
| `` (disabled) | TEI rerank endpoint (e.g. |
|
| Cross-encoder score weight |
|
| Domain authority weight |
|
| Content quality weight |
Quality filter
Variable | Default | Description |
|
| Minimum word count per page |
|
| Minimum text/HTML density ratio |
Auth (optional — for gated sources)
Variable | Description |
| Cookie header for linkedin.com |
| Cookie header for twitter.com / x.com |
| Cookie header for facebook.com |
| Cookie header for instagram.com |
| Adzuna API app ID (job search) — free at developer.adzuna.com |
| Adzuna API key |
|
|
Server
Variable | Default | Description |
|
| HTTP server bind address |
|
| Log level filter |
Tracing (Langfuse, optional)
Variable | Default | Description |
| `` (disabled) | Langfuse base URL; empty disables tracing |
| `` | Langfuse project public key |
| `` | Langfuse project secret key |
|
| Truncate captured LLM/stage I/O |
Domain Profiles
profiles.toml defines named source lists. Pass domain_profile="tech-news" to any tool or API call to restrict searches to those domains. Profiles can be combined with a raw domains list — they are unioned.
Built-in profiles:
Profile | Sources |
| Hacker News, lobste.rs, r/programming, r/rust, r/technology |
| HuggingFace, arXiv, r/LocalLLaMA, r/MachineLearning |
| arXiv, Semantic Scholar, PubMed |
| BBC, Reuters, r/worldnews, r/news, r/europe |
| TripAdvisor, Lonely Planet, Wikivoyage, r/travel |
| OLX.ro, eMag.ro, Altex.ro (Romanian market) |
Add custom profiles in profiles.toml:
[my-profile]
domains = ["example.com", "docs.example.com"]Job Search
Configure your profile in profiles.toml under [job-profile]:
[job-profile]
title = "Senior AI Engineer"
seniority = "senior"
salary_floor = "150000 USD"
remote_only = true
skills = ["Rust", "Python", "LLMs", "MLOps", "RAG"]
preferred_company_size = "startup to mid-size"
avoid_industries = ["gambling", "crypto"]
about_me = """
Brief summary of your background and what you're looking for.
"""Then call search_jobs via MCP or HTTP. Use mode: "deep" for full company briefs on the top 5 matches.
Infrastructure Stack
The project uses a two-compose layout to keep the AI infrastructure reusable across projects:
infra/docker-compose.yml ← always-on: SearXNG, llama-cpp, TEI embed, TEI rerank
docker-compose.yml ← researcher app only (joins ai-infra-net)# Start infrastructure first
make infra-up
# Then start the researcher app
make up
# Logs
make infra-logs # infrastructure services
make logs # researcher app
# Stop everything
make stop-allServices
Service | Port | Description |
| 4000 | Private metasearch (Google/DDG/Bing, optionally via Tor) |
| 30080 | Heavy LLM — NVIDIA GPU (llama.cpp CUDA image) |
| 30081 | Fast LLM — AMD GPU via ROCm, or second card |
| 8081 |
|
| 8082 |
|
| 33100 | Researcher HTTP server |
The infra stack creates a shared Docker network ai-infra-net. Other projects can join it and reuse the LLM and search services without running their own copies.
Single-GPU setup
Set LLM_FAST_BASE_URL= (empty) in .env. All pipeline stages use the same llama-cpp backend.
AMD GPU (ROCm)
llama-cpp-fast uses the ROCm image and targets /dev/kfd + /dev/dri. Works with RDNA2/RDNA3 on kernel 6.x.
Building from Source
# Prerequisites (Debian/Ubuntu)
sudo apt-get install pkg-config libssl-dev
# Type-check only (fast)
cargo check
# Build both binaries (optimized — ~30-60s with LTO)
cargo build --release
# Lint
cargo clippy -- -D warningsBinaries:
target/release/researcher— HTTP server + CLItarget/release/researcher-mcp— MCP stdio server (~6MB)
Docker image
docker build -t researcher .
# Multi-stage build: rust:slim builder → distroless runtime (~8MB total)LLM Backend Compatibility
Backend |
| Notes |
llama.cpp |
| Recommended local; CUDA/ROCm/CPU images available |
Ollama |
| Easy model management |
vLLM |
| Best for multi-user / high concurrency |
LM Studio |
| Desktop GUI for local models |
OpenAI |
| Set |
Google Gemini |
| Set |
Vertex AI |
| Set |
Anthropic | Use LiteLLM proxy | OpenAI-compatible wrapper |
Recommended Models
Qwen3.5-4B-Q4_K_M is the recommended model — it runs on ~3GB VRAM and produces excellent research reports.
Model | VRAM | Notes |
| ~3GB | Recommended — fast, high quality |
| ~6GB | Larger, marginal gains for most queries |
| — | Cloud alternative |
Set STRIP_THINKING_TOKENS=true for all Qwen3 models to strip internal <think> tokens from responses.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
- fastCRWOAuthio.github.us
Scrape, crawl, map & search the web. Open-source, self-hostable Rust crawler & search for AI agents.
Web search, fetch, extract, and research for AI agents. Markdown output + AI-synthesized answers.
Agent-native search engine with live web research optimized for AI agents.
Web research for agents: quality-scored Google search, webpage extraction, and deep research.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables iterative deep research by integrating AI agents with search engines, web scraping, and large language models for efficient data gathering and comprehensive reporting.11 npm322MIT
- AlicenseBqualityCmaintenanceAn automated research agent that leverages Google Gemini models and Google Search to perform deep, multi-step web research, generating sophisticated queries and producing citation-rich answers.128MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI-powered research by breaking a topic into subtopics, gathering information via agents, and compiling a report. Integrates with LangGraph and RAG for orchestration and contextual retrieval.1-
- FlicenseNot gradedqualityDmaintenanceAn AI-powered deep research agent that automates the full research pipeline from web search to structured executive reports using a 4-tool pipeline (search, fetch, cluster, report).4-