Tavily Search (Native Node)
Minimal, auditable Tavily web search.
Native Node.js. Zero dependencies. Two files. Small enough to audit in a few minutes.
Security behavior
- Reads
TAVILY_API_KEYfrom the process environment only. - Does not read credential files or
~/.openclaw/.env. - Sends only the search request/options to
https://api.tavily.com/search. - Does not write files, cache responses, log queries, transmit local files, or print the API key.
When to use
Trigger phrases: "search for", "look up", "what's the latest on", "find recent news about", "research", "compare", "current info on".
Use this when:
- The user needs information past the model's training cutoff
- Current events, news, market data, prices, weather context, recent releases
- Research that needs citations the user can verify
Do NOT use this when:
- The user gives a specific URL to read -> use the
web_fetchtool instead - The question is answerable from training knowledge (basic facts, definitions)
- Privacy-sensitive queries (searches transmit to api.tavily.com)
Want caching, raw full-page content, extract endpoint, or usage stats? Use tavily-search-pro-native-node instead.
How to run
The script is in scripts/search.mjs.
Basic search:
node "<skill-dir>/scripts/search.mjs" "your query here"
News search (past ~7 days by default, freshness-biased):
node "<skill-dir>/scripts/search.mjs" --topic news "software release notes"
Deeper research (costs 2 credits per call):
node "<skill-dir>/scripts/search.mjs" --depth advanced "AI agents market analysis 2026"
(Where <skill-dir> is typically workspace/skills/tavily-search-native-node/.)
All flags
| Flag | Values | Default | Purpose |
|---|---|---|---|
--topic | general | news | general | news biases to fresh articles |
--depth | basic | advanced | basic | advanced = deeper analysis, 2x credits |
--max | 1-20 | 5 | How many results to return |
--days | integer | 7 (news only) | Age window for news topic |
--include | comma list | (none) | Only these domains, e.g. github.com,stackoverflow.com |
--exclude | comma list | (none) | Skip these domains |
--json | flag | off | Return raw JSON instead of formatted output |
Examples
# Compare frameworks, GitHub+SO only
node "./scripts/search.mjs" --include "github.com,stackoverflow.com" "React Native vs Flutter 2026"
# Recent news, 10 results, last 14 days
node "./scripts/search.mjs" --topic news --max 10 --days 14 "small business AI adoption"
# Deep research with JSON for programmatic use
node "./scripts/search.mjs" --depth advanced --json "small business VPN options"
Output format
Human-readable by default:
- Top-line header with query, topic, depth, result count
- Tavily's synthesized Answer (short summary)
- Numbered list of results - title, URL, date (news), snippet
- Footer line with timing info
- ASCII-safe punctuation by default for clean Windows redirection, logs, and email bodies
JSON mode (--json) dumps the full Tavily response as-is, useful for piping into follow-up scripts.
Credentials
Requires TAVILY_API_KEY in the process environment.
If it is not set, the script exits with a clear error message.
Get a key: https://app.tavily.com - free tier is 1,000 searches/month.
Cost & rate limits
--depth basic= 1 credit per search--depth advanced= 2 credits per search- Free tier: 1000 credits/month
- Tavily rate limits on the free tier are per-minute; on 429 the script surfaces the Retry-After in the error.
Agent usage pattern
When invoking this skill, prefer batching:
- Run one well-crafted search per topic rather than many narrow ones
- Prefer
basicdepth unless the user explicitly asks for a deep dive - Use
--includeto scope to trusted domains when appropriate - Quote the sources you cite so the user can verify
Troubleshooting
- "TAVILY_API_KEY not set" -> export the env var in the process environment
- HTTP 401 -> key is invalid or revoked; regenerate at app.tavily.com
- HTTP 429 -> rate limited; wait, retry with longer spacing (script surfaces Retry-After)
- HTTP 432 -> monthly credit cap hit; check usage dashboard
- Network timeout -> transient; retry once
What this skill does
- Reads the Tavily API key from the process environment only
- Sends a POST request to
https://api.tavily.com/search - Prints formatted results to stdout
What this skill does NOT do
- Does not write any files
- Does not make any network calls other than to
api.tavily.com - Does not modify any configuration
- Does not auto-update
- Does not cache (see Pro version for caching)
Publishability notes
This skill is intentionally small and dependency-free for auditability. Before publishing or updating, run node --check scripts/search.mjs, node scripts/search.mjs --help, and a no-key smoke test with a temporary home directory to verify clear credential errors without spending API credits.