ddg-search
ddg-search
Сервер поиска DuckDuckGo MCP, который отказывается иметь единую точку отказа. Один процесс, много бэкендов, автоматический фейловер, честные сообщения об ошибках.
Идея
Веб-поиск — несущая инфраструктура для агентов, пишущих код, и он отказывает скучными способами: лимиты скорости, обнаружение ботов, ваш VPS-провайдер, переживающий не лучшие времена. Большинство серверов дают вам один HTTP-клиент и надеются. Этот же направляет каждый запрос через несколько бэкендов — локальный поисковик на этой машине плюс любое количество удалённых экземпляров duckduckgo-mcp-server, которые у вас запущены — и продолжает попытки, пока что-то не ответит или не закончится бюджет.
Бэкенды, которые сбоят, уходят в таймаут. Бэкенды, которые ведут себя хорошо, получают больше трафика. Вы получаете результаты — один компактный блок с однострочной пометкой, кто его обслужил.
Related MCP server: DuckDuckGo Search MCP Server
Установка
Требуется Python 3.10+ и uv.
git clone <this repo> ~/.local/share/mcp/ddg-search # or anywhere you like
cd ~/.local/share/mcp/ddg-search
uv syncЭто вся процедура. uv sync создаёт .venv, фиксирует зависимости и устанавливает пакет в режиме editable, поэтому правки в src/ применяются при перезапуске.
Подключение к агенту
Любой MCP-клиент, понимающий stdio, подойдёт. Для конфигурации в стиле 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 — это только фильтрация контента; она ничего не даёт против обнаружения ботов и по умолчанию выключена, потому что агенты, проводящие исследования, хотят полноты результатов, а не надзирателя.
Инструменты
search
Аргумент | Тип | По умолчанию | Примечания |
| string | required | Точные существительные лучше расплывчатых однословных вибраций |
| int | 10 | Вышестоящий сервис в любом случае ограничивает примерно 10–11 |
| string |
| Код региона DuckDuckGo |
|
|
| Ручной режим пропускает сортировку по здоровью |
| string |
| Имя/алиас/IP одного бэкенда (ручной режим) |
| list |
| Упорядоченная цепочка запасных вариантов (ручной режим) |
Результаты намеренно возвращаются компактно:
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. ...Каждый ответ указывает, какой бэкенд его обслужил. Неудачные попытки перечислены под Attempts: с тегом, указывающим, где произошёл сбой:
Тег | Значение |
| DuckDuckGo вернул ноль совпадений — настоящий «нет результатов» или пустой ответ боту, отсюда неразличимо |
| Клиент на этой машине потерпел неудачу. Не вините удалённые хосты |
| Удалённый бэкенд ответил некорректно |
| Бюджет в 25 секунд истёк во время ожидания |
Когда что-то ломается, вы получаете путь к логу
Роутер отличает «интернет ведёт себя как интернет» от «этот инструмент действительно сломан». Таймауты и пустые наборы результатов просто получают свой [tag]. Но когда попытка завершается сбоем, означающим, что сломалась наша сторона — ошибки локального транспорта, некорректные ответы удалённых бэкендов — ответ заканчивается так:
log: /path/to/ddg-search/logs/20260822T090206-remote-tool-error.jsonЭтот файл содержит всё необходимое для воспроизведения и диагностики: точный запрос и аргументы, каждую попытку с деталями сбоя и снимок состояния каждого бэкенда на тот момент. При желании укажите DDG_SEARCH_LOGS_DIR в другом месте; логи никогда не пишутся для таймаутов и пустых результатов.
status
Таблица бэкендов: флаг онлайн, наблюдаемые попытки за эту минуту, последний статус, окончание кулдауна. Передайте probe: true, чтобы реально пропинговать удалённые бэкенды, а не доверять кэшированному состоянию.
Конфигурация
Переменные окружения, все необязательные:
Переменная | По умолчанию | Назначение |
|
|
|
|
| Локальный транспорт: |
|
| Общий бюджет на все бэкенды на один запрос |
|
| Штраф за таймаут для каждого бэкенда |
|
| Штраф за ошибку для каждого бэкенда |
|
| Ожидание пробного запроса к бэкенду для |
|
| Каталог состояния роутера |
Бэкенды находятся в src/ddg_search/config.py. Флот по умолчанию — local (эта машина) плюс два удалённых ретранслятора; отредактируйте кортеж под свою инфраструктуру.
Поведение, о котором стоит знать
Фейловер предпочитает здоровые бэкенды с наименьшим числом недавних попыток, поэтому трафик распределяется, а не долбит одну бедную коробку.
Кулдауны действуют на каждый бэкенд и ограничены по времени: таймаут выводит бэкенд из игры на 90 секунд, мягкий сбой — на 30. Один успех мгновенно очищает историю.
Состояние переживает перезапуски в
state/router-state.json. Удалите его, если хотите амнезию; сервер воссоздаст его при следующей загрузке.
Одна особенность заслуживает отдельного абзаца. DuckDuckGo отдаёт пустые страницы клиентам, которым не доверяет, поэтому «нет результатов» может означать либо действительно нет совпадений, либо тихую пометку бота — роутер не может их различить и не притворяется, что может. Он считает пустой ответ сбоем и пробует следующий бэкенд; если все бэкенды вернули пустоту, вы получите баннер с точным указанием, насколько это неоднозначно.
И последнее: потолок в 30 запросов в минуту обеспечивается каждым экземпляром duckduckgo-mcp-server, а не здесь. Роутер распределяет нагрузку между бэкендами, но не будет врать о пропускной способности, которой у флота нет.
Запуск собственных ретрансляторов
Любая машина, способная запустить стандартный сервер, подойдёт как бэкенд:
pip install 'duckduckgo-mcp-server[browser]'
python -m duckduckgo_mcp_server.main --transport streamable-http --host 0.0.0.0 --port 18082Направьте на него BackendConfig(url="http://that-host/ddg-mcp"). В каталоге realip/ находится лаунчер, используемый systemd-юнитом для запуска такого выхода за mullvad-exclude на резидентном IP — полезно, если ваш датацентровый egress получает более суровые капчи, чем домашнее подключение.
Разработка
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 typesБыстрый ручной смоук-тест через весь роутер:
uv run python -c "import asyncio; from ddg_search.router import SearchRouter; \
print(asyncio.run(SearchRouter().search('crawl4ai', 3, '', 'auto', None, None, None)))"Смотрите также
fast-webfetch-mcp — вторая половина: открывает URL, найденные этими поисками, через локальный браузер Crawl4AI
Model Context Protocol — что означает «MCP»
duckduckgo-mcp-server — библиотека поиска, выполняющая непосредственный скрапинг под капотом
Лицензия
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