HasData DuckDuckGo MCP Server

Búsqueda de DuckDuckGo como JSON con resultados orgánicos clasificados, anuncios en su propio array y 37 regiones.

Documentación

Servidor MCP de DuckDuckGo

Un servidor de Protocolo de Contexto de Modelo (MCP) alojado que brinda a Claude, Cursor, Windsurf y cualquier otro cliente MCP resultados de búsqueda de DuckDuckGo como JSON estructurado. Resultados orgánicos clasificados con posiciones, anuncios en su propio arreglo, la respuesta de IA propia de DuckDuckGo y 37 regiones para segmentar. Diseñado para volumen y para análisis, sin navegador local ni cadena de respaldo que configurar.

https://mcp.hasdata.com/api/mcp?apis=duckduckgo

Glama score tool contract MCP Regions npm PyPI License

Contenido

Lo que necesitas

Un cliente MCP que hable HTTP transmisible con encabezados personalizados. Una clave de API de HasData desde el panel, gratuita de crear. Nada más. Este es un servidor remoto, por lo que la ruta más simple es una URL y un encabezado, sin paquete de navegador que agregar ni proceso local que mantener. Un cliente solo-stdio puede usar el lanzador @hasdata/duckduckgo-mcp (npm) o hasdata-duckduckgo-mcp (PyPI) en su lugar.

Inicio rápido

La URL del servidor es la misma para cada cliente. Lo ejecutamos de forma práctica en Claude Code y Claude Desktop. Los otros bloques siguen el formato documentado de cada cliente para un servidor remoto.

CampoValor
URLhttps://mcp.hasdata.com/api/mcp?apis=duckduckgo
TransporteHTTP, transmisible
Encabezado de autenticaciónx-api-key: HASDATA_API_KEY

Los clientes con soporte OAuth pueden agregar la misma URL como conector e iniciar sesión sin poner una clave en un archivo de configuración.

Claude Code
claude mcp add --transport http duckduckgo "https://mcp.hasdata.com/api/mcp?apis=duckduckgo" \
  --header "x-api-key: HASDATA_API_KEY"
Claude Desktop

Configuración, luego Conectores, luego Agregar conector personalizado, luego pega https://mcp.hasdata.com/api/mcp?apis=duckduckgo e inicia sesión.

Para la ruta de archivo de configuración, Claude Desktop carga solo servidores locales (stdio), por lo que llega a un servidor remoto a través de un lanzador stdio. El paquete @hasdata/duckduckgo-mcp es ese lanzador, y lee la clave del entorno. Agrega esto a claude_desktop_config.json:

{
  "mcpServers": {
    "duckduckgo": {
      "command": "npx",
      "args": ["-y", "@hasdata/duckduckgo-mcp"],
      "env": { "HASDATA_API_KEY": "YOUR_KEY" }
    }
  }
}

¿Python en lugar de Node? Cambia el lanzador por el paquete de PyPI, que uvx ejecuta sin instalación manual:

{
  "mcpServers": {
    "duckduckgo": {
      "command": "uvx",
      "args": ["hasdata-duckduckgo-mcp"],
      "env": { "HASDATA_API_KEY": "YOUR_KEY" }
    }
  }
}
Cursor

~/.cursor/mcp.json para cada proyecto, o .cursor/mcp.json para uno solo:

{
  "mcpServers": {
    "duckduckgo": {
      "url": "https://mcp.hasdata.com/api/mcp?apis=duckduckgo",
      "headers": { "x-api-key": "HASDATA_API_KEY" }
    }
  }
}
Windsurf

~/.codeium/windsurf/mcp_config.json. Windsurf llama al campo serverUrl, no url:

{
  "mcpServers": {
    "duckduckgo": {
      "serverUrl": "https://mcp.hasdata.com/api/mcp?apis=duckduckgo",
      "headers": { "x-api-key": "HASDATA_API_KEY" }
    }
  }
}
Cline
{
  "mcpServers": {
    "duckduckgo": {
      "url": "https://mcp.hasdata.com/api/mcp?apis=duckduckgo",
      "type": "streamableHttp",
      "headers": { "x-api-key": "HASDATA_API_KEY" },
      "disabled": false
    }
  }
}
VS Code

.vscode/mcp.json en el espacio de trabajo:

{
  "servers": {
    "duckduckgo": {
      "type": "http",
      "url": "https://mcp.hasdata.com/api/mcp?apis=duckduckgo",
      "headers": { "x-api-key": "HASDATA_API_KEY" }
    }
  }
}
Codex CLI

~/.codex/config.toml:

[mcp_servers.duckduckgo]
url = "https://mcp.hasdata.com/api/mcp?apis=duckduckgo"

[mcp_servers.duckduckgo.headers]
"x-api-key" = "HASDATA_API_KEY"
Gemini CLI

~/.gemini/settings.json:

{
  "mcpServers": {
    "duckduckgo": {
      "httpUrl": "https://mcp.hasdata.com/api/mcp?apis=duckduckgo",
      "headers": { "x-api-key": "HASDATA_API_KEY" }
    }
  }
}

Ejemplos de indicaciones

Indicaciones, no código. Pega una y el agente llama a la herramienta por sí mismo. Cada una está anotada con las llamadas que requiere, porque en MCP el modelo decide cuántas llamadas hacer y cada llamada exitosa cuesta 10 créditos.

Busca en DuckDuckGo "model context protocol" y dame los diez mejores resultados con sus posiciones y dominios.

Una llamada, 10 créditos.

Ejecuta la consulta "vpn review" en la región alemana y nuevamente en la región de EE. UU., luego dime qué dominios aparecen en una y no en la otra.

Dos llamadas, 20 créditos. La región es un parámetro. La misma consulta en dos mercados son dos llamadas.

Busca "best crm software" y lista solo las colocaciones pagadas, con el dominio del anunciante para cada una.

Una llamada, 10 créditos. Los anuncios llegan en su propio arreglo y no necesitan heurísticas de filtrado.

Toma la consulta "model context protocol" y recorre las primeras tres páginas, luego dime qué dominios tienen más de una posición.

Tres llamadas, 30 créditos. Cada página después de la primera es una llamada nueva con el cursor, y elimina q de los argumentos una vez que tengas uno.

Busca "who invented the transistor" y muéstrame la respuesta de IA propia de DuckDuckGo junto a los resultados orgánicos en los que se basó.

Una llamada, 10 créditos.

Dos de esos son la razón por la que existe este servidor. La segmentación por región es un parámetro de primera clase en 37 mercados. Comparar una consulta entre países es un bucle y no una configuración de proxy. Y las colocaciones pagadas vuelven por separado de las orgánicas, lo que evita que el seguimiento de clasificación dependa de adivinar qué resultado era un anuncio.

Paginación cuesta una llamada cada vez. Una indicación que recorre diez páginas son diez llamadas y 100 créditos.

Herramientas

Una herramienta. Las muestras a continuación están recortadas de llamadas reales, y los resultados en ellas cambian a medida que cambia la web. Léelas como formas.

Las muestras son la carga útil, no la respuesta completa. Un resultado tools/call lleva un bloque de texto, y ese texto es en sí mismo JSON que contiene url, status, text y json, con los datos extraídos bajo json. Desde una respuesta JSON-RPC cruda, la ruta es result.content[0].text, analizada, luego .json. Un cliente de chat lo desenvuelve por ti y el código que habla directamente con el endpoint no lo hace.

Obtener resultados de búsqueda de DuckDuckGo

hasdata_duckduckgo_serp_getSearchResults

Obtiene una página de resultados de DuckDuckGo y la devuelve analizada.

ParámetroTipoNotas
qstringEl término de búsqueda. Ya sea q o nextPageToken tiene que estar presente
nextPageTokenstringCursor de pagination.nextPageToken en la respuesta anterior. Gana si envías ambos, y el q que enviaste junto a él se ignora sin advertencia
klstringRegión como <country>-<language>, 37 valores desde us-en y de-de hasta jp-jp y wt-wt para sin región
ccstringPaís de dos letras, 36 valores. Una alternativa a kl cuando se combina con setLang
setLangstringIdioma de interfaz y resultados, 33 valores
safeSearchstringoff, moderate o strict
deviceTypestringdesktop, mobile o tablet

Envía ya sea q o nextPageToken. Enviar ninguno devuelve 422 nombrando ambos campos, porque el requisito es condicional y el esquema no puede expresarlo como una lista obligatoria simple. Enviar ambos tampoco es un error, el cursor gana y la consulta no va a ninguna parte, por lo que un agente que mantiene q en los argumentos mientras pagina lee silenciosamente el conjunto de resultados incorrecto.

position cuenta dentro de la página de la que proviene, no en todo el conjunto de resultados. La página dos vuelve con posiciones comenzando en 1 nuevamente, y el tamaño de página tampoco es fijo, por lo que páginas de 10, 15 y 14 resultados aparecen todas. La clasificación absoluta es por lo tanto el número de resultados orgánicos que ya has recopilado más position, no nada que puedas derivar del número de página. Construye un conjunto de datos de clasificación sin eso y cada página contribuye con su propio número uno.

Devuelve organicResults, ads, searchAssist y pagination. Las entradas orgánicas llevan position, title, link, displayedLink, source y snippet, más una fecha, enlaces de sitio y metadatos de video donde DuckDuckGo los muestra. searchAssist contiene la respuesta de IA propia de DuckDuckGo para la consulta.

ads y searchAssist están ausentes cuando la página no tiene ninguno, así que prueba la clave antes de leerla. organicResults también puede estar ausente, así que léelo con un valor predeterminado en lugar de tratar su presencia como dada. Una consulta sin coincidencias reales aún vuelve como una página completa de entradas vagamente relacionadas, que no es como suele verse "nada encontrado".

{
  "organicResults": [
    {
      "position": 1,
      "title": "What is the Model Context Protocol (MCP)?",
      "link": "https://modelcontextprotocol.io/docs/getting-started/intro",
      "displayedLink": "modelcontextprotocol.io › docs › getting-started › intro",
      "source": "modelcontextprotocol.io",
      "snippet": "MCP is an open-source standard for connecting AI applications to external systems."
    }
  ],
  "ads": [
    { "position": 1, "title": "Make Agents Accountable", "link": "https://www.gravitee.io/platform/ai-agent-management" }
  ],
  "searchAssist": {
    "answer": "Model Context Protocol (MCP) is an open standard from Anthropic that lets LLMs connect to external tools, systems, and data sources using a shared interface."
  },
  "pagination": { "nextPageToken": "eyJ1cmwiOiJodHRwczovL2xpbmtzLmR1Y2tkdWNrZ28uY29t…" }
}

Errores y rutas de fallo

Tu cliente casi nunca ve un código de error HTTP de una llamada de herramienta. La capa MCP responde 200 y pone el fallo dentro del resultado, con isError establecido en true y la razón como texto. El agente lee un mensaje donde podrías esperar una línea de estado.

Una clave incorrecta surge como salida de herramienta, no como una conexión fallida. Listar herramientas acepta cualquier clave no vacía, por lo que el cliente completa su protocolo de enlace y muestra verde. La primera llamada de herramienta luego vuelve con isError: true y el texto HasData API error: 401 Unauthorized. Vigila esa cadena, porque nada antes en el flujo informa el problema.

Una clave faltante es el único error HTTP real. La autorización se ejecuta antes de cualquier herramienta, y la conexión misma falla con 401.

Un argumento que rompe el esquema se rechaza antes de convertirse en una búsqueda. El servidor responde con isError: true y el texto MCP error -32602: Input validation error, nombrando el campo. Nada se obtiene y nada se cobra.

Ni q ni nextPageToken devuelve 422 con un arreglo errors nombrando ambos campos y la regla requiredIfNotExists que los une.

Una consulta sin nada detrás aún devuelve resultados. DuckDuckGo decide la relevancia, por lo que una cadena sin sentido vuelve como una página normal de diez entradas vagamente relacionadas con ads y searchAssist ausentes. Nada la marca como un fallo, lo que importa si estás construyendo una alerta sobre "sin cobertura para esta marca".

Los resultados que llevan datos también llevan un requestMetadata.id que vale la pena citar en soporte.

Precios, plan gratuito y límites

Cada llamada cuesta 10 créditos. El número de resultados no cambia el precio. Una página completa cuesta lo mismo que una página con una entrada.

La prueba gratuita es 1,000 créditos durante 30 días sin tarjeta, que son 100 búsquedas. Después de eso, una cuenta activa sigue recibiendo 100 créditos recargados cada día cuando su saldo baja de 100, por lo que un agente de bajo volumen funciona en el plan gratuito indefinidamente.

Los planes pagados comienzan en $49 al mes por 200,000 créditos, que son 20,000 búsquedas. El precio unitario baja con el volumen, desde $2.45 por 1,000 búsquedas en el plan de entrada hasta $0.99 en Business, $0.83 en Growth y $0.75 en los planes de alto volumen más grandes. Los números actuales viven en la página de precios.

Tu plan también establece la concurrencia. La prueba gratuita permite 1 solicitud a la vez, Startup 15, Business 30, Growth 50, y los planes de alto volumen van de 200 a 1,500. Maneja el caso de desbordamiento de manera defensiva en cualquier cosa desatendida, porque un agente que se expande alcanzará el techo antes que tú.

Una solicitud que vuelve no-200 no se factura. Una llamada exitosa que no encuentra nada sigue siendo una llamada.

Selección de herramientas

El parámetro de consulta apis decide qué herramientas ve tu agente. Menos herramientas significa menos contexto gastado en definiciones de herramientas, y menos oportunidades para que el modelo alcance la incorrecta.

?apis=duckduckgo                        the one tool in this repo
?apis=duckduckgo,google_serp            add Google search
?apis=duckduckgo,bing_serp,google_serp  three engines side by side

El parámetro toma nombres de proveedores como duckduckgo y nombres de API individuales como google_maps_search. Los nombres mal escritos se ignoran. Si cada nombre es incorrecto, la solicitud falla con 400, y el cuerpo lista tanto lo que no reconoció como cada valor válido. Elimina el parámetro y el mismo endpoint expone las 57 herramientas de HasData. Tres motores en un solo agente es la razón habitual para ampliar la lista aquí, porque comparar la misma consulta en DuckDuckGo, Google y Bing es una sola instrucción una vez que los tres están expuestos.

Cómo se compara

La alternativa realista es un servidor autoalojado. Los populares son paquetes de Python que ejecutas localmente, llegan a DuckDuckGo desde tu propia máquina y le entregan al modelo un bloque de texto formateado. Eso funciona bien para un asistente de investigación que responde una pregunta a la vez. Deja de funcionar cuando necesitas volumen y una forma estable.

Servidor autoalojadoEste servidor
Lo que devuelve una búsquedaUna cadena de texto formateada creada para que el modelo la leaJSON con position, title, link, displayedLink, source, snippet, fechas y enlaces de sitio
Ubicaciones pagadasEliminadas junto con el resto del ruidoConservadas en un array ads separado
PaginaciónUn límite de max_results en una sola páginaCursor en cada respuesta
RegionesUn código region37 códigos de región, o país e idioma configurados por separado
SafeSearchFijado al iniciar el servidor, deliberadamente no invocable por el agentePor llamada
Quién obtiene la páginaTu máquina, a través de httpx, con un backend curl_cffi opcional y una alternativa a configurarNosotros
RendimientoAutolimitado a 30 búsquedas por minutoConcurrencia del plan, desde 1 en la prueba hasta 1.500
Lo que ejecutasUn entorno de Python, un extra opcional y ajustes de contenedor o proxy cuando no está en localhostUna URL y una cabecera
Extracción de contenido de páginaUna herramienta fetch_contentNo se ofrece
CosteGratis10 créditos por llamada

Dos filas cargan con la mayor parte de la decisión. Un bloque de texto es la salida correcta para una respuesta de chat y la incorrecta para un conjunto de datos de ranking, porque reconstruir position a partir de prosa es trabajo que no deberías estar haciendo. Y que la obtención sea nuestra significa que la cuestión del backend desaparece, junto con elegir entre httpx y un cliente que imita al navegador, instalar el extra del que depende la alternativa y leer un rastreo de pila cuando un cliente HTTP simple deja de recibir una página.

Todo lo demás en esa lista es un verdadero intercambio. Un servidor autoalojado es gratuito, no necesita cuenta, mantiene tus consultas en tu propia máquina y obtiene contenido de página, algo que este servidor no hace. Si ejecutas un puñado de búsquedas al día dentro de un asistente, es la mejor opción. Este es para el caso en el que el número de búsquedas, el número de regiones o la forma de la salida empiezan a importar.

Frente a la propia API de DuckDuckGo. api.duckduckgo.com es la API de Instant Answer, y devuelve un resumen enciclopédico cuando existe en lugar de una página de resultados. No hay un endpoint oficial que te entregue resultados web clasificados, por eso cada opción aquí analiza la página.

Lo que este servidor no hace. Sin obtención de páginas ni extracción de contenido, sin verticales de imágenes o noticias, sin autocompletado. Devuelve la página de resultados, analizada.

Preguntas frecuentes

¿Existe un servidor MCP oficial de DuckDuckGo?

No. DuckDuckGo no publica ningún servidor MCP. Cada opción está construida por otra persona. La mayoría son proyectos de código abierto que se ejecutan localmente, y este es un servidor alojado mantenido por HasData.

¿Qué es un servidor MCP de DuckDuckGo?

Un servidor que expone la búsqueda de DuckDuckGo como una herramienta que un cliente de IA puede invocar. El cliente envía una llamada de herramienta a través del Model Context Protocol, el servidor ejecuta la búsqueda y devuelve JSON estructurado, y el modelo trabaja con el resultado y nunca ve una página de HTML.

¿Necesito una cuenta de DuckDuckGo o una clave de API?

No. La única credencial es tu clave de HasData. DuckDuckGo no tiene un programa de desarrolladores al que registrarse, y la API de Instant Answer que sí publica no devuelve resultados de búsqueda.

¿Necesito alojar o ejecutar algo?

No. Este es un servidor MCP remoto en HTTP transmisible. Nada que instalar, sin entorno de Python, sin paquete de navegador, sin proceso que reiniciar.

¿Los datos son en vivo o en caché?

En vivo. Cada llamada obtiene la página de resultados en el momento de la solicitud y lleva su propio requestMetadata.id. Dos llamadas idénticas son dos obtenciones separadas y no una reproducción de una copia almacenada.

¿Puedo comparar la misma consulta entre regiones?

Sí, y esa es la razón principal para usar un parámetro en lugar de un proxy. kl acepta 37 códigos de región, y cc con setLang separa país e idioma cuando necesitas distinguirlos. Cada región es su propia llamada.

¿Qué ocurre cuando DuckDuckGo cambia su diseño?

Nada por tu parte. Nosotros seguimos los cambios y mantenemos estable el esquema de respuesta, así que los nombres y tipos de campos permanecen. Un bloque sin nada que informar está ausente de la respuesta, así que lee ads y searchAssist con un valor predeterminado.

¿Puedo usar esto junto con otras APIs de HasData?

Sí. El parámetro apis acepta una lista, y ?apis=duckduckgo,google_serp,bing_serp le da a tu agente tres motores de búsqueda a la vez.

¿Puedo iniciar sesión con OAuth en lugar de pegar una clave?

Sí, en clientes que lo admitan. Claude Desktop y Cursor pueden añadir el endpoint como conector e iniciar sesión. Los agentes y scripts no supervisados usan la cabecera x-api-key.

Cumplimiento y datos personales

HasData accede únicamente a datos disponibles públicamente. Los términos de una plataforma pueden restringir el acceso automatizado, y tú eres responsable de tu propio cumplimiento. Cuando los datos que recopilas incluyan información personal, asegúrate de tener una base legal para ello según el GDPR, la CCPA o las normas equivalentes en tu jurisdicción.

Enlaces de HasData

Página de producto y constructor de solicitudesDuckDuckGo SERP API
Documentación del servidorMCP server docs
Las 57 herramientas en un solo servidorHasData/hasdata-mcp
Tutoriales para clientesMCP clients and integrations
Los otros motores de búsqueda que analizamosGoogle, Bing and 53 more APIs
Planes y costes de créditosPlans and credit costs
Claves y usoHasData dashboard
Lanzador de Node en npm@hasdata/duckduckgo-mcp
Lanzador de Python en PyPIhasdata-duckduckgo-mcp

Desarrollo

Este repositorio es configuración y documentación para un servidor remoto. No hay paso de compilación ni nada que contenerizar.

Las pruebas en test/ verifican el contrato de la herramienta, la parte que puede romperse sin un commit aquí. Comprueban que ?apis=duckduckgo devuelve exactamente una herramienta, que su nombre no ha cambiado, que los parámetros que documenta este README siguen existiendo con las enumeraciones que cita, y que la clave en uso es realmente aceptada. Esa última comprobación ejecuta una búsqueda real y cuesta 10 créditos, que es el precio de un canario que puede fallar por la razón correcta.

# macOS and Linux
HASDATA_API_KEY=your_key_here npm test

# Windows PowerShell
$env:HASDATA_API_KEY="your_key_here"; npm test

La misma suite se ejecuta en CI en cada push y una vez a la semana en un horario, porque la lista de herramientas ascendente puede cambiar sin que nadie toque este repositorio. Un fallo significa que la lista de herramientas se movió, la clave dejó de funcionar o el endpoint era inalcanzable, y el mensaje de la aserción indica cuál.

Contribuciones

Las correcciones a la tabla de parámetros y a la muestra de respuesta son la contribución más útil, porque esas son las partes que se desvían. Incluye la llamada que hiciste y la respuesta que obtuviste. Las solicitudes de extracción desde bifurcaciones ejecutan la suite sin clave, y las comprobaciones en vivo se omiten en lugar de ponerse en rojo.

Licencia

MIT. Ver LICENSE.