Duckduckgo Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Duckduckgo Mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A production-ready Model Context Protocol (MCP) server that performs real-time internet searches via the DuckDuckGo Lite endpoint (https://lite.duckduckgo.com/lite/) with automatic retry logic, intelligent caching, and robust error handling.
Supports all three MCP transports:
duckduckgo-tool/
├── duckduckgo_server.py # Main MCP server entry point
├── pyproject.toml
├── Dockerfile
├── README.md
├── pytest.ini
├── tests/
│ ├── __init__.py
│ └── test_search_tools.py
└── src/
└── duckduckgo_browser/
├── __init__.py
├── __main__.py # python -m duckduckgo_browser
├── duckduckgo_server.py # stub (canonical server is at root)
├── services/
│ ├── __init__.py
│ ├── search_engine.py # RealSearchEngine — DuckDuckGo Lite
│ └── web_scraper.py # DuckDuckGoScraper with retry & cache
└── tools/
├── __init__.py
├── toolhandler.py # Abstract base class
└── search_tools.py # get_internet_result tool handlerget_internet_resultPerforms a real-time search on DuckDuckGo Lite and returns a concise answer with source links.
| Parameter | Type | Required | Description |
|---|---|---|---|
input_value | string | ✅ | Natural language query or search term |
Example output:
Answer: Machine learning is a branch of artificial intelligence that enables systems to learn
and improve from experience without being explicitly programmed.
Source 1: https://www.ibm.com/topics/machine-learning
Source 2: https://www.google.com/search?q=what+is+machine+learning# Create and activate virtual environment
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
# Install dependencies
pip install -e .Dependencies:
mcp[cli] >= 1.12.0starlette >= 0.27.0uvicorn >= 0.20.0requests >= 2.31.0beautifulsoup4 >= 4.12.0truststore >= 0.10.0The server is controlled by environment variables or CLI flags. Environment variables take priority and are used for container deployments.
| Environment Variable | Default | Description |
|---|---|---|
TRANSPORT_TYPE | streamable-http | Transport mode: stdio, sse, streamable-http |
APP_HOST | 0.0.0.0 | Bind host |
APP_PORT | 8000 | Bind port |
duckduckgo-mcp --mode stdioduckduckgo-mcp --mode sse --host 0.0.0.0 --port 8000Endpoints:
GET /sse — open SSE streamPOST /messages/ — send MCP request framesGET /health — health checkGET /healthz — health check (alias)GET / — server infoduckduckgo-mcp --mode streamable-http --host 0.0.0.0 --port 8000Endpoints:
POST /mcp — single MCP endpoint, chunked streaming responseGET /health — health checkGET /healthz — health check (alias)GET / — server info# Build
docker build -t duckduckgo-mcp .
# Run streamable-http (default)
docker run -p 8000:8000 duckduckgo-mcp
# Run SSE mode
docker run -e TRANSPORT_TYPE=sse -e APP_PORT=8000 -p 8000:8000 duckduckgo-mcp
# Run with custom port
docker run -e TRANSPORT_TYPE=streamable-http -e APP_PORT=9000 -p 9000:9000 duckduckgo-mcp
# Run stdio mode (pipe-based)
docker run -i -e TRANSPORT_TYPE=stdio duckduckgo-mcp{
"mcpServers": {
"duckduckgo": {
"type": "streamable-http",
"url": "http://localhost:8000/mcp"
}
}
}{
"mcpServers": {
"duckduckgo": {
"type": "sse",
"url": "http://localhost:8000/sse"
}
}
}{
"mcpServers": {
"duckduckgo": {
"command": "duckduckgo-mcp",
"args": ["--mode", "stdio"]
}
}
}Streamable HTTP:
duckduckgo-mcp --mode streamable-http --port 8000http://localhost:8000/mcpget_internet_result with {"input_value": "what is machine learning"}SSE:
duckduckgo-mcp --mode sse --port 8000http://localhost:8000/sseget_internet_result with {"input_value": "best cloud providers 2026"}User Query
↓
get_internet_result (async tool handler)
↓
RealSearchEngine.search()
↓
DuckDuckGoScraper.search_with_retry()
├─ Check in-memory cache (5-min TTL)
├─ Cache hit → return cached results
└─ Cache miss → fetch from DuckDuckGo Lite
├─ Attempt 1 (10s timeout)
├─ Fail → wait 2s → Attempt 2
├─ Fail → wait 4s → Attempt 3
└─ All fail → return stale cache or empty result
↓
Auto-detect category from result content
↓
Format: Answer + Source 1 + Source 2| Feature | Details |
|---|---|
| Search Source | DuckDuckGo Lite (https://lite.duckduckgo.com/lite/) with HTML + Instant Answer API fallback |
| Retry Logic | 3 attempts with exponential backoff (2s, 4s) |
| Request Timeout | 10 seconds per attempt |
| Caching | In-memory, 5-min TTL, stale fallback on network failure |
| SSL | OS trust store via truststore; falls back to SSL-disabled as last resort |
| CORS | Fully open (allow_origins=["*"]) for all HTTP modes |
| Session Timeout | 60s per request (streamable-http), unlimited (stdio) |
Results are automatically categorised from URL, title, and snippet content:
ai · programming · cloud · finance · health · science · education · travel · food · sports · general
For EC2/Kubernetes, set transport mode and port via environment variables — no image rebuild needed:
# Streamable HTTP deployment
env:
- name: TRANSPORT_TYPE
value: "streamable-http"
- name: APP_PORT
value: "8000"
- name: APP_HOST
value: "0.0.0.0"
# SSE deployment
env:
- name: TRANSPORT_TYPE
value: "sse"
- name: APP_PORT
value: "8000"
- name: APP_HOST
value: "0.0.0.0"No supergateway wrapper is needed. The server handles its own HTTP binding directly for both SSE and streamable-http modes.
pip install pytest pytest-asyncio
pytestPort already in use
duckduckgo-mcp --mode streamable-http --port 8001No search results returned
curl "https://lite.duckduckgo.com/lite/?q=test" PYTHONPATH=src python -c "import logging; logging.basicConfig(level=logging.DEBUG)"SSL errors in corporate network
verify_ssl=False in web_scraper.py DuckDuckGoScraper initImport errors after install
pip install -e . --force-reinstallTune scraper behaviour in src/duckduckgo_browser/services/web_scraper.py:
DuckDuckGoScraper(
timeout=10.0, # Request timeout per attempt (seconds)
max_retries=3, # Number of retry attempts
retry_backoff_base=2.0, # Exponential backoff base (2s, 4s, ...)
cache_ttl=300, # Cache TTL in seconds (5 minutes)
)| Scenario | Behaviour |
|---|---|
| Network timeout | Retry up to 3x with exponential backoff |
| All retries fail | Return stale cache if available, else empty result |
| DuckDuckGo Lite unavailable | Fall back to HTML endpoint, then Instant Answer API |
| SSL certificate error | Retry with SSL verification disabled |
| Invalid query | Validation error returned as TextContent |
| Port conflict | Clear error log with suggested fix |
| Container restart | Cache cleared (in-memory); fresh searches on next request |
MIT License — see LICENSE file for details
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.