attach-db
Attach a DuckDB database file for use with /duckdb-skills:query. Explores the schema (tables, columns, row counts) and writes a SQL state file so subsequent…
Run SQL queries against the attached DuckDB database or ad-hoc against files. Accepts raw SQL or natural language questions. Uses DuckDB Friendly SQL idioms.
$ npx -y skills add duckdb/duckdb-skills --skill query --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/queryContext preview
The summary Claude sees to decide when to auto-load this skill.
Run SQL queries against the attached DuckDB database or ad-hoc against files. Accepts raw SQL or natural language questions. Uses DuckDB Friendly SQL idioms.
name: query description: > Run SQL queries against the attached DuckDB database or ad-hoc against files. Accepts raw SQL or natural language questions. Uses DuckDB Friendly SQL idioms. argument-hint: <SQL or question> [--file path] allowed-tools: Bash
You are helping the user query data using DuckDB.
Input: `$@`
Follow these steps in order.
Look for an existing state file in either location:
STATE_DIR="" test -f .duckdb-skills/state.sql && STATE_DIR=".duckdb-skills" PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")" PROJECT_ID="$(echo "$PROJECT_ROOT" | tr '/' '-')" test -f "$HOME/.duckdb-skills/$PROJECT_ID/state.sql" && STATE_DIR="$HOME/.duckdb-skills/$PROJECT_ID"
If found, verify the databases it references are still accessible:
duckdb -init "$STATE_DIR/state.sql" -c "SHOW DATABASES;"
Now determine the mode:
If no state file exists and no file is referenced, fall back to ad-hoc mode against `:memory:` — the user must reference files directly in their SQL.
If the state file exists but any ATTACH in it fails, warn the user and fall back to ad-hoc mode.
command -v duckdb
If not found, delegate to `/duckdb-skills:install-duckdb` and then continue.
If the input is natural language (not valid SQL), generate SQL using the Friendly SQL reference below.
In **session mode**, first retrieve the schema to inform query generation:
duckdb -init "$STATE_DIR/state.sql" -csv -c " SELECT table_name FROM duckdb_tables() ORDER BY table_name; "
Then for relevant tables:
duckdb -init "$STATE_DIR/state.sql" -csv -c "DESCRIBE <table_name>;"
Use the schema context and the Friendly SQL reference to generate the most appropriate query.
Before executing, estimate whether the query could produce a very large result that would consume excessive tokens when returned to this conversation.
**Session mode** — check row counts for the tables involved:
duckdb -init "$STATE_DIR/state.sql" -csv -c "
SELECT table_name, estimated_size, column_count
FROM duckdb_tables()
WHERE table_name IN ('<table1>', '<table2>');
"**Ad-hoc mode** — probe the source:
duckdb :memory: -csv -c " SET allowed_paths=['FILE_PATH']; SET enable_external_access=false; SET allow_persistent_secrets=false; SET lock_configuration=true; SELECT count() AS row_count FROM 'FILE_PATH'; "
**Evaluate**:
*"This query would return a very large result set. Displaying it here would consume a lot of tokens and increase cost. I'd recommend adding `LIMIT 1000` or an aggregation to keep the output manageable."* Ask for confirmation before running as-is.
*"This table is over 10 GB — the query may take a while to complete."* Proceed if the user confirms.
Skip this step for queries that are intrinsically bounded (e.g. `DESCRIBE`, `SUMMARIZE`, aggregations, `count()`).
**Ad-hoc mode** (sandboxed — only the referenced file is accessible):
duckdb :memory: -csv <<'SQL' SET allowed_paths=['FILE_PATH']; SET enable_external_access=false; SET allow_persistent_secrets=false; SET lock_configuration=true; <QUERY>; SQL
Replace `FILE_PATH` with the actual file path extracted from the query or `--file` argument. If multiple files are referenced, include all paths in the `allowed_paths` list.
**Session mode** (user-trusted database):
duckdb -init "$STATE_DIR/state.sql" -csv -c "<QUERY>"
For multi-line queries, use a heredoc with `-init`:
duckdb -init "$STATE_DIR/state.sql" -csv <<'SQL' <QUERY>; SQL
Always use heredocs (`<<'SQL'`) for multi-line queries to avoid shell quoting issues.
Show the query output to the user. If the result has more than 100 rows, note the truncation and suggest adding `LIMIT` to the query.
For natural language questions, also provide a brief interpretation of the results.
---
When generating SQL, prefer these idiomatic DuckDB constructs:
A Claude Code plugin that adds DuckDB-powered skills for data exploration and session memory.
Repo: duckdb/duckdb-skills
Attach a DuckDB database file for use with /duckdb-skills:query. Explores the schema (tables, columns, row counts) and writes a SQL state file so subsequent…
Convert any data file to another format: CSV, Parquet, JSON, Excel, GeoJSON, and more. Use when the user says "convert to parquet", "save as xlsx", "export as…
Search DuckDB and DuckLake documentation and blog posts. Returns relevant doc chunks for a question or keyword using full-text search against a locally cached…
Install or update DuckDB extensions. Each argument is either a plain extension name (installs from core) or name@repo (e.g. magic@community). Pass --update to…
Read any data file (CSV, JSON, Parquet, Avro, Excel, spatial, SQLite) or remote URL (S3, HTTPS). Use when user references a data file, asks "what's in this…
Search past Claude Code session logs to recall prior decisions, patterns, or unresolved work. Use when user says "do you remember", "what did we do",…