-
Notifications
You must be signed in to change notification settings - Fork 8
Home
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.
- Python 3.11+
-
uv — install it with
curl -LsSf https://astral.sh/uv/install.sh | sh
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.gitMost 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).
Once running, try:
search_web(query="current weather in Tokyo")
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) |
| 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 |
Chaining tools gives better results than using a single one:
| Goal | Workflow |
|---|---|
| Deep Research |
search_web → fetch_page → retry with search_web(provider="exa") for JS-heavy pages |
| Technical Audit |
search_github → get_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
|
| 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_pageBot Detection: Uses anautobackend (trieshttpx→ falls back tocurlwith TLS impersonation). If Cloudflare blocks you, trybackend="curl". -
search_arxivUpstream: arXiv API occasionally returns HTTP 503 during maintenance — retry after a few minutes.
The project is built for low-friction expansion. Each search engine or utility is an isolated module, preventing cross-module bugs.
Each tool is a standalone function in its own module. A bug in the Reddit parser won't crash GitHub search.
All inputs and outputs validated via Pydantic. The LLM receives consistent data shapes, reducing hallucination and client-side parsing errors.
Every tool returns a consistent ErrorResponse via _utils/formatting.py, so the LLM can distinguish auth failures from rate limits and pivot accordingly.
Most tools (Reddit, HN, Wikipedia, arXiv, DuckDuckGo) work with zero configuration. Auth is required only for X/Twitter and optional for Exa AI.
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
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-
/web-search:research— Autonomous multi-source research across 7+ platforms -
/web-search:debug— Evidence-based debugging using web search and Stack Overflow
- Imports: Absolute imports only
-
Naming:
snake_casefor functions,PascalCasefor classes -
Types: Modern union syntax (
str | None) -
Errors: All tool errors wrapped in
format_error()from_utils/formatting.py
-
Implement — Create a new module in
search/,social/, ortools/ -
Register — Add
@mcp.tool()inserver.py -
Validate — Define Pydantic models in
_models/if needed -
Test — Add a corresponding test in
tests/
-
Commits: Conventional Commits (
feat:,fix:,refactor:,test:,chore:) -
Pre-commit: Run
uv run ruff check . && uv run pytestbefore pushing - Branches: Use feature branches for all new work
Note: See
CLAUDE.mdin the repo for common commands (testing, linting, type checking).