Skip to main content

Kestrel Search

Python 3.13+ Search source: DuckDuckGo HTML Agent-ready JSON GitHub stars

Kestrel Search logo

Kestrel Search turns a web query into a small set of readable, relevant pages. It searches DuckDuckGo, fetches result pages concurrently, extracts their main text, and re-ranks the results with BM25. The command line stays pipe-friendly: data goes to stdout and progress goes to stderr.

It is useful when search snippets are not enough and an agent or script needs page content it can work with.

Note Kestrel Search is an independent project and is not affiliated with DuckDuckGo.

Install

Requires Python 3.13 or later.

# With uv
uv tool install kestrelsearch

# Or with pip
pip install kestrelsearch

Quick start

# Search, fetch the matching pages, and rank them by relevance
kestrelsearch search "python dataclasses"

# Send structured results to another program or agent
kestrelsearch search "rust ownership" --output json

# A fast snippet-only search, without fetching pages
kestrelsearch search "openai news" --no-fetch

What it does

  • Searches DuckDuckGo’s HTML endpoint, with optional region and recency filters.
  • Fetches result pages concurrently over HTTP/2.
  • Removes common page chrome and extracts headings, paragraphs, and list content.
  • Re-ranks fetched results against the original query using BM25.
  • Returns readable terminal output or clean JSON.

For agents

Use JSON output when Kestrel Search is called from an agent, script, or pipeline. Progress messages are written to stderr, leaving stdout safe to parse.

kestrelsearch search "recent Python packaging changes" \
  --time-filter m \
  --top-k 3 \
  --output json > results.json

Each result contains the search metadata plus extracted content when fetching is enabled:

Field Description
title Result title
url Result URL
display_url Shortened URL shown in the search result
snippet Search-result snippet
content Extracted page text, prefixed with its source URL; null if unavailable
bm25_score Relevance score when ranking is enabled

To make the command discoverable to supported coding agents, install its generated SKILL.md:

# Prompts for the agent and whether to install locally or globally
kestrelsearch skill install

# Or install for every supported agent without prompts
kestrelsearch skill install --agent all --scope global

It supports Claude Code, Codex, and GitHub Copilot in VS Code. Use --agent claude, --agent codex, or --agent vscode to target one agent; --agent both remains available for Claude Code and VS Code Copilot. Installed skill locations are tracked locally, so kestrelsearch skill uninstall can remove them later.

Agent Project install Global install
Claude Code .claude/skills/kestrelsearch/SKILL.md ~/.claude/skills/kestrelsearch/SKILL.md
Codex .codex/skills/kestrelsearch/SKILL.md ~/.codex/skills/kestrelsearch/SKILL.md
GitHub Copilot in VS Code .github/skills/kestrelsearch/SKILL.md ~/.copilot/skills/kestrelsearch/SKILL.md

Useful options

# Return three results
kestrelsearch search "climate change" --top-k 3

# Limit results to the past day; use d, w, m, or y
kestrelsearch search "breaking news" --time-filter d

# Narrow the DuckDuckGo region
kestrelsearch search "local elections" --region us-en

# Tune fetching for a pipeline
kestrelsearch search "machine learning" \
  --concurrency 8 --timeout 15 --content-limit 3000

# Keep DuckDuckGo ordering rather than applying BM25 ranking
kestrelsearch search "python typing" --no-rank

Run kestrelsearch search --help for the complete CLI reference.

How it works

  1. Kestrel Search submits the query to DuckDuckGo’s HTML endpoint and parses the result list.
  2. Unless --no-fetch is used, it fetches eligible result pages concurrently.
  3. It strips common boilerplate, focuses on likely main content, and keeps meaningful headings and body text.
  4. BM25 scores the extracted text against the original query and returns the best matches.

PDFs are skipped during page fetching. If fetching or extraction fails for a result, the result is retained with content: null; BM25 ranking may omit zero-relevance results.

Development

git clone https://github.com/rafaelpierre/kestrelsearch
cd kestrelsearch
uv sync
uv run kestrelsearch search "test"

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kestrelsearch-1.0.0.tar.gz (261.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kestrelsearch-1.0.0-py3-none-any.whl (14.7 kB view details)

Uploaded Python 3

File details

Details for the file kestrelsearch-1.0.0.tar.gz.

File metadata

  • Download URL: kestrelsearch-1.0.0.tar.gz
  • Upload date:
  • Size: 261.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for kestrelsearch-1.0.0.tar.gz
Algorithm Hash digest
SHA256 5155d5c33947013881f5ab9df9083d242f1470ef12f6a4eee0d23ebaee97bbad
MD5 4d88071fd30d6ef073f457fdfbbe0610
BLAKE2b-256 82bc62b5752fd285b9218ad459b1b34d069d9b4fedb9b9b2bd9904e82811a919

See more details on using hashes here.

Provenance

The following attestation bundles were made for kestrelsearch-1.0.0.tar.gz:

Publisher: release.yml on rafaelpierre/kestrelsearch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file kestrelsearch-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: kestrelsearch-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 14.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for kestrelsearch-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c854e72a1a88b90b4a6187b793c4cb17268e58421a98c5fa672c1e5faba7cb24
MD5 86fcffb6fad16d26acd7b071405b6dfc
BLAKE2b-256 f3fbcade772c5317680089d9cd770636d289652a96135a486503625531ddab4a

See more details on using hashes here.

Provenance

The following attestation bundles were made for kestrelsearch-1.0.0-py3-none-any.whl:

Publisher: release.yml on rafaelpierre/kestrelsearch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.1.1

2 files

1.1.0

2 files

1.0.1

2 files

This release

1.0.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page