HasData DuckDuckGo MCP Server
Pesquisa DuckDuckGo como JSON com resultados orgânicos ranqueados, anúncios em sua própria matriz e 37 regiões.
Documentação
Servidor MCP DuckDuckGo
Um servidor de Protocolo de Contexto de Modelo (MCP) hospedado que fornece ao Claude, Cursor, Windsurf e qualquer outro cliente MCP resultados de busca do DuckDuckGo como JSON estruturado. Resultados orgânicos ranqueados com posições, anúncios em sua própria matriz, a resposta de IA do próprio DuckDuckGo e 37 regiões para segmentar. Construído para volume e para análise, sem navegador local e sem cadeia de fallback para configurar.
https://mcp.hasdata.com/api/mcp?apis=duckduckgo
Conteúdo
- O que você precisa
- Início rápido
- Exemplos de prompts
- Ferramentas
- Erros e caminhos de falha
- Preços, camada gratuita e limites
- Seleção de ferramentas
- Como se compara
- Perguntas frequentes
- Links HasData
- Desenvolvimento
- Contribuição
- Licença
O que você precisa
Um cliente MCP que fale HTTP transmissível com cabeçalhos personalizados. Uma chave de API HasData do painel, gratuita para criar. Nada mais. Este é um servidor remoto, então o caminho mais simples é uma URL e um cabeçalho, sem pacote de navegador para adicionar e sem processo local para manter. Um cliente somente stdio pode usar o lançador @hasdata/duckduckgo-mcp (npm) ou hasdata-duckduckgo-mcp (PyPI).
Início rápido
A URL do servidor é a mesma para todos os clientes. Nós a executamos na prática no Claude Code e no Claude Desktop. Os outros blocos seguem o formato documentado de cada cliente para um servidor remoto.
| Campo | Valor |
|---|---|
| URL | https://mcp.hasdata.com/api/mcp?apis=duckduckgo |
| Transporte | HTTP, transmissível |
| Cabeçalho de autenticação | x-api-key: HASDATA_API_KEY |
Clientes com suporte a OAuth podem adicionar a mesma URL como conector e entrar sem colocar uma chave em um arquivo de configuração.
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
Configurações, depois Conectores, depois Adicionar conector personalizado, depois cole https://mcp.hasdata.com/api/mcp?apis=duckduckgo e entre.
Para o caminho de arquivo de configuração, o Claude Desktop carrega apenas servidores locais (stdio), então ele alcança um servidor remoto por meio de um lançador stdio. O pacote @hasdata/duckduckgo-mcp é esse lançador, e ele lê a chave do ambiente. Adicione isto a claude_desktop_config.json:
{
"mcpServers": {
"duckduckgo": {
"command": "npx",
"args": ["-y", "@hasdata/duckduckgo-mcp"],
"env": { "HASDATA_API_KEY": "YOUR_KEY" }
}
}
}
Prefere Python em vez de Node? Troque o lançador pelo pacote PyPI, que uvx executa sem instalação manual:
{
"mcpServers": {
"duckduckgo": {
"command": "uvx",
"args": ["hasdata-duckduckgo-mcp"],
"env": { "HASDATA_API_KEY": "YOUR_KEY" }
}
}
}
Cursor
~/.cursor/mcp.json para cada projeto, ou .cursor/mcp.json para um:
{
"mcpServers": {
"duckduckgo": {
"url": "https://mcp.hasdata.com/api/mcp?apis=duckduckgo",
"headers": { "x-api-key": "HASDATA_API_KEY" }
}
}
}
Windsurf
~/.codeium/windsurf/mcp_config.json. O Windsurf chama o campo serverUrl, não 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 no espaço de trabalho:
{
"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" }
}
}
}
Exemplos de prompts
Prompts, não código. Cole um e o agente chama a ferramenta sozinho. Cada um é anotado com as chamadas que faz, porque no MCP o modelo decide quantas chamadas fazer e cada chamada bem-sucedida custa 10 créditos.
Pesquise no DuckDuckGo por "model context protocol" e me dê os dez principais resultados com suas posições e domínios.
Uma chamada, 10 créditos.
Execute a consulta "vpn review" na região alemã e novamente na região dos EUA, depois me diga quais domínios aparecem em uma e não na outra.
Duas chamadas, 20 créditos. Região é um parâmetro. A mesma consulta em dois mercados são duas chamadas.
Pesquise por "best crm software" e liste apenas os posicionamentos pagos, com o domínio do anunciante para cada um.
Uma chamada, 10 créditos. Os anúncios chegam em sua própria matriz e não precisam de heurísticas de filtragem.
Pegue a consulta "model context protocol" e percorra as três primeiras páginas, depois me diga quais domínios ocupam mais de uma posição.
Três chamadas, 30 créditos. Cada página após a primeira é uma nova chamada com o cursor, e remova q dos argumentos assim que tiver um.
Pesquise "who invented the transistor" e mostre a resposta de IA do próprio DuckDuckGo ao lado dos resultados orgânicos em que ela se baseou.
Uma chamada, 10 créditos.
Duas dessas são a razão pela qual este servidor existe. A segmentação por região é um parâmetro de primeira classe em 37 mercados. Comparar uma consulta entre países é um loop e não uma configuração de proxy. E os posicionamentos pagos voltam separadamente dos orgânicos, o que impede que o rastreamento de classificação dependa de adivinhar qual resultado era um anúncio.
Paginção custa uma chamada por vez. Um prompt que percorre dez páginas são dez chamadas e 100 créditos.
Ferramentas
Uma ferramenta. As amostras abaixo são reduzidas de chamadas reais, e os resultados nelas mudam conforme a web muda. Leia-as como formatos.
As amostras são o payload, não a resposta inteira. Um resultado tools/call carrega um bloco de texto, e esse texto é ele próprio JSON contendo url, status, text e json, com os dados raspados sob json. De uma resposta JSON-RPC bruta, o caminho é result.content[0].text, analisado, depois .json. Um cliente de chat desembrulha isso para você, e código que fala diretamente com o endpoint não faz.
Obter resultados de busca do DuckDuckGo
hasdata_duckduckgo_serp_getSearchResults
Busca uma página de resultados do DuckDuckGo e a retorna analisada.
| Parâmetro | Tipo | Observações |
|---|---|---|
q | string | O termo de busca. Ou q ou nextPageToken tem que estar presente |
nextPageToken | string | Cursor de pagination.nextPageToken na resposta anterior. Vence se você enviar ambos, e o q que você enviou junto é ignorado sem aviso |
kl | string | Região como <country>-<language>, 37 valores de us-en e de-de a jp-jp e wt-wt para sem região |
cc | string | País de duas letras, 36 valores. Uma alternativa a kl quando combinado com setLang |
setLang | string | Idioma da interface e dos resultados, 33 valores |
safeSearch | string | off, moderate ou strict |
deviceType | string | desktop, mobile ou tablet |
Envie ou
qounextPageToken. Enviar nenhum retorna 422 nomeando ambos os campos, porque o requisito é condicional e o esquema não pode expressá-lo como uma lista obrigatória simples. Enviar ambos também não é erro; o cursor vence e a consulta não vai a lugar nenhum, então um agente que mantémqnos argumentos enquanto pagina silenciosamente lê o conjunto de resultados errado.
positionconta dentro da página de onde veio, não em todo o conjunto de resultados. A página dois volta com posições começando em 1 novamente, e o tamanho da página também não é fixo, então páginas de 10, 15 e 14 resultados aparecem. A classificação absoluta é, portanto, o número de resultados orgânicos que você já coletou maisposition, não algo que você possa derivar do número da página. Construa um conjunto de dados de classificação sem isso e cada página contribuirá com seu próprio número um.
Retorna organicResults, ads, searchAssist e pagination. Entradas orgânicas carregam position, title, link, displayedLink, source e snippet, além de uma data, sitelinks e metadados de vídeo onde o DuckDuckGo os mostra. searchAssist contém a resposta de IA do próprio DuckDuckGo para a consulta.
adsesearchAssistestão ausentes quando a página não tem nenhum dos dois, então teste a chave antes de lê-la.organicResultstambém pode estar ausente, então leia-o com um padrão em vez de tratar sua presença como garantida. Uma consulta sem correspondências reais ainda volta como uma página completa de entradas vagamente relacionadas, o que não é como "nada encontrado" normalmente parece.
{
"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…" }
}
Erros e caminhos de falha
Seu cliente quase nunca vê um código de erro HTTP de uma chamada de ferramenta. A camada MCP responde 200 e coloca a falha dentro do resultado, com isError definido como true e o motivo como texto. O agente lê uma mensagem onde você poderia esperar uma linha de status.
Uma chave errada aparece como saída de ferramenta, não como conexão falha. Listar ferramentas aceita qualquer chave não vazia, então o cliente completa o handshake e mostra verde. A primeira chamada de ferramenta então volta com isError: true e o texto HasData API error: 401 Unauthorized. Fique atento a essa string, porque nada antes no fluxo relata o problema.
Uma chave ausente é o único erro HTTP real. A autorização roda antes de qualquer ferramenta, e a própria conexão falha com 401.
Um argumento que quebra o esquema é rejeitado antes de se tornar uma busca. O servidor responde com isError: true e o texto MCP error -32602: Input validation error, nomeando o campo. Nada é buscado e nada é cobrado.
Nem q nem nextPageToken retorna 422 com uma matriz errors nomeando ambos os campos e a regra requiredIfNotExists que os une.
Uma consulta sem nada por trás ainda retorna resultados. O DuckDuckGo decide a relevância, então uma string sem sentido volta como uma página normal de dez entradas vagamente relacionadas com ads e searchAssist ausentes. Nada a marca como um erro, o que importa se você está construindo um alerta sobre "sem cobertura para esta marca".
Resultados que carregam dados também carregam um requestMetadata.id que vale citar no suporte.
Preços, camada gratuita e limites
Cada chamada custa 10 créditos. O número de resultados não muda o preço. Uma página completa custa o mesmo que uma página com uma entrada.
O teste gratuito é 1.000 créditos por 30 dias sem cartão, o que equivale a 100 buscas. Depois disso, uma conta ativa continua recebendo 100 créditos recarregados diariamente sempre que seu saldo cair abaixo de 100, então um agente de baixo volume roda na camada gratuita indefinidamente.
Planos pagos começam em US$ 49 por mês para 200.000 créditos, o que equivale a 20.000 buscas. O preço unitário cai com o volume, de US$ 2,45 por 1.000 buscas no plano inicial para US$ 0,99 no Business, US$ 0,83 no Growth e US$ 0,75 nos maiores planos de alto volume. Os números atuais estão na página de preços.
Seu plano também define concorrência. O teste gratuito permite 1 solicitação por vez, Startup 15, Business 30, Growth 50, e os planos de alto volume variam de 200 a 1.500. Lide com o caso de estouro defensivamente em qualquer coisa não supervisionada, porque um agente que se expande atingirá o teto antes de você.
Uma solicitação que volta não-200 não é cobrada. Uma chamada bem-sucedida que não encontra nada ainda é uma chamada.
Seleção de ferramentas
O parâmetro de consulta apis decide quais ferramentas seu agente vê. Menos ferramentas significa menos contexto gasto em definições de ferramentas e menos chances de o modelo alcançar a errada.
?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
O parâmetro aceita nomes de provedores como duckduckgo e nomes de APIs individuais como google_maps_search. Nomes com erros de digitação são ignorados. Se todos os nomes estiverem errados, a solicitação falha com 400, e o corpo lista tanto o que não reconheceu quanto todos os valores válidos. Remova o parâmetro e o mesmo endpoint expõe todas as 57 ferramentas HasData.
Três mecanismos em um único agente é o motivo comum para ampliar a lista aqui, porque comparar a mesma consulta no DuckDuckGo, Google e Bing é um único prompt, uma vez que os três estejam expostos.
Como ele se compara
A alternativa realista é um servidor auto-hospedado. Os populares são pacotes Python que você executa localmente, eles acessam o DuckDuckGo a partir da sua própria máquina e entregam ao modelo um bloco de texto formatado. Isso funciona bem para um assistente de pesquisa que responde uma pergunta por vez. Deixa de funcionar quando você precisa de volume e de um formato estável.
| Servidor auto-hospedado | Este servidor | |
|---|---|---|
| O que uma busca retorna | Uma string de texto formatada para o modelo ler | JSON com position, title, link, displayedLink, source, snippet, datas e links de site |
| Posicionamentos pagos | Removidos junto com o restante do ruído | Mantidos em um array separado ads |
| Paginação | Um limite de max_results em uma única página | Cursor em cada resposta |
| Regiões | Um código de region | 37 códigos de região, ou país e idioma definidos separadamente |
| SafeSearch | Fixo quando o servidor inicia, deliberadamente não acionável pelo agente | Por chamada |
| Quem busca a página | Sua máquina, via httpx, com um backend opcional curl_cffi e um fallback para configurar | Nós |
| Throughput | Autolimitado a 30 buscas por minuto | Concorrência do plano, de 1 no teste a 1.500 |
| O que você executa | Um ambiente Python, um extra opcional e configurações de contêiner ou proxy quando não está em localhost | Uma URL e um cabeçalho |
| Extração de conteúdo de página | Uma ferramenta fetch_content | Não oferecida |
| Custo | Gratuito | 10 créditos por chamada |
Duas linhas carregam a maior parte da decisão. Um bloco de texto é a saída certa para uma resposta de chat e a errada para um conjunto de dados ranqueados, porque reconstruir position a partir de prosa é trabalho que você não deveria fazer. E o fato de a busca ser nossa elimina a questão do backend, junto com a escolha entre httpx e um cliente que imita navegador, a instalação do extra do qual o fallback depende e a leitura de um stack trace quando um cliente HTTP simples deixa de receber uma página de volta.
Todo o resto nessa lista é uma troca real. Um servidor auto-hospedado é gratuito, não exige conta, mantém suas consultas na sua própria máquina e busca conteúdo de página, o que este servidor não faz. Se você executa algumas buscas por dia dentro de um único assistente, ele é a melhor opção. Este é para o caso em que o número de buscas, o número de regiões ou o formato da saída começa a importar.
Contra a própria API do DuckDuckGo. api.duckduckgo.com é a API Instant Answer, e ela retorna um resumo enciclopédico quando existe, em vez de uma página de resultados. Não há endpoint oficial que entregue resultados web ranqueados, e é por isso que toda opção aqui analisa a página.
O que este servidor não faz. Sem busca de páginas ou extração de conteúdo, sem verticais de imagens ou notícias, sem autocomplete. Ele retorna a página de resultados, analisada.
FAQ
Existe um servidor MCP oficial do DuckDuckGo?
Não. O DuckDuckGo não publica nenhum servidor MCP. Toda opção é construída por terceiros. A maioria são projetos de código aberto que rodam localmente, e este é um servidor hospedado mantido pela HasData.
O que é um servidor MCP do DuckDuckGo?
Um servidor que expõe a busca do DuckDuckGo como uma ferramenta que um cliente de IA pode chamar. O cliente envia uma chamada de ferramenta pelo Model Context Protocol, o servidor executa a busca e retorna JSON estruturado, e o modelo trabalha com o resultado e nunca vê uma página de HTML.
Preciso de uma conta ou chave de API do DuckDuckGo?
Não. A única credencial é a sua chave HasData. O DuckDuckGo não tem programa de desenvolvedor para se cadastrar, e a API Instant Answer que ele publica não retorna resultados de busca.
Preciso hospedar ou executar algo?
Não. Este é um servidor MCP remoto em HTTP streamable. Nada para instalar, sem ambiente Python, sem pacote de navegador, sem processo para reiniciar.
Os dados são ao vivo ou em cache?
Ao vivo. Cada chamada busca a página de resultados no momento da solicitação e carrega seu próprio requestMetadata.id. Duas chamadas idênticas são duas buscas separadas e não uma reprodução de uma cópia armazenada.
Posso comparar a mesma consulta entre regiões?
Sim, e esse é o principal motivo para usar um parâmetro em vez de um proxy. kl aceita 37 códigos de região, e cc com setLang divide país e idioma quando você precisa separá-los. Cada região é uma chamada própria.
O que acontece quando o DuckDuckGo muda o layout?
Nada do seu lado. Nós acompanhamos as mudanças e mantemos o esquema de resposta estável, então nomes de campos e tipos permanecem os mesmos. Um bloco sem nada a relatar fica ausente da resposta, então leia ads e searchAssist com um valor padrão.
Posso usar isso junto com outras APIs da HasData?
Sim. O parâmetro apis aceita uma lista, e ?apis=duckduckgo,google_serp,bing_serp dá ao seu agente três mecanismos de busca de uma vez.
Posso entrar com OAuth em vez de colar uma chave?
Sim, em clientes que suportam isso. Claude Desktop e Cursor podem adicionar o endpoint como conector e fazer login. Agentes e scripts não supervisionados usam o cabeçalho x-api-key.
Conformidade e dados pessoais
A HasData acessa apenas dados publicamente disponíveis. Os termos de uma plataforma podem restringir o acesso automatizado, e você é responsável pela sua própria conformidade. Quando os dados que você coleta incluem informações pessoais, certifique-se de ter uma base legal para isso sob o GDPR, CCPA ou as regras equivalentes na sua jurisdição.
Links da HasData
| Página do produto e construtor de solicitações | DuckDuckGo SERP API |
| Documentação do servidor | MCP server docs |
| Todas as 57 ferramentas em um servidor | HasData/hasdata-mcp |
| Tutoriais para clientes | MCP clients and integrations |
| Os outros mecanismos de busca que analisamos | Google, Bing and 53 more APIs |
| Planos e custos de créditos | Plans and credit costs |
| Chaves e uso | HasData dashboard |
| Lançador Node no npm | @hasdata/duckduckgo-mcp |
| Lançador Python no PyPI | hasdata-duckduckgo-mcp |
Desenvolvimento
Este repositório é configuração e documentação para um servidor remoto. Não há etapa de build e nada para containerizar.
Os testes em test/ verificam o contrato da ferramenta, a parte que pode quebrar sem um commit aqui. Eles verificam que ?apis=duckduckgo retorna exatamente uma ferramenta, que o nome dela não mudou, que os parâmetros documentados neste README ainda existem com as enumerações que ele cita, e que a chave em uso é realmente aceita. Esse último teste executa uma busca real e custa 10 créditos, que é o preço de um canário que pode falhar pelo motivo certo.
# macOS and Linux
HASDATA_API_KEY=your_key_here npm test
# Windows PowerShell
$env:HASDATA_API_KEY="your_key_here"; npm test
A mesma suíte roda em CI a cada push e uma vez por semana em um agendamento, porque a lista de ferramentas upstream pode mudar sem que ninguém toque neste repositório. Uma falha significa que a lista de ferramentas mudou, a chave parou de funcionar ou o endpoint ficou inacessível, e a mensagem de asserção diz qual.
Contribuindo
Correções na tabela de parâmetros e na amostra de resposta são a contribuição mais útil, porque essas são as partes que se desatualizam. Inclua a chamada que você fez e a resposta que obteve. Pull requests de forks rodam a suíte sem chave, e as verificações ao vivo são puladas em vez de ficarem vermelhas.
Licença
MIT. Veja LICENSE.