query_sql¶
Scope: read · Signature: query_sql(workspace_id: str, sql: str, limit: int | None = None, knowledgebase_id: str | None = None) -> Any
Use for rows and aggregates: ONE read-only SELECT over the lakehouse.
Returns {columns, rows, n_returned, has_more}. Table names EXACTLY as describe_catalog reports (double-quoted). Rows are capped — by count, and to what fits in your context; has_more=true means truncated — filter/aggregate or select fewer columns, don't page. Join per-row facts to inputs on the declared key column(s) they carry (catalog role key), never by position; forecast joins on (series, ts). No DDL/DML (HTTP 400). knowledgebase_id reads that knowledge base's source tables instead (describe_catalog(knowledgebase_id=…) names them): investigate a database, workbook or demo before any recipe exists. DuckDB dialect: write AS before every column alias (a keyword such as days, weeks or nulls fails bare); binning, dates and quantiles are in get_playbook("overview"), DuckDB idioms.
Typed output: schema query_result — generated from the backend pydantic model by scripts/export_mcp_schemas.py (the same SSOT as the React client types).
Powered by: the Workspace DuckDB lakehouse (backend/app/services/workspace_query.py).