duckdb-skills

repository·main·Indexed 19 days ago

https://github.com/duckdb/duckdb-skills

A Claude Code plugin providing specialized skills for data exploration, SQL querying, and session memory using DuckDB. It includes tools to attach databases, run SQL queries, read various data formats (CSV, JSON, Parquet, etc.), convert files, search DuckDB and DuckLake documentation, and manage DuckDB extensions.

Tokens
14.5K
Snippets
56
Records
71
Agent score
67%

What's inside duckdb-skills

  1. How to handle the POINT_2D requirement for spheroid functions

    main

    Spheroid-based functions (e.g., ST_Distance_Spheroid, ST_Area_Spheroid, ST_Length_Spheroid, ST_DWithin_Spheroid) require inputs of type POINT_2D. They do not accept the generic GEOMETRY type returned by ST_Read() or Overture Maps.

    To use these functions, you must extract the coordinates and rebuild the point as a POINT_2D type:

    ST_Point(ST_X(geometry), ST_Y(geometry))::POINT_2D
  2. Resolve the DuckDB session state directory

    main

    The attach-db skill uses a state.sql file to persist session state (like ATTACH statements). You can choose between two storage locations for this file:

    1. Project Directory: Stored in .duckdb-skills/state.sql. This is colocated with your project and is easy to find, but you may want to add .duckdb-skills/ to your .gitignore.
    2. Home Directory: Stored in ~/.duckdb-skills/<project-id>/state.sql. The <project-id> is a slugified version of your project's root path. This keeps your project directory clean.

    All skills in duckdb-skills share this single state.sql file per project to ensure a consistent environment.

  3. Select the correct DuckDB or DuckLake documentation index

    main

    Depending on the query, you should choose between two available indexes. Both share a common schema containing chunk_id, page_title, section, breadcrumb, url, version, and text.

    IndexRemote URLLocal cache filenameVersionsUse when
    DuckDB docs + bloghttps://duckdb.org/data/docs-search.duckdbduckdb-docs.duckdblts, current, blogDefault — any DuckDB question
    DuckLake docshttps://ducklake.select/data/docs-search.duckdbducklake-docs.duckdbstable, previewQuery mentions DuckLake, catalogs, or DuckLake-specific features

    Version Filtering Strategy:

    • version = 'lts': Default for general DuckDB questions.
    • version = 'current': For nightly or latest features.
    • version = 'blog': For background, motivation, or blog posts.
    • version = 'stable': For DuckLake queries.
    • Omit version filter: To search across all available versions.
  4. Understand DuckDB-skills session state

    main

    All skills share a single state.sql file per project. This is a plain SQL file containing ATTACH, USE, and LOAD statements, secrets, and macros. When state is first required, you can choose to store it in one of two locations:

    1. Project directory: .duckdb-skills/state.sql (colocated with the project, can be gitignored).
    2. Home directory: ~/.duckdb-skills/<project>/state.sql (keeps the repository clean).

    The file is append-only and idempotent. Skills restore the session using duckdb -init state.sql.

  5. Append database attachment to the state file

    main

    To ensure subsequent sessions automatically use the attached database, the attach-db skill appends an ATTACH statement to the state.sql file. It uses an alias derived from the filename (e.g., my_data.duckdb becomes my_data).

    Important: Never overwrite the state.sql file, as it may contain macros, LOAD statements, or secrets from other skills. Always check for existing ATTACH statements before appending.

    Example State SQL format:

    ATTACH IF NOT EXISTS '/absolute/path/to/database.duckdb' AS my_data;
    USE my_data;
  6. Best practices for spatial queries in DuckDB

    main

    When working with spatial data in DuckDB, follow these principles to ensure accuracy and performance:

    1. BBox Filtering First: When querying large remote datasets like Overture Maps, always filter on bbox.xmin, bbox.xmax, ymin, and ymax before applying spatial functions. This leverages Parquet predicate pushdown and prevents downloading the entire dataset.
    2. Use Spheroid Functions for Real-World Distances: Use ST_Distance_Spheroid (which returns meters on the WGS84 ellipsoid) instead of ST_Distance. Plain ST_Distance uses planar coordinates and is inaccurate for latitude/longitude.
    3. Handle Spheroid Input Types: Spheroid functions require POINT_2D inputs, not generic GEOMETRY. Since Overture geometry columns are typed GEOMETRY('OGC:CRS84'), you must extract the coordinates first:
      ST_Point(ST_X(geometry), ST_Y(geometry))::POINT_2D
    4. Convert CSV Lat/Lng: When creating points from CSV columns, use ST_Point(longitude, latitude) (longitude must come first).
  7. Attach a DuckDB database for interactive querying

    main

    The attach-db skill allows you to attach an existing DuckDB database file to your session. It resolves the database path, validates the file, explores the schema (tables, columns, and row counts), and writes a SQL state file. This state file allows subsequent queries via /duckdb-skills:query to automatically restore the session using duckdb -init "$STATE_DIR/state.sql".

    Usage Argument: <path-to-database.duckdb>

    # Example of how the state file is used to restore a session
    duckdb -init "$STATE_DIR/state.sql" -c "<QUERY>"
  8. Install or update DuckDB extensions

    main

    Use the install-duckdb skill to manage DuckDB extensions. You can install extensions from the core repository or from specific community repositories using the name@repo syntax. Use the --update flag to update existing extensions instead of installing new ones.

    Argument Syntax:

    • name: Installs the extension from the core repository (INSTALL name;).
    • name@repo: Installs the extension from a specific repository (INSTALL name FROM repo;).
    • --update: When present, switches the operation from installation to updating extensions.
    install-duckdb [--update] [ext1 ext2@repo ext3 ...]
  9. Configure DuckDB for spatial analysis

    main

    To perform spatial operations, you must load the spatial extension and configure the coordinate system. It is critical to set geometry_always_xy = true to ensure all spatial functions interpret coordinates as (longitude, latitude), which is the standard for GeoJSON, Overture Maps, and most other spatial data sources. Without this setting, spheroid functions may assume latitude is first, leading to incorrect results.

    Always start your session with:

    LOAD spatial;
    SET geometry_always_xy = true;
  10. Search past Claude Code session logs with read-memories

    main

    The read-memories skill allows you to search through past Claude Code session logs to recall prior decisions, patterns, or unresolved work. This is useful when you need context from previous conversations or when a user asks about past actions (e.g., "what did we do?").

    To use this skill, provide a <keyword> to search for. You can optionally pass the --here flag to scope the search to the current project only.

    Search Scopes:

    • All projects: $HOME/.claude/projects/*/*.jsonl
    • Current project only (--here): $HOME/.claude/projects/$(echo "$PWD" | sed 's|[/_]|-|g')/*.jsonl
    duckdb :memory: -c "
    SELECT
      regexp_extract(filename, 'projects/([^/]+)/', 1) AS project,
      strftime(timestamp::TIMESTAMPTZ, '%Y-%m-%d %H:%M') AS ts,
      message.role AS role,
      left(message.content::VARCHAR, 500) AS content
    FROM read_ndjson('<SEARCH_PATH>', auto_detect=true, ignore_errors=true, filename=true)
    WHERE message::VARCHAR ILIKE '%<KEYWORD>%'
      AND message.role IS NOT NULL
    ORDER BY timestamp
    LIMIT 40;
    "
  11. List contents of an S3 bucket or directory

    main

    If the URL points to a directory or bucket (e.g., it ends with / or has no file extension), you can list its contents, sizes, and modification dates. To avoid downloading the actual file content, only select the filename, size, and last_modified columns using read_blob with a glob pattern.

    Warning: Never select the content column when listing directories, as this will trigger a full download of the files.

    duckdb -c "
    LOAD httpfs;
    <SECRET_SETUP>
    SELECT filename, (size / 1024 / 1024)::DECIMAL(10,1) AS size_mb, last_modified
    FROM read_blob('<URL>/*')
    ORDER BY filename
    LIMIT 50;
    "