Exa Search
Use Exa directly over HTTP through the bundled cross-platform Python CLI.
Entry point
Cross-platform:
uv run --script <skill-dir>/scripts/cli.py ...Set <skill-dir> to this skill directory. Do not rely on shell sourcing, executable bits, or shebang dispatch.
Credential check policy: run the documented CLI entrypoint first; it auto-loads a skill-local .env using the lookup order below. Only report missing credentials if the CLI itself fails after that lookup.
When to use
- Deeper web research with richer retrieval than lightweight search
- Fetching full-page contents from known URLs
- Grounded answer generation from web results
- Exa research mode for bigger synthesis tasks
Quick start
uv run --script <skill-dir>/scripts/cli.py search "best sqlite backup strategy" 5
uv run --script <skill-dir>/scripts/cli.py contents https://sqlite.org/backup.html
uv run --script <skill-dir>/scripts/cli.py answer "What is the capital of France?"
uv run --script <skill-dir>/scripts/cli.py research "Summarize the current state of OpenTelemetry in the Java ecosystem" exa-researchCredentials
- Keep
.envbeside this skill. - CLI lookup order:
- EXA_SEARCH_ENV_FILE - skill .env - $SKILLS_DIR/exa-search/.env - nearest ancestor skills/exa-search/.env
- Tracked template:
.env.example
Failure handling
- If a CLI run says
EXA_API_KEY required, retry once with the documenteduv run --scriptcommand; do not assume the parent shell env is authoritative. - If env loading still fails, set
EXA_SEARCH_ENV_FILEto the skill-local.envdynamically from the skill path rather than hard-coding a home directory. - Distinguish env lookup failures from provider failures:
- EXA_API_KEY required means local env discovery failed. - HTTP 401, 402, 403, or similar means the API responded and the key/account/quota is the issue.
- When the API responds with an auth/billing/quota error, report that explicitly instead of claiming the skill lacks credentials.
Notes
- Auth header:
x-api-key: $EXA_API_KEY searchis the best default entrypoint.- Use
contentswhen you already know the target URL(s). - Use
postfor advanced payloads not covered by convenience wrappers. - For code-specific public usage patterns, prefer
grep-app,gh, andcontext7before forcing Exa.
Raw examples
uv run --script <skill-dir>/scripts/cli.py post /search '{"query":"rust async channels","numResults":5}'
uv run --script <skill-dir>/scripts/cli.py post /contents '{"urls":["https://example.com/article"]}'
uv run --script <skill-dir>/scripts/cli.py post /answer '{"query":"What is Bun?"}'Validation
uv run --script <skill-dir>/scripts/cli.py --helpQuery templates
See assets/query-templates.json.
Reference
See reference.md.