mcpField
D
DuckDuckGo Search MCP Server

DuckDuckGo Search MCP Server

本地服务
github.com/nickclyde搜索与检索1.6k8 周前更新

关于 DuckDuckGo Search MCP Server

DuckDuckGo Search MCP 服务通过 DuckDuckGo 提供网页搜索,并可抓取和解析网页内容,输出面向大模型阅读的格式。适合需要联网检索的 AI 助手与开发者。

主要功能

  1. 01DuckDuckGo 网页搜索
  2. 02网页内容抓取与文本提取
  3. 03长 URL 替换为 ref:// 短令牌
  4. 04搜索与抓取的速率限制
  5. 05支持 stdio、SSE 与 Streamable HTTP

适用场景

  1. 01让 AI 助手搜索最新资讯并读取结果页面
  2. 02按地区或语言设置搜索结果
  3. 03在 Claude Desktop 或 Claude Code 中添加网页检索能力

MCP 相关

这是一个 MCP 服务,向 MCP 客户端暴露 search 与 fetch_content 等工具,用于网页搜索和内容获取。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"duckduckgo": {
"command": "uvx",
"args": [
"duckduckgo-mcp-server"
]
}
}
}
启动命令uvx duckduckgo-mcp-server

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiduckduckgo-mcp-server

工具

3

收录的工具列表 · 更新于 2 周前

参数类型必填说明
querystring是
max_resultsinteger否
regionstring否

详细介绍

DuckDuckGo Search MCP 服务

PyPI 版本 PyPI 下载量 Python 版本

一个通过 DuckDuckGo 提供网页搜索功能的模型上下文协议(MCP)服务,还具备内容抓取和解析功能。

快速开始

uvx duckduckgo-mcp-server

功能

  • 网页搜索:搜索 DuckDuckGo,支持高级速率限制和结果格式化
  • 内容抓取:获取并解析网页内容,支持智能文本提取
  • 长 URL 缩短:过长的搜索结果 URL 会转换为较短的 ref:// 令牌,可直接用于 fetch_content,节省上下文
  • 速率限制:内置搜索和内容抓取的速率限制保护
  • 错误处理:全面的错误处理和日志记录
  • 适用于大模型的输出:专为大模型处理而格式化的结果

安装

使用 uv 从 PyPI 安装:

uv pip install duckduckgo-mcp-server

用法

与 Claude Desktop 配合运行
  1. 下载 Claude Desktop
  2. 创建或编辑 Claude Desktop 配置:
    • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
    • Windows:%APPDATA%\Claude\claude_desktop_config.json

添加以下配置:

基本配置(不启用 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。
  1. 重启 Claude Desktop
与 Claude Code 配合运行
  1. 下载 Claude Code
  2. 确保已安装 uvenv,并且 uvx 命令可用
  3. 添加 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 重试。是

配置后端的两种方式:

  1. 服务级默认设置:通过 --fetch-backend CLI 标志配置(适用于每次 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
    
  2. 单次调用覆盖:通过 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/https URL。对于需要抓取内部主机的可信本地部署,可通过 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 历史

Star 历史图表

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。