web.search
The web.search tool searches the web using DuckDuckGo Lite and returns structured results with titles, URLs, and snippets.
Capability Required
tool.invoke:web.search
Network access also requires appropriate spec.network.policy.
Input Schema
{
"type": "object",
"required": ["query"],
"properties": {
"query": {
"type": "string",
"description": "The search query."
}
}
}
Output Schema
{
"type": "object",
"properties": {
"results": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": { "type": "string", "description": "Page title." },
"link": { "type": "string", "description": "URL." },
"snippet": { "type": "string", "description": "Description snippet." }
}
}
}
}
}
Examples
#![allow(unused)] fn main() { let result = agent.invoke_tool("web.search", json!({ "query": "renewable energy breakthroughs 2026" })).await?; for r in result["results"].as_array().unwrap_or(&vec![]) { println!("- {}", r["title"]); println!(" {}", r["link"]); println!(" {}", r["snippet"]); } }
ash tools invoke <agent-id> web.search '{"query": "Rust async programming"}'
Implementation
web.search uses DuckDuckGo Lite (https://duckduckgo.com/lite) with HTML parsing via the scraper crate. Results are returned as a list of {title, link, snippet} objects, with no JavaScript execution or API key required.
Network Policy
spec:
network:
policy: allowlist
allowlist:
- "duckduckgo.com:443"
Or use policy: full for unrestricted access.
Cost
Estimated cost: 0.5
Error Cases
| Error | Cause |
|---|---|
network policy denies outbound | duckduckgo.com not in allowlist |
no results | DuckDuckGo returned no results (empty array, not an error) |
parse error | DuckDuckGo changed their HTML structure |