API ВЕГА

DuckDuckGo MCP Server

Размещённый на сервере Model Context Protocol (MCP), который предоставляет Claude, Cursor, Windsurf и любому другому MCP-клиенту результаты поиска DuckDuckGo в виде структурированного JSON. Органические результаты с позициями, объявления в отдельном массиве, собственный ответ DuckDuckGo на основе ИИ и выбор региона из 37 вариантов. Сервер рассчитан на большие объёмы запросов и удобный разбор результатов: локальный браузер и настраиваемая цепочка резервных вариантов не нужны.

1 000 бесплатных кредитов каждый месяц, банковская карта не требуется — этого хватит на 100 поисковых запросов.

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

Содержание

  • Требования

  • Быстрый старт

  • Примеры запросов

  • Инструменты

  • Ошибки и сбои

  • Стоимость, бесплатный тариф и лимиты

  • Выбор инструмента

  • Сравнение с другими решениями

  • Часто задаваемые вопросы

  • Ссылки HasData

  • Разработка

  • Участие в проекте

  • Лицензия

Требования

MCP-клиент с поддержкой streamable HTTP и пользовательских заголовков. API-ключ HasData, который можно бесплатно создать в панели управления. Больше ничего не нужно. Сервер удалённый, поэтому для подключения достаточно URL и заголовка: устанавливать пакет для браузера или поддерживать локальный процесс не требуется. Клиент, поддерживающий только stdio, может использовать в качестве запускающего компонента пакет @hasdata/duckduckgo-mcp (npm) или hasdata-duckduckgo-mcp (PyPI).

Быстрый старт

URL сервера одинаков для всех клиентов. Мы проверили подключение в Claude Code и Claude Desktop. Примеры для остальных клиентов соответствуют их собственной документации по подключению удалённых серверов.

ПолеЗначение
URLhttps://mcp.hasdata.com/mcp?apis=duckduckgo
ТранспортHTTP, streamable
Заголовок авторизацииx-api-key: HASDATA_API_KEY

Клиенты с поддержкой OAuth можно подключить по тому же URL и войти в систему, не добавляя ключ в файл конфигурации.

Claude Code

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

Claude Desktop

Откройте Settings, затем Connectors, выберите Add custom connector, вставьте https://mcp.hasdata.com/mcp?apis=duckduckgo и войдите в систему.

Если вы настраиваете подключение через файл конфигурации, учтите, что Claude Desktop загружает только локальные серверы (stdio). Поэтому для подключения к удалённому серверу понадобится запускающий компонент, работающий через stdio. Эту роль выполняет пакет @hasdata/duckduckgo-mcp: он считывает ключ из переменной окружения. Добавьте следующий фрагмент в claude_desktop_config.json:

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

Предпочитаете Python вместо Node? Замените запускающий компонент на пакет из PyPI. Команда uvx запустит его без предварительной установки:

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

Cursor

Файл ~/.cursor/mcp.json — для всех проектов, .cursor/mcp.json — для одного проекта:

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

Windsurf

Файл ~/.codeium/windsurf/mcp_config.json. В Windsurf поле называется serverUrl, а не url:

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

Cline

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

VS Code

Файл .vscode/mcp.json в рабочей области:

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

Codex CLI

Файл ~/.codex/config.toml:

[mcp_servers.duckduckgo]
url = "https://mcp.hasdata.com/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/mcp?apis=duckduckgo",
      "headers": { "x-api-key": "HASDATA_API_KEY" }
    }
  }
}

Примеры запросов

Это запросы на естественном языке, а не фрагменты кода. Вставьте любой из них, и агент сам вызовет инструмент. Указано количество необходимых вызовов: в MCP модель сама определяет, сколько вызовов выполнить, а каждый успешный вызов стоит 10 кредитов.

Найди в DuckDuckGo результаты по запросу "model context protocol" и выведи первые десять, указав их позиции и домены.

Один вызов, 10 кредитов.

Выполни поиск по запросу "vpn review" в немецком регионе, а затем в регионе США. Сравни домены, которые встречаются только в одном из двух регионов.

Два вызова, 20 кредитов. Регион задаётся параметром. Один запрос в двух регионах — это два вызова.

Найди результаты по запросу "best crm software" и выведи только платные размещения, указав домен рекламодателя для каждого.

Один вызов, 10 кредитов. Объявления возвращаются в отдельном массиве, поэтому определять их эвристически не нужно.

Возьми запрос "model context protocol", просмотри первые три страницы и укажи домены, которые встречаются более чем на одной позиции.

Три вызова, 30 кредитов. Каждая следующая страница требует отдельного вызова с курсором; после первого запроса исключи q из аргументов.

Найди ответ на вопрос "who invented the transistor" и покажи собственный ответ DuckDuckGo на основе ИИ рядом с органическими результатами, на которые он опирается.

Один вызов, 10 кредитов.

Два ключевых преимущества сервера — это выбор региона и отдельная выдача платных размещений. Регион — полноценный параметр для 37 рынков. Чтобы сравнить запрос в разных странах, достаточно повторить его с нужными параметрами: настраивать прокси не нужно. Платные размещения возвращаются отдельно от органических результатов, поэтому для отслеживания позиций не приходится гадать, какое из них является рекламой.

Каждый переход на следующую страницу требует отдельного вызова. Запрос, который просматривает десять страниц, потребует десяти вызовов и 100 кредитов.

Инструменты

ИнструментЧто возвращает
hasdata_duckduckgo_serp_getSearchResultsОрганические результаты (заголовок, url, сниппет, отображаемый url, позиция, дата, быстрые ссылки и метаданные видео), объявления и ответ Search Assist на основе ИИ. 10 кредитов за вызов

Инструмент один. Примеры ниже сокращены на основе реальных вызовов, а результаты со временем меняются вместе с содержимым интернета. Используйте их, чтобы понять структуру данных.

В примерах показана полезная нагрузка, а не полный ответ. Результат tools/call содержит один текстовый блок, в котором находится JSON с полями url, status, text и json; извлечённые данные находятся в json. В необработанном ответе JSON-RPC нужный путь — result.content[0].text: сначала разберите его, затем обратитесь к .json. Чат-клиент выполнит это извлечение за вас, но при прямом обращении к конечной точке кода — нет.

Получение результатов поиска DuckDuckGo

Получение результатов поиска hasdata_duckduckgo_serp_getSearchResults

Получает страницу результатов DuckDuckGo и возвращает её в разобранном виде.

ПараметрТипПримечания
qstringПоисковый запрос. Нужно указать либо q, либо nextPageToken
nextPageTokenstringКурсор из pagination.nextPageToken в предыдущем ответе. Если переданы оба параметра, используется курсор, а указанный вместе с ним q игнорируется без предупреждения
klstringРегион: - или одно из 37 значений — от us-en и de-de до jp-jp; wt-wt означает отсутствие региона
ccstringДвухбуквенный код страны; доступно 36 значений. Альтернатива kl, если используется вместе с setLang
setLangstringЯзык интерфейса и результатов; доступно 33 значения
safeSearchstringoff, moderate или strict
deviceTypestringdesktop, mobile или tablet

Укажите либо q, либо nextPageToken. Если не передать ни один из них, сервер вернёт 422 и назовёт оба поля: требование условное, поэтому схема не может задать его обычным списком обязательных параметров. Передача обоих значений тоже не считается ошибкой: приоритет у курсора, а запрос игнорируется. Поэтому агент, который не удаляет q из аргументов при переходе между страницами, незаметно получит не те результаты.

Значение position указывает позицию результата на той странице, откуда он получен, а не во всей выдаче. На второй странице нумерация снова начинается с 1, а размер страницы не фиксирован: встречаются страницы с 10, 15 и 14 результатами. Поэтому абсолютную позицию нужно рассчитывать как количество уже собранных обычных результатов плюс position. Её нельзя определить только по номеру страницы. Если не учитывать это при формировании набора данных с позициями, каждая страница будет содержать собственный результат номер один.

Ответ содержит organicResults, ads, searchAssist и pagination. Элементы обычной выдачи содержат position, title, link, displayedLink, source и snippet, а также дату, дополнительные ссылки и метаданные видео, если DuckDuckGo их показывает. searchAssist содержит собственный ответ DuckDuckGo, сгенерированный с помощью AI, на поисковый запрос.

Если на странице нет рекламы или блока с ответом, поля ads и searchAssist отсутствуют — проверяйте наличие ключа перед чтением. Поле organicResults тоже может отсутствовать, поэтому при чтении задавайте значение по умолчанию, а не рассчитывайте на его наличие. Даже если подходящих совпадений нет, запрос всё равно возвращает страницу с приблизительно связанными результатами. Обычно именно так выглядит ответ «ничего не найдено».

{
  "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…" }
}

Ошибки и сценарии сбоев

Клиент почти никогда не получает HTTP-код ошибки при вызове инструмента. Уровень MCP отвечает кодом 200 и помещает сведения об ошибке в результат: для неё устанавливается isError: true, а причина передаётся текстом. Вместо ожидаемой строки со статусом агент получает сообщение.

Неверный ключ отражается в ответе инструмента, а не в ошибке подключения. Для просмотра списка инструментов подходит любой непустой ключ, поэтому клиент успешно завершает рукопожатие, и соединение отображается как активное. При первом вызове инструмента возвращается isError: true с текстом HasData API error: 401 Unauthorized. Обратите внимание на это сообщение: раньше в процессе проблема никак не проявляется.

Отсутствующий ключ — единственный случай, когда возникает настоящая HTTP-ошибка. Проверка авторизации выполняется до вызова любого инструмента, поэтому само подключение завершается с ошибкой 401.

Аргумент, не соответствующий схеме, отклоняется до отправки поискового запроса. Сервер возвращает isError: true и текст MCP error -32602: Input validation error, указывая проблемное поле. Данные не запрашиваются, списание не производится.

Если не переданы ни q, ни nextPageToken, сервер возвращает 422 и массив errors, в котором указаны оба поля и связывающее их правило requiredIfNotExists.

Даже если по запросу ничего не найдено, результаты всё равно возвращаются. DuckDuckGo самостоятельно определяет релевантность, поэтому бессмысленная строка запроса приводит к обычной странице с десятью приблизительно связанными результатами, но без ads и searchAssist. Никакого признака отсутствия совпадений нет — это важно, если вы настраиваете оповещение о том, что «для этого бренда нет охвата».

Ответы с данными также содержат requestMetadata.id. Его полезно указывать при обращении в поддержку.

Стоимость, бесплатный тариф и ограничения

Каждый вызов стоит 10 кредитов. Количество результатов на стоимость не влияет: полная страница стоит столько же, сколько страница с одним результатом.

Бесплатный тариф предоставляет 1 000 кредитов в месяц без привязки карты — этого хватит на 100 поисковых запросов. Кредиты обновляются с началом расчётного периода, поэтому агент с небольшим объёмом запросов может пользоваться бесплатным тарифом неограниченно долго.

Платные тарифы начинаются от 59 долларов в месяц за 200 000 кредитов, то есть за 20 000 запросов. При увеличении объёма цена за единицу снижается: с 2,95 доллара за 1 000 запросов на начальном тарифе до 1,19 доллара на тарифе Basic и 0,83 доллара на тарифах Growth. Актуальные цены указаны на странице с тарифами.

Тариф также определяет допустимое количество одновременных запросов. Бесплатный тариф разрешает выполнять 1 запрос за раз, Startup — 5, Basic — 15, а на тарифах Growth лимит составляет от 50 до 500. Если система работает без наблюдения, предусмотрите обработку превышения лимита: агент, отправляющий несколько запросов параллельно, достигнет его раньше, чем вы успеете вмешаться.

Запрос, завершившийся ответом не с кодом 200, не тарифицируется. Успешный вызов, который ничего не нашёл, всё равно считается вызовом.

Выбор инструментов

Параметр запроса apis определяет, какие инструменты будут доступны агенту. Чем их меньше, тем меньше контекста занимают описания инструментов и тем ниже вероятность, что модель выберет неподходящий инструмент.

?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

В качестве значений параметр принимает названия провайдеров, например duckduckgo, и отдельных API, например google_maps_search. Названия с опечатками игнорируются. Если все указанные значения неверны, запрос завершается ошибкой 400. В теле ответа перечисляются нераспознанные значения и все допустимые варианты. Если убрать параметр, тот же endpoint предоставит доступ ко всем 57 инструментам HasData.

Чаще всего список расширяют, чтобы предоставить агенту доступ сразу к трём поисковым системам. Тогда сравнить результаты одного запроса в DuckDuckGo, Google и Bing можно с помощью одного prompt.

Сравнение с альтернативами

Практичная альтернатива — сервер, который вы размещаете самостоятельно. Популярные варианты — это пакеты Python, запускаемые локально: они обращаются к DuckDuckGo с вашего компьютера и передают модели отформатированный текстовый блок. Для исследовательского помощника, который отвечает на один вопрос за раз, этого достаточно. Но такой подход перестаёт справляться, когда нужны большой объём запросов и стабильная структура данных.

Сервер, размещённый самостоятельноЭтот сервер
Что возвращает поискОтформатированную текстовую строку, предназначенную для чтения модельюJSON с полями position, title, link, displayedLink, source, snippet, датами и дополнительными ссылками
Рекламные результатыУдаляются вместе с остальными лишними даннымиСохраняются в отдельном массиве ads
ПагинацияОграничение max_results для одной страницыКурсор в каждом ответе
РегионыОдин код region37 кодов регионов либо отдельная настройка страны и языка
SafeSearchЗадаётся при запуске сервера и намеренно недоступен агенту для вызоваНастраивается для каждого вызова
Кто получает страницуВаш компьютер через httpx, с дополнительным бэкендом curl_cffi и запасным вариантом для настройкиМы
Пропускная способностьОграничена сервером: не более 30 поисковых запросов в минутуЗависит от тарифа: от 1 одновременного запроса на бесплатном тарифе до 1 500
Что нужно запускатьСреду Python, дополнительный пакет и, если сервер запущен не на localhost, контейнер или настройки проксиURL и заголовок
Извлечение содержимого страницИнструмент fetch_contentНе поддерживается
СтоимостьБесплатно10 кредитов за вызов

На решение влияют прежде всего два пункта. Текстовый блок удобен для ответа в чате, но не подходит для набора данных с позициями результатов: восстанавливать position из текста — лишняя работа. А поскольку страницы получаем мы, вам не нужно разбираться с бэкендом: выбирать между httpx и клиентом, имитирующим браузер, устанавливать дополнительный пакет, от которого зависит запасной вариант, или изучать трассировку стека после того, как обычный HTTP-клиент перестал получать страницу.

Остальные отличия — реальные компромиссы. Сервер, размещённый самостоятельно, бесплатен, не требует учётной записи, сохраняет запросы на вашем компьютере и получает содержимое страниц — чего этот сервер не делает. Если вы выполняете несколько поисковых запросов в день в рамках одного помощника, такой вариант подойдёт лучше. Этот сервер рассчитан на ситуации, когда важны количество запросов, число регионов или структура результата.

В сравнении с собственным API DuckDuckGo. api.duckduckgo.com — это Instant Answer API. Если для запроса есть энциклопедическая справка, API возвращает её, а не страницу результатов. Официального endpoint для получения ранжированных результатов поиска нет, поэтому все представленные здесь решения разбирают содержимое страницы.

Чего этот сервер не делает. Он не получает страницы и не извлекает их содержимое, не поддерживает поиск по изображениям и новостям, а также автодополнение. Сервер возвращает разобранную страницу результатов.

Часто задаваемые вопросы

Есть ли официальный MCP-сервер DuckDuckGo?

Нет. DuckDuckGo не выпускает MCP-сервер. Все доступные варианты созданы сторонними разработчиками. Большинство из них — проекты с открытым исходным кодом, которые запускаются локально. Этот сервер размещён и поддерживается HasData.

Что такое MCP-сервер DuckDuckGo?

Это сервер, который предоставляет поиск DuckDuckGo в виде инструмента, вызываемого AI-клиентом. Клиент отправляет вызов инструмента по протоколу Model Context Protocol, сервер выполняет поиск и возвращает структурированный JSON. Модель работает с результатом и не видит HTML-страницу.

Нужны ли учётная запись DuckDuckGo или API-ключ?

Нет. Единственные учётные данные, которые вам понадобятся, — ключ HasData. В DuckDuckGo нет программы для разработчиков, к которой можно присоединиться, а опубликованный компанией Instant Answer API не возвращает результаты поиска.

Нужно ли что-то размещать или запускать самостоятельно?

Нет. Это удалённый MCP-сервер, работающий по streamable HTTP. Ничего устанавливать не нужно: не требуется среда Python, пакет для работы с браузером или процесс, который нужно перезапускать.

Данные актуальные или кэшированные?

Актуальные. При каждом вызове сервер получает страницу результатов в момент запроса и присваивает ей собственный requestMetadata.id. Два одинаковых вызова — это два отдельных обращения, а не повторная выдача сохранённой копии.

Можно ли сравнить один и тот же запрос в разных регионах?

Да. Это основная причина использовать параметр, а не прокси. Параметр kl поддерживает 37 кодов регионов, а сочетание cc и setLang позволяет указать страну и язык отдельно. Для каждого региона выполняется отдельный вызов.

Что произойдёт, если DuckDuckGo изменит оформление страницы?

Вам ничего не придётся делать. Мы отслеживаем изменения и сохраняем стабильную схему ответа, поэтому названия и типы полей остаются неизменными. Если в блоке нет данных, он не включается в ответ. Поэтому при работе с ads и searchAssist указывайте значение по умолчанию.

Можно ли использовать этот сервер вместе с другими API HasData?

Да. Параметр apis принимает список, поэтому запрос ?apis=duckduckgo,google_serp,bing_serp позволяет агенту одновременно использовать три поисковые системы.

Можно ли войти через OAuth вместо того, чтобы вставлять ключ?

Да, если клиент поддерживает такую возможность. В Claude Desktop и Cursor endpoint можно добавить как коннектор и войти в систему. Для автоматизированных агентов и скриптов используется заголовок x-api-key.

Соблюдение требований и персональные данные

HasData получает только общедоступные данные. Условия использования платформы могут ограничивать автоматизированный доступ, поэтому за соблюдение требований отвечаете вы. Если собранные данные содержат персональную информацию, убедитесь, что у вас есть законное основание для её обработки согласно GDPR, CCPA или аналогичным правилам вашей юрисдикции.

Ссылки HasData

Страница продукта и конструктор запросовDuckDuckGo SERP API
Документация сервераДокументация MCP-сервера
Все 57 инструментов на одном сервереHasData/hasdata-mcp
Руководства по клиентамКлиенты MCP и интеграции
Другие поисковые системы, которые мы разбираемGoogle, Bing и ещё 53 API
Тарифы и стоимость в кредитахТарифы и стоимость в кредитах
Ключи и использованиеПанель управления HasData
Запуск Node из npm@hasdata/duckduckgo-mcp
Запуск Python из PyPIhasdata-duckduckgo-mcp

Разработка

Этот репозиторий содержит конфигурацию и документацию удалённого сервера. Сборка не требуется, как и упаковка в контейнер.

Тесты в test/ проверяют контракт инструмента — то, что может измениться без коммита в этом репозитории. Они проверяют, что запрос ?apis=duckduckgo возвращает ровно один инструмент, его имя не изменилось, параметры, описанные в этом README, по-прежнему доступны с указанными вариантами значений и используемый ключ действительно принимается. Последняя проверка выполняет реальный поиск и стоит 10 кредитов — такова цена проверки, которая может обнаружить проблему по правильной причине.

# macOS and Linux
HASDATA_API_KEY=your_key_here npm test

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

Этот же набор тестов запускается в CI при каждом push, а также раз в неделю по расписанию: список инструментов upstream может измениться, даже если в этом репозитории никто ничего не менял. Сбой означает, что список инструментов изменился, ключ перестал работать или endpoint недоступен. В сообщении об ошибке указано, что именно произошло.

Участие в разработке

Наибольшую пользу принесут исправления таблицы параметров и примера ответа — именно эти разделы чаще всего устаревают. Укажите выполненный запрос и полученный ответ. Для pull request из fork набор тестов запускается без ключа, а проверки с обращением к сервису пропускаются, чтобы сборка не завершалась ошибкой.

Лицензия

MIT. См. LICENSE.