From duckdb-skills
Searches DuckDB and DuckLake documentation and blog posts via full-text search on locally cached indexes. Returns relevant doc chunks for questions or keywords on DuckDB features.
npx claudepluginhub duckdb/duckdb-skills --plugin duckdb-skillsThis skill is limited to using the following tools:
You are helping the user find relevant DuckDB or DuckLake documentation.
Fetches dbt docs in markdown via .md URLs or llms.txt index; searches full content with bash script. For dbt Core, Cloud, Semantic Layer queries.
Guides DuckDB SQL writing, analytical queries, CSV/Parquet/JSON ingestion, ETL pipelines, client APIs for Python/Node/Rust/Java/Go, extensions, configuration, and performance tuning.
Executes raw SQL or natural language queries against attached DuckDB databases or ad-hoc files. Manages session state, schema retrieval, and result size estimation.
Share bugs, ideas, or general feedback.
You are helping the user find relevant DuckDB or DuckLake documentation.
Query: $@
Follow these steps in order.
command -v duckdb
If not found, delegate to /duckdb-skills:install-duckdb and then continue.
duckdb :memory: -c "INSTALL httpfs; INSTALL fts;"
If this fails, report the error and stop.
The query is: $@
There are two search indexes available:
| Index | Remote URL | Local cache filename | Versions | Use when |
|---|---|---|---|---|
| DuckDB docs + blog | https://duckdb.org/data/docs-search.duckdb | duckdb-docs.duckdb | lts, current, blog | Default — any DuckDB question |
| DuckLake docs | https://ducklake.select/data/docs-search.duckdb | ducklake-docs.duckdb | stable, preview | Query mentions DuckLake, catalogs, or DuckLake-specific features |
Both indexes share the same schema:
| Column | Type | Description |
|---|---|---|
chunk_id | VARCHAR (PK) | e.g. stable/sql/functions/numeric#absx |
page_title | VARCHAR | Page title from front matter |
section | VARCHAR | Section heading (null for page intros) |
breadcrumb | VARCHAR | e.g. SQL > Functions > Numeric |
url | VARCHAR | URL path with anchor |
version | VARCHAR | See table above |
text | TEXT | Full markdown of the chunk |
By default, search DuckDB docs and filter to version = 'lts'. Use different versions when:
current/nightly features → version = 'current'version = 'blog'version = 'stable'If the input is a natural language question (e.g. "how do I find the most frequent value"), extract the key technical terms (nouns, function names, SQL keywords) to form a compact BM25 query string. Drop stop words like "how", "do", "I", "the".
If the input is already a function name or technical term (e.g. arg_max, GROUP BY ALL), use it as-is.
Use the extracted terms as SEARCH_QUERY in the next step.
The cache lives at $HOME/.duckdb/docs/CACHE_FILENAME (where CACHE_FILENAME is duckdb-docs.duckdb or ducklake-docs.duckdb per Step 3).
First, ensure the directory exists:
mkdir -p "$HOME/.duckdb/docs"
Then check whether the cache file exists and is fresh (≤2 days old):
CACHE_FILE="$HOME/.duckdb/docs/CACHE_FILENAME"
if [ -f "$CACHE_FILE" ]; then
MTIME=$(stat -f %m "$CACHE_FILE" 2>/dev/null || stat -c %Y "$CACHE_FILE")
CACHE_AGE_DAYS=$(( ( $(date +%s) - MTIME ) / 86400 ))
else
CACHE_AGE_DAYS=999
fi
echo "Cache age: $CACHE_AGE_DAYS days"
If CACHE_AGE_DAYS ≤ 2 → skip to Step 5.
Otherwise (stale or missing) → fetch the index:
duckdb -c "
LOAD httpfs;
LOAD fts;
ATTACH 'REMOTE_URL' AS remote (READ_ONLY);
ATTACH '$HOME/.duckdb/docs/CACHE_FILENAME.tmp' AS tmp;
COPY FROM DATABASE remote TO tmp;
" && mv "$HOME/.duckdb/docs/CACHE_FILENAME.tmp" "$HOME/.duckdb/docs/CACHE_FILENAME"
Replace REMOTE_URL and CACHE_FILENAME per Step 3. If the fetch fails (network error), report the error and stop.
duckdb "$HOME/.duckdb/docs/CACHE_FILENAME" -readonly -json -c "
LOAD fts;
SELECT
chunk_id, page_title, section, breadcrumb, url, version, text,
fts_main_docs_chunks.match_bm25(chunk_id, 'SEARCH_QUERY') AS score
FROM docs_chunks
WHERE score IS NOT NULL
AND version = 'VERSION'
ORDER BY score DESC
LIMIT 8;
"
Replace CACHE_FILENAME, SEARCH_QUERY, and VERSION per Step 3. Remove the AND version = 'VERSION' line if searching across all versions.
If the user's question could benefit from both DuckDB docs and blog results, run two queries (one with version = 'stable', one with version = 'blog') or omit the version filter entirely.
httpfs or fts not found): run duckdb :memory: -c "INSTALL httpfs; INSTALL fts;" and retry.https://duckdb.org/data/docs-search.duckdb and the DuckLake index at https://ducklake.select/data/docs-search.duckdb.For each result chunk returned (ordered by score descending), format as:
### {section} — {page_title}
{url}
{text}
---
After presenting all chunks, synthesize a concise answer to the user's original question ($@) based on the retrieved documentation. If the chunks directly answer the question, lead with the answer before showing the sources.