Skip to main content
Glama
arthurxavier106

duckdb-analytics-mcp

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
WAREHOUSE_DB_PATHNoPath to the DuckDB database file. If not set, an in-memory database is used.
WAREHOUSE_DATA_DIRNoDirectory containing Parquet files to build the warehouse from. If not set, the bundled sample dataset is used.
WAREHOUSE_MAX_ROWSNoMaximum number of rows returned by a query.200
WAREHOUSE_TIMEOUT_SNoQuery timeout in seconds.15
WAREHOUSE_CATALOG_PATHNoPath to the catalog YAML file (datasets.yaml).
WAREHOUSE_MAX_CELL_CHARSNoMaximum characters per cell in results.60

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
list_datasetsA

List every table in the warehouse with its row count, grain, and caveats.

Start here. The output is deliberately small -- one line per table plus the business rules that change query correctness -- so it is cheap to call before anything else.

Returns: str: Markdown containing: - a table of (table, rows, grain, description) - a "Before you write SQL" section listing every caveat in the warehouse, each prefixed with its table name

On failure: "Error: <message>".

Examples: - Use when: "What data do I have access to?" - Use when: starting any analysis, before describe_table. - Don't use when: you already know the table and need its columns (use describe_table instead).

describe_tableA

Describe one table: columns, types, null rates, distinct counts, examples.

Call this before writing a query against an unfamiliar table. It answers "what can I filter on, and what will be NULL" in a single round trip, which a raw information_schema dump does not.

Args: table (str): Table name, case-insensitive (e.g. 'orders').

Returns: str: Markdown containing: - header with row count and grain - a table of (column, type, null%, distinct, range, examples) - column definitions from the semantic layer - declared join keys - caveats that affect correctness

On failure: "Error: No table named 'x'. Available tables: ..."

Examples: - Use when: "What columns does orders have?" - Use when: a query failed with an unknown-column error. - Don't use when: you need the distribution of one column (use profile_column instead).

profile_columnA

Profile one column: distribution, outliers, coverage gaps, dirty values.

The profile adapts to the column type:

  • numeric: min/p25/median/mean/p75/p95/max/stddev, plus a Tukey outlier count and the largest values when the distribution is skewed

  • date/timestamp: range, distinct days, and the largest gaps in coverage

  • text/boolean: top values with shares, plus a warning when values differ only by case or formatting

Args: table (str): Table name, case-insensitive. column (str): Column name, case-insensitive.

Returns: str: Markdown profile, ending with the column's definition and any caveats that mention it.

On failure: "Error: Table 'orders' has no column 'x'. Columns: ..."

Examples: - Use when: "Is unit_price skewed? Should I use mean or median?" - Use when: "Are there missing days in order_date?" - Use when: a GROUP BY returned more groups than expected. - Don't use when: you want the whole schema (use describe_table).

explainA

Show the query plan and estimated row count WITHOUT executing the query.

Use this when a query might be expensive, or after one has timed out. The estimate comes from DuckDB's optimizer, so it is an estimate, not a guarantee -- but it is enough to catch an accidental cross join before it runs for fifteen seconds.

Args: sql (str): The SELECT to plan. It is not executed.

Returns: str: Markdown containing the estimated cardinality, a verdict on whether the query is worth running, and the physical plan.

On failure: "Error: <guard message>" for non-SELECT input.

Examples: - Use when: a previous query hit the timeout. - Use when: joining two large tables for the first time. - Don't use when: you just want the answer (call query directly).

queryA

Run one read-only SELECT against the warehouse and return the rows.

Enforcement, in order: the statement is parsed and rejected unless it is a single SELECT; a LIMIT is injected if absent and lowered if it exceeds the server cap; execution is cancelled if it exceeds the time limit. When the result is truncated, the true total is counted and reported -- the output never implies it is complete when it is not.

Prefer aggregating in SQL over selecting raw rows. SELECT count(*), avg(x) costs a handful of tokens; SELECT * costs hundreds and usually answers less.

Args: sql (str): One SELECT statement in DuckDB SQL. max_rows (Optional[int]): Per-call row cap, clamped to the server cap (default 200). response_format (ResponseFormat): 'markdown' (default) or 'json'.

Returns: str: For 'markdown', an unpadded markdown table followed by a row-count footer that discloses truncation. For 'json', an object: { "columns": [str], "rows": [[Any]], "row_count": int, # rows returned "total_rows": int|null, # true total when truncated "truncated": bool, "elapsed_ms": float }

On failure: "Error: <message>" naming the recovery path.

Examples: - Use when: "What was revenue by month in 2025?" -> aggregate in SQL. - Use when: "Show me 10 example rows from orders." - Don't use when: you do not yet know the column names (call describe_table first -- it is cheaper than a failed query).

Error Handling: - Non-SELECT statements, multiple statements, and filesystem functions are rejected before execution. - Queries exceeding the time limit are cancelled, not left running. - Unknown columns return DuckDB's message, which names the candidates.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/arthurxavier106/duckdb-analytics-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server