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 across all transport modes.
Previously: Simulated search with a deterministic knowledge base Now: Live web search results with enterprise-grade reliability
✨ Real-Time Search: Fetch live results from DuckDuckGo Lite 🔄 Automatic Retries: 3 attempts with exponential backoff 💾 Smart Caching: 5-minute TTL with stale-data fallback ⏱️ Timeout Protection: Request-level and session-level timeouts 📊 Auto-Detection: Category detection from search results 🛡️ Robust Modes: Enhanced error handling for STDIO, SSE, and Streamable HTTP 📝 Detailed Logging: Debug-friendly operation tracking
duckduckgo-browser-mcp/
├── src/
│ └── duckduckgo_browser/
│ ├── __init__.py # Package entry point (sync main())
│ ├── __main__.py # python -m duckduckgo_browser
│ ├── server.py # MCP app + all three transport modes
│ ├── services/
│ │ ├── __init__.py
│ │ ├── search_engine.py # Real-time search via DuckDuckGo Lite
│ │ └── web_scraper.py # Web scraper with retry logic & caching
│ └── tools/
│ ├── __init__.py
│ ├── toolhandler.py # Abstract base class for tools
│ └── search_tools.py # get_internet_result tool handler
├── tests/
│ ├── __init__.py
│ └── test_search_tools.py
├── Dockerfile
├── pyproject.toml
├── pytest.ini
└── README.mdcd duckduckgo-browser-mcp
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS/Linux
source .venv/bin/activate
pip install -e .Dependencies:
Used by MCP hosts like Claude Desktop, IDE plugins, and CLI clients.
python -m duckduckgo_browser --mode stdioThe server reads JSON-RPC frames from stdin and writes responses to stdout.
python -m duckduckgo_browser --mode sse --host 0.0.0.0 --port 7070GET http://localhost:7070/sse — open SSE streamPOST http://localhost:7070/messages/ — send MCP request framespython -m duckduckgo_browser --mode streamable-http --host 0.0.0.0 --port 7070POST http://localhost:7070/mcp — single endpoint, chunked streaming response# Build
docker build -t duckduckgo-browser-mcp .
# Run (streamable-http, default)
docker run -p 7070:7070 duckduckgo-browser-mcp
# Run SSE mode
docker run -p 7070:7070 duckduckgo-browser-mcp --mode sse --port 7070
# Run STDIO mode (pipe-based)
docker run -i duckduckgo-browser-mcp --mode stdioget_internet_resultPerforms real-time searches on DuckDuckGo Lite with automatic retry and caching.
| Field | Type | Required | Description |
|---|---|---|---|
input_value | string | ✅ | Natural language query or search term |
# DuckDuckGo Browser -- Search Results
- **Query:** "what is machine learning"
- **Topic category detected:** ai
- **Results found:** 5
## Top Results
### 1. Machine Learning Explained
- **URL:** https://www.ibm.com/topics/machine-learning
- **Summary:** Machine learning is a subset of AI ...
- **Relevance score:** 5
## Suggested Websites to Explore
### Hugging Face
- **URL:** https://huggingface.co
- **Why visit:** Leading hub for open-source AI models and datasets
## What to Look For
When researching AI topics, prioritise peer-reviewed papers (arXiv, NeurIPS)
and official model documentation. Cross-check benchmark claims on Papers With Code.
---
*Results powered by DuckDuckGo Lite (https://lite.duckduckgo.com/lite/).*
*Search performed in real-time with automatic retry and caching for reliability.*import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def main():
params = StdioServerParameters(
command="python",
args=["-m", "duckduckgo_browser", "--mode", "stdio"],
)
async with stdio_client(params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool(
"get_internet_result",
{"input_value": "what is machine learning"},
)
print(result.content[0].text)
asyncio.run(main())import asyncio
from mcp import ClientSession
from mcp.client.sse import sse_client
async def main():
async with sse_client("http://localhost:7070/sse") as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool(
"get_internet_result",
{"input_value": "best travel destinations Europe"},
)
print(result.content[0].text)
asyncio.run(main())import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
async with streamablehttp_client("http://localhost:7070/mcp") as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool(
"get_internet_result",
{"input_value": "how does quantum computing work"},
)
print(result.content[0].text)
asyncio.run(main())curl -X POST http://localhost:7070/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl-client","version":"1.0"}}}'# Replace <SESSION_ID> with the mcp-session-id from the initialize response header
curl -X POST http://localhost:7070/mcp \
-H "Content-Type: application/json" \
-H "mcp-session-id: <SESSION_ID>" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_internet_result","arguments":{"input_value":"python web frameworks"}}}'pip install pytest pytest-asyncio
pytestUser Query
↓
get_internet_result tool (async)
↓
RealSearchEngine.search()
↓
DuckDuckGoScraper.search_with_retry()
├─ Check in-memory cache
├─ If cached & valid → return cached results
├─ If cache miss → fetch from DuckDuckGo Lite
│ ├─ Attempt 1: Request + parse (10s timeout)
│ ├─ Timeout? → wait 2s, retry
│ ├─ Attempt 2: Request + parse
│ ├─ Timeout? → wait 4s, retry
│ ├─ Attempt 3: Request + parse
│ ├─ All fail? → return stale cache or empty
└─ Cache new results (5 min TTL)
↓
Auto-detect Category
↓
Curated Website Suggestions
↓
Formatted Markdown ResponseRetry Logic
Caching
Error Handling
Category Detection Results are automatically categorized based on content patterns:
Each category includes curated website suggestions.
Adjust scraper behavior in src/duckduckgo_browser/services/web_scraper.py:
DuckDuckGoScraper(
timeout=10.0, # Request timeout (seconds)
max_retries=3, # Retry attempts
retry_backoff_base=2.0, # Exponential backoff base
cache_ttl=300, # Cache TTL (seconds)
)Adjust HTTP server timeouts in src/duckduckgo_browser/server.py:
Server provides detailed logging at multiple levels:
Startup Output
2026-04-01T15:36:13 INFO duckduckgo-browser ================================================================================
2026-04-01T15:36:13 INFO duckduckgo-browser Starting DuckDuckGo Browser MCP Server
2026-04-01T15:36:13 INFO duckduckgo-browser Python: 3.11.6
2026-04-01T15:36:13 INFO duckduckgo-browser Mode: streamable-http
2026-04-01T15:36:13 INFO duckduckgo-browser Listening at http://0.0.0.0:7070
2026-04-01T15:36:13 INFO duckduckgo-browser Registered tools: ['get_internet_result']Log Levels
Enable debug logging:
import logging
logging.basicConfig(level=logging.DEBUG)| Feature | Details |
|---|---|
| Network Retry | 3x with exponential backoff (2s, 4s) |
| Request Timeout | 10 seconds per attempt |
| Session Timeout | 60s HTTP, 1h SSE, unlimited STDIO |
| Caching | 5-min TTL + stale fallback |
| Error Recovery | Graceful degradation, no crashes |
| STDIO Mode | Handles BrokenPipeError, client disconnect |
| SSE Mode | Connection error handling, CORS support |
| Streamable HTTP | Error responses (504 timeout, 500 error) |
| Logging | DEBUG/INFO/WARNING/ERROR levels |
Port Already in Use
python -m duckduckgo_browser --mode streamable-http --port 8000Connection Timeout
curl https://lite.duckduckgo.com/lite/?q=testNo Results
Dependency Issues
pip install -r requirements.txt
# or
pip install -e .| File | Change | Purpose |
|---|---|---|
services/web_scraper.py | NEW | DuckDuckGo Lite scraper with retry/cache |
services/search_engine.py | Modified | Live search engine (was deterministic) |
services/__init__.py | Modified | Export new functions |
tools/search_tools.py | Modified | Async tool handler |
server.py | Modified | Enhanced error handling & timeouts |
pyproject.toml | Modified | Added requests + beautifulsoup4 |
v1.0.0 (April 2026) - Live DuckDuckGo Search
v0.1.0 (Previous) - Deterministic Knowledge Base
Status: Production Ready ✓ Last Updated: April 1, 2026
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.