Skip to main content

A multi-source DuckDB query + transformation-pipeline MCP server.

Project description

Spelunk

A multi-source DuckDB query + transformation-pipeline MCP server. Point it at files (CSV/Parquet/JSON/Excel) and databases (SQLite/PostgreSQL/MySQL), and an agent like Claude Code can query across all of them — and build step-by-step pipelines — through one DuckDB engine.

Architecture in one line

A single DuckDB session is both the query engine and the workspace: every source is ATTACHed (databases) or scanned (files) into one connection, so one query can join a Parquet file to a Postgres table to a result you built two steps ago — all in DuckDB SQL.

Path Role
spelunk/core/duck.py DuckSession — the one DuckDB connection: query / profile / export / catalog / drop / lineage / replay + introspection.
spelunk/core/sources.py Source registry — maps a spec to a DuckDB attach/scan. DuckDB-only: a source it can't attach (e.g. SQL Server) is rejected.
spelunk/core/guard.py sqlglot AST safety: read-only enforcement (assert_read_only).
spelunk/mcp/server.py Thin FastMCP wrapper over DuckSession.
tests Acceptance tests.

Tools

query(sql, name, flow?)     # run a read-only SELECT over sources + results; store the full
                            #   result as table `name` for immediate reuse. The ONE tool for
                            #   looking and building — every result is named and chainable.
profile(sql, flow?)         # per-column stats (null_rate, min/max/mean/std, percentiles, top/freq)
export(target, fmt, path)   # write a saved result name OR a full SELECT to csv/json/parquet
catalog(flow?)              # list flows, or the results in one flow
drop(name?, flow?)          # drop one result, or a whole flow
lineage(name?, flow?)       # provenance DAG: the SQL + deps that built a result (or a whole flow)
replay(flow?, into?)        # rebuild a flow from its recorded SQL, in dependency order

Discovery resources: db://tables (queryable source objects) and db://{table} (columns, PK, sample, row count). A flow is an isolated result namespace (a DuckDB schema); give each concurrent line of analysis its own flow.

Install & run

The fastest path is uvx — no clone, no venv. It fetches Spelunk into an ephemeral environment and runs the spelunk command. The package is published as spelunk-mcp (the command is spelunk), so pass it via --from:

uvx --from spelunk-mcp spelunk \
  --source sales=./data/sales.parquet \
  --source sqlite:///path/to/app.db \
  --session-dir .spelunk_session          # omit for an ephemeral (non-durable) workspace

Want the latest commit instead of the released version? Point uvx straight at the repo:

uvx --from git+https://github.com/shaunak2512/spelunk spelunk --source sales=./data/sales.parquet

Either way, wire it into Claude Code with a .mcp.json:

{
  "mcpServers": {
    "spelunk": {
      "command": "uvx",
      "args": ["--from", "spelunk-mcp", "spelunk", "--source", "sales=./data/sales.parquet"]
    }
  }
}

Prefer a local checkout? python -m spelunk.mcp.server --source ... is equivalent to the spelunk command.

Sources auto-detect by extension/scheme; prefix with name= to set the catalog/view name. Optional resource guards: --memory-limit 4GB, --temp-dir <dir>, --max-temp-size 50GB. DuckDB is out-of-core, so a source larger than RAM is the normal case — scans read on demand and buffering operators spill to the temp directory.

Dev

uv sync --extra dev
uv run --extra dev python -m pytest -q
uv run --extra dev ruff check spelunk/

Project details


Download files

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

Source Distribution

spelunk_mcp-0.2.0.tar.gz (146.4 kB view details)

Uploaded Source

Built Distribution

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

spelunk_mcp-0.2.0-py3-none-any.whl (46.0 kB view details)

Uploaded Python 3

File details

Details for the file spelunk_mcp-0.2.0.tar.gz.

File metadata

  • Download URL: spelunk_mcp-0.2.0.tar.gz
  • Upload date:
  • Size: 146.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for spelunk_mcp-0.2.0.tar.gz
Algorithm Hash digest
SHA256 ee2bf46f5a01d9ef281d04968bc5fb4706e57da6c466f2c4364ffda5fbdbefac
MD5 3ed58401ab02eb983fd967959b54b6d3
BLAKE2b-256 18c337756b409735feceb8aa52ff0f4e2883b725d6dd8af8fd44f806708d2b17

See more details on using hashes here.

Provenance

The following attestation bundles were made for spelunk_mcp-0.2.0.tar.gz:

Publisher: publish.yml on shaunak2512/spelunk

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

File details

Details for the file spelunk_mcp-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: spelunk_mcp-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 46.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for spelunk_mcp-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1c2e48e75482b732acb3bd4f75d2aed0e3642bb4dc4e62ff7e90ee20d6a966ac
MD5 9664008ea2071509bc4dcf39c11e48df
BLAKE2b-256 8ffeefde244978000da332930abec96613b288744eafd85d6823f9f784c4870b

See more details on using hashes here.

Provenance

The following attestation bundles were made for spelunk_mcp-0.2.0-py3-none-any.whl:

Publisher: publish.yml on shaunak2512/spelunk

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page