Skip to content
Syed Asif edited this page Jul 1, 2026 · 14 revisions

Web Search MCP

A FastMCP server that gives LLMs real-time web access — search engines, social platforms, academic databases, and developer tools, all in one MCP interface.

Full setup guide → README.md — covers prerequisites, all install options (uvx, permanent, dev), step-by-step config for each provider (X cookies, GitHub PAT, Exa), usage examples, and troubleshooting.


Table of Contents


Getting Started

Prerequisites

  • Python 3.11+
  • uv — install it with curl -LsSf https://astral.sh/uv/install.sh | sh

Quick Install

Run without installing (uvx) — add to your MCP client config:

{
  "mcpServers": {
    "web-search": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/sydasif/web-search-mcp.git", "web-search-mcp"]
    }
  }
}

Or install globally:

uv tool install git+https://github.com/sydasif/web-search-mcp.git

Environment Variables

Most tools work out of the box. Only set these if you need the corresponding feature:

Variable Purpose Required For
EXA_API_KEY Semantic search + JS page fallback Optional — Exa AI
GITHUB_TOKEN Higher GitHub API rate limits Optional — GitHub tools
AUTH_TOKEN + CT0 X session cookies Required — search_x
XQUIK_API_KEY Alternative X/Twitter backend (bypasses Bird CLI) Optional — search_x

Tip: Export these in the same shell where the MCP server runs. See the README for detailed setup guides (X cookie extraction, GitHub PAT, Exa signup).

Verify It's Working

Once running, try:

search_web(query="current weather in Tokyo")

Tools Reference

The server exposes 9 tools across 10 data sources. All are keyless unless noted.

Tool What It Does Works With Auth
search_web Broad web & news search with domain scoping DuckDuckGo + Exa (fallback) None
fetch_page Clean text extraction from any URL Trafilatura + Exa (JS fallback) None
search_reddit Community discussions and real user experiences RSS + Shreddit enrichment None
search_hackernews Technical discourse and startup news Algolia API + comment enrichment None
search_arxiv Academic paper search (Lucene field prefixes) arXiv API None
search_wikipedia Factual summaries and background research MediaWiki API None
search_github Issues, PRs, and community discussion search GitHub Search API Optional GITHUB_TOKEN
get_github_issue Full issue/PR thread with all comments rendered gh CLI gh CLI or GITHUB_TOKEN
search_x Real-time discourse and breaking news Xquik API or Bird CLI AUTH_TOKEN + CT0 (or XQUIK_API_KEY)

Quick Pick — Which Tool to Use

When you need... Use Why
A specific fact/page search_web Fast, keyword-accurate
Actual page content fetch_page Clean text extraction
Unbiased user reviews search_reddit Real people, real problems
Developer consensus search_hackernews High-signal technical discourse
Breaking news search_x Fastest propagation
SOTA research search_arxiv Primary academic sources
Bug context get_github_issue Full conversation history
Code discussions search_github Issues and PRs
Background facts search_wikipedia Encyclopedic summaries

Recommended Workflows

Chaining tools gives better results than using a single one:

Goal Workflow
Deep Research search_webfetch_page → retry with search_web(provider="exa") for JS-heavy pages
Technical Audit search_githubget_github_issue on top results
Bug Fixing search_web for error strings → fetch_page on relevant results
Trend Analysis search_reddit + search_hackernews + search_x

Edge Cases & Known Quirks

Scenario Affected Tools Expected Result
Empty query Most search tools "Query cannot be empty"
Invalid URL fetch_page UnsupportedProtocol or graceful error
404 / Not Found get_github_issue Clean not found message
Large pages fetch_page Content truncated with warning
Invalid domain search_web(domain=...) No results found
  • fetch_page Bot Detection: Uses an auto backend (tries httpx → falls back to curl with TLS impersonation). If Cloudflare blocks you, try backend="curl".
  • search_arxiv Upstream: arXiv API occasionally returns HTTP 503 during maintenance — retry after a few minutes.

Design Decisions

The project is built for low-friction expansion. Each search engine or utility is an isolated module, preventing cross-module bugs.

1. Modular Tooling

Each tool is a standalone function in its own module. A bug in the Reddit parser won't crash GitHub search.

2. Schema-First API

All inputs and outputs validated via Pydantic. The LLM receives consistent data shapes, reducing hallucination and client-side parsing errors.

3. Unified Error Shape

Every tool returns a consistent ErrorResponse via _utils/formatting.py, so the LLM can distinguish auth failures from rate limits and pivot accordingly.

4. Keyless-First Approach

Most tools (Reddit, HN, Wikipedia, arXiv, DuckDuckGo) work with zero configuration. Auth is required only for X/Twitter and optional for Exa AI.

5. Depth-Based Enrichment

Reddit and GitHub use a tiered pipeline balancing latency against depth:

  • Quick: Raw search results only
  • Default: Top results + basic metadata
  • Deep: Full comment enrichment and threaded conversations

Plugin

For Claude Code users, install as a plugin to get both the MCP tools and specialized research skills:

/plugin marketplace add sydasif/web-search-mcp
/plugin install web-search@sydasif-web-search-mcp
/reload-plugins

Available Skills

  • /web-search:research — Autonomous multi-source research across 7+ platforms
  • /web-search:debug — Evidence-based debugging using web search and Stack Overflow

Development

Coding Standards

  • Imports: Absolute imports only
  • Naming: snake_case for functions, PascalCase for classes
  • Types: Modern union syntax (str | None)
  • Errors: All tool errors wrapped in format_error() from _utils/formatting.py

Adding a New Tool

  1. Implement — Create a new module in search/, social/, or tools/
  2. Register — Add @mcp.tool() in server.py
  3. Validate — Define Pydantic models in _models/ if needed
  4. Test — Add a corresponding test in tests/

Git Workflow

  • Commits: Conventional Commits (feat:, fix:, refactor:, test:, chore:)
  • Pre-commit: Run uv run ruff check . && uv run pytest before pushing
  • Branches: Use feature branches for all new work

Note: See CLAUDE.md in the repo for common commands (testing, linting, type checking).