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 "Install 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.
Recommended backend:
gemini-2.5-flashvia the Google AI OpenAI-compatible endpoint. Local LLM stacks (llama.cpp + quantized models) work but produce noticeably weaker results — small cloud models consistently outperform local quantized models for this pipeline's multi-stage workload.
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 — Google Gemini Flash (recommended)
No GPU required. Gemini Flash is fast, cheap, and outperforms local quantized models on this pipeline.
Get a free API key at aistudio.google.com, then:
cp .env.example .envEdit .env:
LLM_BASE_URL=https://generativelanguage.googleapis.com/v1beta/openai/
LLM_MODEL=gemini-2.5-flash
LLM_API_KEY=AIzaSy... # your Google AI Studio key
LLM_MAX_TOKENS=8192
STRIP_THINKING_TOKENS=false # not needed for Gemini
# Fast model (same endpoint — leave blank to reuse LLM_MODEL for all stages)
LLM_FAST_BASE_URL=
LLM_FAST_MODEL=
# SearXNG (bundled in infra stack)
SEARXNG_URL=http://localhost:4000# Start infra (SearXNG only — no llama.cpp needed)
make infra-up
make up
curl -X POST http://localhost:33100/research \
-H 'Content-Type: application/json' \
-d '{"query": "What are the latest advances in fusion energy?"}'MCP 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": "https://generativelanguage.googleapis.com/v1beta/openai/",
"LLM_MODEL": "gemini-2.5-flash",
"LLM_API_KEY": "AIzaSy...",
"LLM_MAX_TOKENS": "8192",
"STRIP_THINKING_TOKENS": "false",
"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 |
|
| Model name sent in requests |
|
| Set to |
|
| Max tokens per LLM call |
|
| Generation temperature |
|
| Strip |
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 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 |
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 |
Anthropic | Use LiteLLM proxy | OpenAI-compatible wrapper |
Recommended Models
gemini-2.5-flash is the recommended model — no GPU required, free tier available, and it consistently outperforms local quantized models on this pipeline's multi-stage workload (planning, parallel summarization, report synthesis).
Note on local LLMs: Running llama.cpp with quantized Qwen models works but results are noticeably weaker. The pipeline makes many concurrent LLM calls and small quantized models struggle with instruction following across all stages. Cloud models handle this much better.
Model | Backend | Notes |
| Google AI | Recommended — fast, cheap, excellent quality |
| Google AI | Cheaper, slightly lower quality |
| Google AI | Newest, preview only — may change |
| OpenAI | Solid cloud alternative |
| llama.cpp / Ollama | Local option — ~3GB VRAM, results vary |
| llama.cpp | Local option — ~6GB VRAM, marginal improvement |
Set STRIP_THINKING_TOKENS=true when using Qwen3 models to strip internal <think> tokens from responses.
License
MIT
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.
Latest Blog Posts
- 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/mareurs/researcher'
If you have feedback or need assistance with the MCP directory API, please join our Discord server