CAUTION version 1.0.1 · audited 2026-09-09
This skill is a thin command-line wrapper around Tavily's web search API. A single Node.js script takes a search query plus optional flags (result count, depth, topic, time range, domain filters), reads the user's Tavily API key from the TAVILY_API_KEY environment variable, POSTs the query to https://api.tavily.com/search, and prints the results as Markdown or raw JSON. There is no shell execution, no file writing, no package installation, no persistence, and no network destination other than Tavily's documented endpoint. The API key is only used in the Authorization header to the vendor it belongs to; it is never printed or sent elsewhere. The main residual risk is inherent to any web search tool: search results come from untrusted web pages and, if fed back into an agent, could contain prompt-injection text.
Instructions try to steer the agent beyond the declared purpose. The script prints third-party web content fetched from Tavily directly to stdout, which an agent will typically read as context: 'console.log(` ${content.slice(0, 300)}${content.length > 300 ? "..." : ""}`);' (scripts/search.mjs line 143) and optional full raw page content via --raw-content (line 93). This is standard for a search tool, but returned page text is untrusted and could contain instructions aimed at the agent. No injection attempts exist in the package files themselves.
| Declared purpose | Web search via Tavily's LLM-optimized API, returning results with content snippets, relevance scores, and metadata (SKILL.md lines 2-3). |
| Observed behavior | scripts/search.mjs parses CLI arguments, requires TAVILY_API_KEY (line 81), builds a JSON request body from the user's query and options, and sends a single POST to https://api.tavily.com/search with the key as a Bearer token (lines 100-107). It then prints the answer and result list to stdout (lines 116-150). No other network calls, no subprocess execution, no filesystem writes, no environment scanning beyond the one expected key. |
| Verdict, rules only | CAUTION · reads credential-like environment variables: TAVILY_API_KEY |
| Verdict, AI | SAFE |
| Final verdict | CAUTION (never better than either pass) |
| capability | vs purpose | detail |
|---|---|---|
| network | needed | Single outbound HTTPS POST to https://api.tavily.com/search (scripts/search.mjs line 100). No other hosts contacted. |
| credentials | needed | Reads TAVILY_API_KEY from the environment (line 81) and sends it only in the Authorization header to Tavily (line 104). Key is not logged or transmitted elsewhere. |
| severity | finding |
|---|---|
| info | Reads the Tavily API key from the environment The skill requires one sensitive environment variable. It is used solely for authenticating to Tavily; there is no code path that writes it to a file or sends it to any other destination. scripts/search.mjs:81 const apiKey = (process.env.TAVILY_API_KEY ?? "").trim(); |
| info | Single hardcoded network destination The only outbound request goes to the documented Tavily search endpoint. The URL is a literal, not built from user input or remote configuration, so there is no hidden or redirectable destination. scripts/search.mjs:100 const resp = await fetch("https://api.tavily.com/search", { |
| low | API key transmitted to vendor with each search Queries and options are sent to Tavily along with the user's key. This is expected for the declared purpose, but means every query leaves the local environment; do not include secrets in queries. scripts/search.mjs:104 "Authorization": `Bearer ${apiKey}`, |
| low | Untrusted web content is echoed to the agent Snippets (or full page text with --raw-content) from arbitrary websites are printed verbatim. An agent consuming this output should treat it as data, not instructions, since attacker-controlled pages could include prompt-injection text. scripts/search.mjs:143 console.log(` ${content.slice(0, 300)}${content.length > 300 ? "..." : ""}`); |
| info | No actual filesystem write despite scan flag The automated scan flagged a file write at this line, but the code only reads the HTTP error response body into a variable for the thrown error message. No files are created or modified anywhere in the package. scripts/search.mjs:110 const text = await resp.text().catch(() => ""); |
0 AI finding(s) were dropped because their file, line or quote did not match the package.
| domain | service rating | where |
|---|---|---|
| api.tavily.com | not in the service index | scripts/search.mjs:100 |
| clawhub.ai | not in the service index | skill-card.md:7 |
| tavily.com | not in the service index | SKILL.md:4 |
| Binaries invoked | bash, node, python |
| Environment variables read | TAVILY_API_KEY |
| Hard-coded wallets | none |
| Pipes a download to a shell | 0 |
| eval / exec / subprocess | 0 |
| base64 blobs | 0 |
| File writes | 1 |
| Persistence | 0 |
| file | lines | sha256 |
|---|---|---|
SKILL.md | 92 | 66c9539968a23300… |
_meta.json | 6 | 8d35c2032cd0880d… |
scripts/search.mjs | 150 | 7bba79629e3af4dd… |
skill-card.md | 41 | 8e9c40922bac2e8e… |
For agents
JSON: https://agenteconomy.report/k/liang-tavily-search.audit.json · badge: https://agenteconomy.report/k/liang-tavily-search.audited.svg ·
skill rating: /k/liang-tavily-search · commission an audit of any skill: US$ 29 per version.
The complete published package of this exact version was downloaded from the registry and read statically; nothing was executed. A deterministic pass extracts network destinations, binaries, environment variables, writes, install commands, obfuscation markers, subprocesses and wallets, each with file and line. An AI then reads the whole package with those facts and writes the summary, the capabilities and the findings under a strict schema; every finding it produces must cite a file, a line and the exact text, or it is dropped. The final verdict is the worst of the two passes. The audit does not change the skill's trust tier (policy); the author may respond through the dispute channel and the response is published here. Commissioned by: the Agent Economy Report (free program: the 150 most downloaded skills, September 2026).