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. Примеры для остальных клиентов соответствуют их собственной документации по подключению удалённых серверов.
| Поле | Значение |
|---|---|
| URL | https://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 и возвращает её в разобранном виде.
| Параметр | Тип | Примечания |
|---|---|---|
q | string | Поисковый запрос. Нужно указать либо q, либо nextPageToken |
nextPageToken | string | Курсор из pagination.nextPageToken в предыдущем ответе. Если переданы оба параметра, используется курсор, а указанный вместе с ним q игнорируется без предупреждения |
kl | string | Регион: - или одно из 37 значений — от us-en и de-de до jp-jp; wt-wt означает отсутствие региона |
cc | string | Двухбуквенный код страны; доступно 36 значений. Альтернатива kl, если используется вместе с setLang |
setLang | string | Язык интерфейса и результатов; доступно 33 значения |
safeSearch | string | off, moderate или strict |
deviceType | string | desktop, 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 для одной страницы | Курсор в каждом ответе |
| Регионы | Один код region | 37 кодов регионов либо отдельная настройка страны и языка |
| 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 из PyPI | hasdata-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.