BonnardBonnard

Warehouse Adapters

Bundled adapters for Postgres, BigQuery, Snowflake, Databricks, and DuckDB that turn a native driver result into typed chart data, and how to bring your own.

An adapter is a small function that wraps your warehouse driver and returns a runSql callback for addCharts. It maps the driver's column types to chart field kinds (dimension, measure, time) so the chart picks sensible axes and formatting automatically.

Each adapter lives at its own import subpath. The underlying driver is an optional peer dependency. You only install the one you use, and importing a subpath pulls in no runtime dependency beyond your driver.

Read-only by default

Every bundled adapter rejects non-read SQL before it reaches your warehouse. Each one runs assertReadOnlySql on the incoming query, which requires a single statement starting with SELECT or WITH and rejects anything containing a write or DDL keyword (insert, update, delete, merge, drop, alter, create, truncate, grant, revoke, call, copy, execute, attach, and others). Postgres adds a BEGIN TRANSACTION READ ONLY around the query, rolled back afterwards, so the engine rejects writes too.

Pass { readOnly: false } to turn the check off:

addCharts(server, { runSql: postgresRunSql(pool, { readOnly: false }) });

assertReadOnlySql is a cheap string check on LLM-authored SQL, not a sandbox. A read-only, least-privilege database role is the real boundary, and it is what you should rely on. See Security.

Postgres

import { Pool } from "pg";
import { postgresRunSql } from "@bonnard/mcp-charts/postgres";

const pool = new Pool({ connectionString: process.env.DATABASE_URL });
addCharts(server, { runSql: postgresRunSql(pool) });

On top of the shared SQL check, Postgres wraps each query in a BEGIN TRANSACTION READ ONLY and rolls it back, so the server rejects writes as well. Both are disabled by { readOnly: false }.

BigQuery

import { BigQuery } from "@google-cloud/bigquery";
import { bigQueryRunSql } from "@bonnard/mcp-charts/bigquery";

const bq = new BigQuery();
addCharts(server, {
  runSql: bigQueryRunSql(bq, {
    location: "europe-west2",
    maximumBytesBilled: "200000000", // cost guard
    defaultDataset: "analytics", // unqualified table names resolve here
  }),
});

DuckDB

import { duckDbRunSql } from "@bonnard/mcp-charts/duckdb";

addCharts(server, { runSql: duckDbRunSql(connection) });

Snowflake

import { snowflakeRunSql } from "@bonnard/mcp-charts/snowflake";

addCharts(server, { runSql: snowflakeRunSql(connection) });

Databricks

import { databricksRunSql } from "@bonnard/mcp-charts/databricks";

addCharts(server, { runSql: databricksRunSql(session) });

Optional peer dependencies

Install only the driver(s) you use:

AdapterSubpathPeer dependency
Postgres@bonnard/mcp-charts/postgrespg
BigQuery@bonnard/mcp-charts/bigquery@google-cloud/bigquery
DuckDB@bonnard/mcp-charts/duckdb@duckdb/node-api
Snowflake@bonnard/mcp-charts/snowflakesnowflake-sdk
Databricks@bonnard/mcp-charts/databricks@databricks/sql

Connect adapters with a read-only, least-privilege role. See Security.

On this page