ddg-search
ddg-search
Un servidor MCP de búsqueda DuckDuckGo que se niega a tener un solo punto de fallo. Un solo proceso, varios backends, conmutación automática por error y mensajes de error honestos.
La idea
La búsqueda web es infraestructura crítica para agentes de programación, y falla de maneras aburridas: límites de tasa, detección de bots, o que a tu proveedor de VPS le dé un mal día. La mayoría de los servidores te dan un cliente HTTP y esperanzas. Este enruta cada consulta a través de varios backends — un buscador local en esta máquina más cualquier número de instancias remotas de duckduckgo-mcp-server que estés ejecutando — y sigue intentando hasta que algo responde o la cuenta se agota.
Los backends que fallan entran en timeout. Los que se portan bien reciben más tráfico. Tú recibes los resultados como un bloque compacto, con una nota de una línea sobre quién los sirvió.
Related MCP server: DuckDuckGo Search MCP Server
Instalación
Requiere Python 3.10+ y uv.
git clone <this repo> ~/.local/share/mcp/ddg-search # or anywhere you like
cd ~/.local/share/mcp/ddg-search
uv syncEsa es toda la ceremonia. uv sync crea .venv, bloquea dependencias e instala el paquete en modo editable, de modo que los cambios en src/ se aplican al reiniciar.
Conecta con tu agente
Cualquier cliente MCP que hable stdio funciona. Para una configuración de estilo mcp.json:
{
"mcpServers": {
"ddg-search": {
"type": "stdio",
"command": "/path/to/ddg-search/.venv/bin/python",
"args": ["-m", "ddg_search.server"],
"env": {
"DDG_SAFE_SEARCH": "OFF",
"DDG_SEARCH_BACKEND": "auto"
},
"timeout": 60000
}
}
}DDG_SAFE_SEARCH filtra contenido solo — no hace nada contra la detección de bots y está desactivado por defecto porque los agentes que investigan prefieren resultados completos, no una supervisión.
Herramientas
search
Argumento | Tipo | Default | Notas |
| string | obligatorio | Los sustantivos concretos superan a las palabras sueltas ambiguas |
| int | 10 | El upstream limita a unos 10–11 sin importar qué pidas |
| string |
| Código de región de DuckDuckGo |
|
|
| Manual omite la clasificación de salud |
| string |
| Nombre/alias IP de backend (modo manual) |
| list |
| Cadena ordenada de respaldo (modo manual) |
Los resultados se devuelven compactos a propósito:
via relay-b
3 results:
1. Some Page Title
https://example.com/page
The snippet text, labels stripped, no blank lines eating your tokens.
2. ...Cada respuesta indica qué backend la sirvió. Los intentos fallidos aparecen listados bajo Attempts: con una etiqueta que te dice dónde se rompió:
Etiqueta | Significado |
| DuckDuckGo devolvió cero coincidencias — sin resultados reales o bot-flag silencioso, indistinguible desde aquí |
| El cliente de esta máquina falló. No culpes a los hosts remotos |
| Un remoto respondió mal |
| El presupuesto de 25 s se agotó mientras se esperaba |
Cuando algo se rompe, hay una ruta de registro
El router distingue «Internet está siendo Internet» de «esta herramienta está realmente rota». Los timeouts y los conjuntos sin resultados solo reciben su [tag]. Pero cuando un intento falla de una forma que implica que algo falló en tu lado — errores de transporte local, backends remotos que responden mal — la respuesta termina con:
log: /path/to/ddg-search/logs/20260822T090206-remote-tool-error.jsonEse archivo contiene todo lo necesario para reproducir y diagnosticar: la consulta exacta y los argumentos, cada intento con su detalle de error y una foto del estado de cada backend en ese momento. Con puta DDG_SEARCH_LOGS_DIR a donde quieras si lo prefieres; nunca se escribe log por timeouts ni por resultados vacíos.
status
Tabla de backends: indicador de conexión, intentos observados en el último minuto, último estado y caducidad de la penalización. Pasa probe: true para comprobar la conexión real con los backends remotos en lugar de confiar en el estado en caché.
Configuración
Variables de entorno, todas opcionales:
Variable | Default | Propósito |
|
|
|
|
| Transporte local: |
|
| Presupuesto total de búsqueda en todos los backends |
|
| Penalización de timeout por backend |
|
| Penalización de error por backend |
|
| Espera de verificación por backend para |
|
| Directorio de estado del router |
Los backends viven en src/ddg_search/config.py. La flota por defecto es local (esta máquina) más dos relay remotos; ajusta la tupla para que coincida con tu propia infraestructura.
Comportamiento que vale la pena saber
La conmutación por error prefiere backends sanos y con menos intentos recientes, así que aníta el tráfico en lugar de golpear a una sola máquina.
Los enfriamientos son por backend y con límite temporal: un timeout relega al backend durante 4 90 s y una falla suave durante 30 s. 90s? They said 90s and 30s. okay: Timeout: 90s, soft error: 30s. But the table says 90000 y 30000. In the bullet: "a timeout sits a block out for 90s, a soft failure for 30s."
El estado sobrevive a reinicios en
state/router-state.json. Bórralo si quieres amnesia; el servidor lo recrea en el siguiente arranque.
Una pequeña rareza merece su propio párrafo. DuckDuckGo sirve páginas vacías mientras él no confía en el cliente, así que «sin resultados» puede significar tanto ningún resultado genuino como bloqueo silencioso por bot — no es posible distinguirlos, y el router no actúa como si fuera posible. Trata un resultado vacío como fallo e intenta el siguiente backend; si todos dan vacío, recibes un mensaje que evidencia exactamente la ambigüedad del resultado.
Última cosa: el límite de 30 peticiones/minuto se aplica en cada instancia del duckduckgo-mcp-server, no en esta capa. El router distribuye la carga entre backend, pero no puede inventar una capacidad que no tiene.
Configuración de tus propios relays
Cualquier máquina que pueda ejecutar el servidor estándar sirve como backend:
pip install 'duckduckgo-mcp-server[browser]'
python -m duckduckgo_mcp_server.main --transport streamable-http --host 0.0.0.0 --port 18082Apunta un BackendConfig(url="http://that-host/ddg-mcp") a él. El directorio realip/ contiene un lanzador usado por una unidad systemd para ejecutar un relay detrás de mullvad-exclude en IP de cliente final — útil si el tráfico de salida de tu data center recibe peor tratamiento de captcha que una conexión doméstica.
Desarrollo
uv sync # install everything including dev tools
uv run pytest # 26 tests, no network needed except one optional live check
uv run ruff check src tests # lint
uv run ruff format src tests # format
uv run pyrefly check # static typesPara una prueba manual rápida de humo por el router completo:
uv run python -c "import asyncio; from ddg_search.router import SearchRouter; \
print(asyncio.run(SearchRouter().search('crawl4ai', 3, '', 'auto', None, None, None)))"Ver también
fast-webfetch-mcp — la otra mitad: abre las páginas que encuentran estas búsquedas, vía un navegador crawl captchAI
Model Context Protocol — qué significa «MCP»
duckduckgo-mcp-server — la librería de búsqueda que rasca debajo de todo
Licencia
MIT.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides web search functionality via DuckDuckGo for Claude Code and MCP-compatible clients, featuring advanced content exploration, navigation across search results, and detailed webpage analysis.316MIT
- FlicenseNot gradedqualityCmaintenanceBrings DuckDuckGo search (web, news, images, videos) to any MCP-compatible AI client without requiring an API key.
- FlicenseNot gradedqualityDmaintenanceMCP server that provides web search scraping from DuckDuckGo (with Mojeek fallback) and URL content fetching as markdown/text or raw HTML.1
- AlicenseAqualityBmaintenanceMCP server for DuckDuckGo web search, enabling AI agents to perform real-time text, news, and image searches without an API key.3MIT
Related MCP Connectors
Serper MCP — wraps the Serper Google Search API (serper.dev)
Stealth web browser for agents: search, fetch, click and type through persistent sessions over MCP.
Agentic search over your Dewey document collections from any MCP-compatible client.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- 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/NikkeTryHard/ddg-search'
If you have feedback or need assistance with the MCP directory API, please join our Discord server