search-mcp
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., "@search-mcp what happened in the Champions League final last night?"
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.
search-mcp
An MCP server with one tool: broad web search for current,
time-sensitive information. It returns short snippets (title, url, snippet), not full pages. It is backed by
the keyless multi-engine ddgs library, which fans out across several web search
engines with fallback (its encyclopedia engines, Wikipedia and Grokipedia, are left out: encyclopedic hits are
the wrong answer for current events).
It is deliberately small. It is meant to sit next to other, non-overlapping tools (an offline encyclopedia, a curated news feed, structured local data), so a small local model can pick the right tool from the docstrings alone. Design rationale: CLAUDE.md.
Tool
web_search(query, max_results=10, region=None)
arg | |
| sent to the engines verbatim, never rewritten |
| 1–25, default 10 |
|
|
Every result is one JSON text block with a status field. Callers branch on it, never on prose:
{"status":"ok","query":"...","backend":"auto-web","region":"wt-wt","safesearch":"moderate","max_results":10,
"attempts":1,"count":2,"results":[{"title":"...","url":"https://...","snippet":"..."}]}ok: the search ran and returned results. (results:[]is reserved for a backend that can prove a search was empty; ddgs can't, see below.)refused: input the caller can fix (blank query,max_resultsout of range, malformed region), withreasonandadvice. It is returned as a normal result, never raised.error: the search backend failed (blocked, rate-limited, timed out, network down), withkindanddetail. A backend outage is always reported as an error, never as an empty result. A failed search is retried server-side first (SEARCH_ATTEMPTS, default 2), because a second try with a different engine order often succeeds. Every result echoesattempts, so anerrorhas already been retried.kind:"empty_or_blocked"means no engine returned anything: ddgs counts an engine that blocks or rate-limits it as "no results", so it can't tell an obscure query from a blocked server. One reworded retry is reasonable; otherwise treat search as unavailable.
All resolved parameters are echoed back, so a result is reproducible. The tool declares a title and all four
MCP hints: read-only, non-destructive, idempotent, open-world.
Related MCP server: DuckDuckGo MCP Server
Run
uv sync
uv run search-mcp serve # stdio, for a local MCP client
SEARCH_MCP_TOKEN=secret uv run search-mcp serve --transport http --host 0.0.0.0 --port 8000 # streamable-http at /mcp
uv run pytest # no network: the backend is fakedenv | default | |
| unset | bearer token required on HTTP ( |
|
| seconds ddgs waits on each batch of engines |
|
| backend calls per search before reporting an error (each reshuffles the engines) |
| unset | optional outbound proxy for ddgs (read by the library itself) |
TLS note: behind a TLS-inspecting proxy,
uvmay reportUnknownIssuer. Pass--system-certs(or setUV_NATIVE_TLS=1) so it trusts the OS certificate store.
Claude Desktop / Claude Code (stdio)
{
"mcpServers": {
"search": { "command": "uv", "args": ["--directory", "/path/to/search-mcp", "run", "search-mcp", "serve"] }
}
}Docker
docker build -t search-mcp .
docker run --rm -p 8000:8000 -e SEARCH_MCP_TOKEN=... search-mcpThe server is stateless: no database, no volume. It needs outbound HTTPS to the public search engines.
Auth and exposure
Auth is deliberately simple: stdio, or streamable-HTTP with a single bearer token (SEARCH_MCP_TOKEN) on a
private network, for example behind mcpo. There is no OAuth, no users
and no audit log, by design. To publish it more widely, put a management layer in front of it: an MCP
gateway or auth proxy that handles OAuth, users and audit for all your servers at once.
A note on the backend
ddgs gets its results by scraping search-engine result pages. It needs no API key, but it is not a sanctioned
API, and engines may rate-limit or block it. That shows up here as status:"error". The backend sits behind a
single function (src/search_mcp/backend.py), so a sanctioned API (Brave, Mojeek) or a self-hosted SearXNG can
replace it by editing that one file.
AI assistance
search-mcp is developed openly with the help of Claude (Anthropic). Commits Claude helped write carry a
Co-Authored-By: Claude trailer. The code and design are open source so the work can be inspected, reused, and
given back.
License
MPL-2.0 © Daniel Núñez.
Available Tools
1 toolweb_searchWeb searchARead-onlyIdempotent
Search the web for CURRENT information: news, current events, anything recent/latest/today/this week, weather, prices, time-sensitive facts. Do NOT use for general knowledge like recipes, definitions, or history — those have better tools. Returns snippets (title, url, snippet), not full pages.
Args:
query: what to search for, sent to the search engines exactly as written.
max_results: how many results (default 10, allowed 1-25).
region: optional region code `country-lang`, e.g. "us-en", "es-es", "de-de"; default "wt-wt" (no region).
Inputs: query (required), region, max_results.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 1 tool
With only one tool, there is no possibility of confusing it with another. Its purpose is clearly limited to current/timely web search, with explicit negative guidance for general knowledge.
A single tool named `web_search` is descriptive, readable, and uses consistent snake_case. There is no pattern to violate or mix.
One tool is thin even for a narrow search server, though it may be intentional. The surface feels minimal rather than clearly well-scoped across typical search needs.
The tool covers core web search with useful parameters like region and result count. Minor gaps remain, such as no page-content retrieval or specialized news/image search, but the stated snippet-only behavior is clear.
Maintenance
Related MCP Connectors
Executes live web/news search queries and returns clean, token-pruned results with zero ad bloat.
Search the web, images, videos, news, and local businesses with robust filters, freshness controls…
Multi-engine web and platform search, news, Google Maps places, page reading, sitemaps, and trends.
Live web search, news from 45+ countries, full article text and research papers for AI agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables free web searching using Google search results without the need for API keys or authentication. It returns structured data including titles, URLs, and descriptions with configurable result limits.28 npm1MIT
- AlicenseAqualityDmaintenanceProvides web and news search via DuckDuckGo with support for region filtering, time ranges, and token optimization for AI assistants.240,629 npm1MIT
- AlicenseAqualityCmaintenanceEnables keyless multi-engine web, news, image, and video metasearch plus full-page markdown extraction for AI agents over MCP, with resilient fallback across DuckDuckGo, Bing, Brave, Google, and other backends.6MIT
- AlicenseNot gradedqualityCmaintenanceEnables free web searches using DuckDuckGo results without requiring API keys or authentication, returning structured titles, URLs, and descriptions with a configurable result limit.28 npmMIT