关于 DuckDuckGo Search MCP Server
DuckDuckGo Search MCP 服务通过 DuckDuckGo 提供网页搜索,并可抓取和解析网页内容,输出面向大模型阅读的格式。适合需要联网检索的 AI 助手与开发者。
主要功能
- 01DuckDuckGo 网页搜索
- 02网页内容抓取与文本提取
- 03长 URL 替换为 ref:// 短令牌
- 04搜索与抓取的速率限制
- 05支持 stdio、SSE 与 Streamable HTTP
适用场景
- 01让 AI 助手搜索最新资讯并读取结果页面
- 02按地区或语言设置搜索结果
- 03在 Claude Desktop 或 Claude Code 中添加网页检索能力
MCP 相关
这是一个 MCP 服务,向 MCP 客户端暴露 search 与 fetch_content 等工具,用于网页搜索和内容获取。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
3收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| query | string | 是 | |
| max_results | integer | 否 | |
| region | string | 否 |
详细介绍
DuckDuckGo Search MCP 服务
一个通过 DuckDuckGo 提供网页搜索功能的模型上下文协议(MCP)服务,还具备内容抓取和解析功能。
快速开始
uvx duckduckgo-mcp-server
功能
- 网页搜索:搜索 DuckDuckGo,支持高级速率限制和结果格式化
- 内容抓取:获取并解析网页内容,支持智能文本提取
- 长 URL 缩短:过长的搜索结果 URL 会转换为较短的
ref://令牌,可直接用于fetch_content,节省上下文 - 速率限制:内置搜索和内容抓取的速率限制保护
- 错误处理:全面的错误处理和日志记录
- 适用于大模型的输出:专为大模型处理而格式化的结果
安装
使用 uv 从 PyPI 安装:
uv pip install duckduckgo-mcp-server
用法
与 Claude Desktop 配合运行
- 下载 Claude Desktop
- 创建或编辑 Claude Desktop 配置:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
- macOS:
添加以下配置:
基本配置(不启用 SafeSearch,也不设置默认地区):
{
"mcpServers": {
"ddg-search": {
"command": "uvx",
"args": ["duckduckgo-mcp-server"]
}
}
}
配置 SafeSearch 和地区:
{
"mcpServers": {
"ddg-search": {
"command": "uvx",
"args": ["duckduckgo-mcp-server"],
"env": {
"DDG_SAFE_SEARCH": "STRICT",
"DDG_REGION": "cn-zh"
}
}
}
}
配置选项:
DDG_SAFE_SEARCH:SafeSearch 过滤级别(可选)STRICT:最严格的内容过滤(kp=1)MODERATE:平衡过滤(kp=-1,未指定时的默认值)OFF:不进行内容过滤(kp=-2)
DDG_REGION:默认地区/语言代码(可选,示例如下)us-en:美国(英语)cn-zh:中国(中文)jp-ja:日本(日语)wt-wt:不指定特定地区- 留空以使用 DuckDuckGo 的默认行为
DDG_CA_CERTS:用于验证出站请求 TLS 证书的 PEM CA 证书包路径(可选)。在 TLS 拦截代理后方运行时需要此项 — 请参阅在 TLS 拦截代理后方运行。DDG_RATE_LIMIT_STRATEGY:sliding(默认,沿用历史设置的 60 秒窗口)或token_bucket(允许突发请求,然后平滑处理)。DDG_SEARCH_RPM:每分钟搜索请求数(默认:30)。DDG_FETCH_RPM:每分钟全局fetch_content请求数(默认:20)。DDG_FETCH_HOST_RPM:可选的单主机抓取上限(默认:0,关闭)。设置为正数即可启用。DDG_CACHE_TTL:解析后的页面在内存fetch_content缓存中的保留秒数(默认:300)。对同一 URL 的分页读取会复用一次下载。设置为0可禁用。DDG_CACHE_MAX_ENTRIES:该缓存中保留的最大页面数(默认:64)。按最近最少使用原则淘汰条目。设置为0可禁用。DDG_PARSE_MODE:fetch_content的默认提取器(text、main或markdown)。默认值为text(沿用历史设置,展平页面内容)。单次调用中的parse_mode会覆盖此设置。DDG_REF_URL_THRESHOLD:搜索结果 URL 超过此字符数时,会替换为较短的ref://<id>令牌(默认:120)。设置为0可始终显示完整 URL。也可使用--ref-url-threshold。
- 重启 Claude Desktop
与 Claude Code 配合运行
- 下载 Claude Code
- 确保已安装
uvenv,并且uvx命令可用 - 添加 MCP 服务:
claude mcp add ddg-search uvx duckduckgo-mcp-server
使用 SSE 或 Streamable HTTP 运行
该服务支持其他 MCP 客户端使用的备用传输方式:
# SSE transport
uvx duckduckgo-mcp-server --transport sse
# Streamable HTTP transport
uvx duckduckgo-mcp-server --transport streamable-http
默认传输方式为 stdio,Claude Desktop 和 Claude Code 使用该方式。
使用 sse 或 streamable-http 运行时,请通过 --host 和 --port 标志覆盖默认绑定地址(127.0.0.1:8000):
uvx duckduckgo-mcp-server --transport streamable-http --host 0.0.0.0 --port 7070
在反向代理后或 Docker 中运行
MCP SDK 为 HTTP 传输启用了 DNS 重绑定保护,默认情况下只接受 localhost 的 Host/Origin 标头。在反向代理后或容器中运行时,客户端的 Host 标头会不匹配,因此请求会失败并返回 421 Misdirected Request。
可将客户端实际使用的主机和来源列入允许列表来解决此问题(建议采用此方式,而不是禁用保护)。值支持 host、host:port 和通配端口 host:*:
uvx duckduckgo-mcp-server --transport streamable-http --host 0.0.0.0 --port 7070 \
--allowed-hosts ddg-mcp.example.com "ddg-mcp.example.com:*" \
--allowed-origins "https://ddg-mcp.example.com"
也可以使用等效的环境变量(以逗号分隔):DDG_ALLOWED_HOSTS、DDG_ALLOWED_ORIGINS。
作为最后手段,你可以通过 --disable-dns-rebinding-protection(或 DDG_DISABLE_DNS_REBINDING_PROTECTION=1)彻底关闭检查。建议使用允许列表;禁用保护会移除一道防范 DNS 重绑定攻击的屏障。如果未配置任何内容,则会保留仅允许 localhost 的安全默认设置。
在 TLS 拦截代理后运行
企业代理会通过自己的 CA 重新签署 HTTPS 流量(通过 HTTPS_PROXY),导致出站请求因证书验证错误而失败,因为 HTTP 客户端不信任代理的自签名 CA(而 httpx 不再读取 SSL_CERT_FILE 环境变量)。请将服务指向代理的 CA 证书包:
uvx duckduckgo-mcp-server --ca-certs /path/to/proxy-ca.pem
或者设置 DDG_CA_CERTS=/path/to/proxy-ca.pem。search 和 fetch_content 工具都会使用此证书包,httpx 和 curl 后端均适用。
作为最后手段,--no-ssl-verify(或 DDG_SSL_VERIFY=0)会彻底禁用证书验证。这会使流量暴露给网络路径上的任何人进行拦截;建议使用 --ca-certs。
后端(绕过机器人检测)
有些网站——最近 DuckDuckGo 自己的搜索端点(html.duckduckgo.com)也一样——会因默认 httpx 客户端独特的 TLS 指纹而将其拦截,无论 User-Agent 是什么。Cloudflare Bot Management 和类似过滤器会检查 JA3/TLS 握手,而不是标头,因此 html.duckduckgo.com 可能会向 httpx 返回空的 HTTP 202 页面(静默地导致“无结果”)。可选的 curl 后端(通过 curl_cffi 实现)会模拟真实 Chrome 浏览器的 TLS 握手,从而通过这些检查。
search 工具和 fetch_content 工具都支持这些后端。
安装:
# Default install (httpx only)
uv pip install duckduckgo-mcp-server
# With the optional browser backend
uv pip install "duckduckgo-mcp-server[browser]"
后端选项:
| 值 | 行为 | 需要 [browser] |
|---|---|---|
httpx | 轻量级异步 HTTP。默认选项。适用于大多数网站。 | 否 |
curl | 使用 curl_cffi 模拟 Chrome 131 的 TLS。可通过基于 TLS 指纹的过滤器。 | 是 |
auto | 先尝试 httpx;遇到 403 或 Cloudflare 挑战响应时,再使用 curl 重试。 | 是 |
配置后端的两种方式:
-
服务级默认设置:通过
--fetch-backendCLI 标志配置(适用于每次fetch_content调用):# Default behavior — uses httpx uvx duckduckgo-mcp-server # Force curl for every fetch (requires the [browser] extra) uvx --with "duckduckgo-mcp-server[browser]" duckduckgo-mcp-server --fetch-backend curl # Try httpx first, fall back to curl on 403 / Cloudflare challenge uvx --with "duckduckgo-mcp-server[browser]" duckduckgo-mcp-server --fetch-backend auto -
单次调用覆盖:通过
fetch_content工具的backend参数配置(仅对这次调用覆盖 CLI 默认设置)。该工具会在其输入架构中公开backend,因此 MCP 客户端可以在每次抓取时选择"httpx"、"curl"或"auto"。
对于 fetch_content,默认值仍为 httpx,因此不需要模拟功能的用户无需承担额外依赖带来的开销。
搜索后端
由于 DuckDuckGo 的搜索端点现在会通过指纹识别拦截纯 httpx 请求,search 工具默认使用 auto:它会先尝试 httpx,检测到拦截(HTTP 202/403)时再回退到 curl。只有安装了 [browser] 扩展后,回退机制才能生效;否则,搜索会返回提示你安装该扩展的消息。
使用 --search-backend CLI 标志或 DDG_SEARCH_BACKEND 环境变量配置搜索后端(auto(默认值)/ httpx / curl):
# Recommended: install the browser extra so the auto fallback can impersonate Chrome
uvx --with "duckduckgo-mcp-server[browser]" duckduckgo-mcp-server
# Force curl for every search
uvx --with "duckduckgo-mcp-server[browser]" duckduckgo-mcp-server --search-backend curl
# Opt out of the fallback (legacy behavior — may return no results while blocked)
uvx duckduckgo-mcp-server --search-backend httpx
开发
本地开发:
# Install dependencies
uv sync
# Run with the MCP Inspector
mcp dev src/duckduckgo_mcp_server/server.py
# Install locally for testing with Claude Desktop
mcp install src/duckduckgo_mcp_server/server.py
# Run all tests
uv run python -m pytest src/duckduckgo_mcp_server/ -v
# Run only unit tests
uv run python -m pytest src/duckduckgo_mcp_server/test_server.py -v
# Run only e2e tests
uv run python -m pytest src/duckduckgo_mcp_server/test_e2e.py -v
可用工具
1. 搜索工具
async def search(query: str, max_results: int = 10, region: str = "") -> str
在 DuckDuckGo 上执行网页搜索并返回格式化结果。
参数:
query:搜索查询字符串max_results:返回结果的最大数量(默认值:10)region:(可选)用于覆盖默认值的地区/语言代码。留空则使用已配置的默认地区。
地区代码示例:
us-en:美国(英语)cn-zh:中国(中文)jp-ja:日本(日语)de-de:德国(德语)fr-fr:法国(法语)wt-wt:不指定特定地区
返回值: 包含搜索结果标题、URL 和摘要的格式化字符串。
使用示例:
- 使用默认设置搜索:
search("python tutorial") - 指定地区搜索:
search("latest news", region="jp-ja"),搜索日语新闻
2. 内容抓取工具
async def fetch_content(
url: str,
start_index: int = 0,
max_length: int = 8000,
backend: Optional[str] = None,
parse_mode: Optional[str] = None,
) -> str
抓取并解析网页内容。
参数:
url:要抓取内容的网页 URL,或搜索结果中的ref://<id>令牌start_index:开始读取的字符偏移量(用于分页)max_length:要返回的最大字符数backend:可选的单次调用后端覆盖设置("httpx"、"curl"或"auto")。省略时,使用服务启动时通过--fetch-backend设置的值。parse_mode:可选的单次调用提取器("text"、"main"或"markdown")。省略时,使用DDG_PARSE_MODE/--parse-mode的设置(默认值为text)。
返回值:
从网页中提取并格式化的文本内容。解析后的完整页面会缓存在内存中(默认 5 分钟),因此后续通过 start_index 获取页面时无需重新下载。启用缓存时,元数据会包含 cache=hit 或 cache=miss。
SSRF 保护: 默认情况下,
fetch_content会拒绝解析到回环、私有(RFC1918)、链路本地(包括169.254.169.254云元数据端点)、保留、多播或未指定地址的 URL,并会对每次重定向跳转重新验证。仅允许http/httpsURL。对于需要抓取内部主机的可信本地部署,可通过DDG_ALLOW_PRIVATE_URLS=1或--allow-private-urls禁用防护。详情请参阅 SECURITY.md。
3. 链接展开工具
async def expand_link(token: str) -> str
搜索结果会将长度超过 DDG_REF_URL_THRESHOLD 个字符(默认值为 120)的 URL 替换为简短、稳定的 ref://<id> 令牌,以免包含大量跟踪参数的长链接占用上下文。fetch_content 可以接受令牌代替 URL,因此只有在模型需要显示或引用真实链接时才需要使用此工具。
参数:
token:搜索结果中原样出现的ref://<id>令牌(仅使用 ID 也可以)
返回值: 完整的原始 URL;如果令牌未知,则返回错误。令牌在服务进程运行期间保存在内存中(受 LRU 上限约束),因此服务重启后会被清除。
功能详解
速率限制
- 搜索:默认每分钟 30 次请求(
DDG_SEARCH_RPM/--search-rpm) - 内容抓取:全局每分钟 20 次请求(
DDG_FETCH_RPM/--fetch-rpm) - 可选的单主机抓取上限,默认关闭(
DDG_FETCH_HOST_RPM/--fetch-host-rpm) - 策略:可通过
DDG_RATE_LIMIT_STRATEGY/--rate-limit-strategy设置为sliding(默认)或token_bucket - HTTP 429 响应会遵循
Retry-After(上限为 30 秒),并重试一次 fetch_content命中缓存时,会跳过下载和抓取速率限制器
内容缓存
- 缓存完整解析后的页面(分页前),采用内存 TTL 缓存
- 默认 TTL 为 300 秒,最多缓存 64 条,按最近最少使用策略淘汰
- 错误永远不会被缓存
- 使用
DDG_CACHE_TTL/DDG_CACHE_MAX_ENTRIES或--cache-ttl/--cache-max-entries配置 - 将任一值设为
0即可禁用
结果处理
- 移除广告和无关内容
- 清理 DuckDuckGo 重定向 URL
- 将结果格式化为适合大模型使用的形式
- 适当截断过长的内容
内容解析模式
fetch_content 接受 parse_mode:
| 模式 | 行为 |
|---|---|
text | 历史默认模式。移除页面框架内容,返回扁平化的页面文本。 |
main | 仅保留主要的 article / main / 内容容器。 |
markdown | 保留相同的主要内容,并以轻量级 Markdown 格式呈现(标题、列表、链接、代码)。 |
内容安全
-
SafeSearch 过滤:通过服务启动时的
DDG_SAFE_SEARCH环境变量进行配置- 由管理员控制,AI 助手无法修改
- 根据所选级别过滤不当内容
- 使用 DuckDuckGo 官方的
kp参数
-
区域本地化:
- 通过
DDG_REGION环境变量设置默认区域 - AI 助手可针对每次搜索请求覆盖该设置
- 提高特定地理区域内结果的相关性
- 通过
错误处理
- 全面捕获并报告错误
- 通过 MCP 上下文记录详细日志
- 遇到速率限制或超时时优雅降级
贡献
欢迎提交问题和拉取请求!
许可证
本项目采用 MIT 许可证。
Star 历史
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。