build-entity-list
Find every entity on the web that matches a natural-language description, and return one organized, deduplicated list — not a pile of search results you have to read and compile yourself.
Before running any command
If tvly is not found on PATH, see https://github.com/tavily-ai/tavily-cli for installation instructions.
Known issue: --output-schema currently requires API-key auth, not OAuth
TODO: remove this section once Tavily's MCP server adds output_schema support to its tavily_research tool — tracked as a gap report filed 2026-08-28.
As of 2026-08, --output-schema fails when the CLI is authenticated via tvly login (OAuth) — that path routes through Tavily's MCP server (mcp.tavily.com), which doesn't yet accept an output_schema parameter on its tavily_research tool, even though the direct REST API/SDK does. If you see Unexpected keyword argument / Internal error... call[tavily_research], this is why.
Fix: authenticate with a raw API key instead of OAuth before using this skill:
tvly login --api-key tvly-YOUR_KEY
# or: export TAVILY_API_KEY=tvly-YOUR_KEY
When to use
- You want a list of things matching a description, and you don't have a starting list yet
- Examples: "AI startups that raised a Series A in 2026", "US states that passed a data-privacy law this year", "open-source alternatives to X"
Not this skill:
- You already have the list and want fields added to each row → fill-missing-fields
- You want one exhaustive report on a single, already-known entity → tavily-research
How it works
Same underlying primitive as fill-missing-fields — tavily-research's --output-schema — but shaped as a list, not a single object, and combined with multiple search angles to maximize coverage before deduplicating.
- Turn the user's criteria into a research query, and define a schema shaped as an array of matches.
- Run
tvly research(often with--model pro— finding every match needs more thorough multi-source search than a single narrow lookup). - Optionally, run a couple of differently-phrased queries to widen coverage, then merge and dedupe by name/URL.
- Return the list as a table (and optionally write it to CSV/JSON).
Quick start
1. Write a schema shaped as a list:
{
"properties": {
"results": {
"type": "array",
"description": "Every distinct entity found that matches the criteria",
"items": {
"type": "object",
"properties": {
"name": {"type": "string", "description": "Name of the matching entity"},
"evidence": {"type": "string", "description": "One-sentence reason it matches the criteria"},
"source_url": {"type": "string", "description": "URL supporting this match"}
},
"required": ["name", "evidence", "source_url"]
}
}
},
"required": ["results"]
}
2. Run the research call:
tvly research "Find AI startups that publicly announced a Series A funding round in 2026. \
List each distinct company once, with a one-sentence reason and a supporting source URL." \
--model pro --output-schema schema.json --json -o findall_results.json
3. (Optional) Widen coverage with a second angled query and merge/dedupe:
python3 << 'PYEOF'
import json
with open('findall_results.json') as f:
result = json.load(f)
content = result.get('content', {})
r1 = json.loads(content) if isinstance(content, str) else content
# Run a second, differently-worded query the same way, save it, and load it here as r2,
# then merge both result sets before deduplicating.
all_entries = r1['results'] # + r2['results'] once you have a second angle
seen, merged = set(), []
for entry in all_entries:
key = entry['name'].strip().lower()
if key not in seen:
seen.add(key)
merged.append(entry)
for m in merged:
print(f"- {m['name']}: {m['evidence']} ({m['source_url']})")
PYEOF
Options
Same underlying flags as tavily-research:
| Option | Description |
|---|---|
--model |
pro recommended by default — "find all" needs broader multi-angle search than a narrow lookup; drop to mini only for tightly scoped criteria |
--output-schema |
Schema with a top-level array field — this is what makes the output a list instead of a report |
--json |
Required to parse the array programmatically |
--citation-format |
Use if you need formatted citations per entity rather than raw URLs |
Tips
- Ask for "distinct"/"each once" explicitly in the query. Without it, results can repeat the same entity under slightly different phrasing.
- Widen with multiple angled queries for anything that matters. One
researchcall is good coverage, not guaranteed complete coverage — for a "find all" claim you're going to rely on, run 2-3 differently-worded queries and dedupe, the same multi-source pattern already used intavily-dynamic-search. - Always require a source URL per entry. A finding with no source is unverifiable — treat schema fields like
evidence/source_urlas non-optional. prooverminifor breadth. This is the one place wherepro's extra time is usually worth it — the whole point is not missing matches.- Tell the user what was NOT covered. If you scoped the search to certain sources/time ranges, say so — silent narrowing looks like completeness when it isn't.
See also
- tavily-research — the underlying structured-output capability this skill wraps
- fill-missing-fields — for completing a list you already have, rather than building one
- tavily-dynamic-search — the multi-angle-search-then-dedupe pattern this skill borrows