bigquery-analytics-mcp-server
v0.1.2
Published
MCP server for Google BigQuery, built for the Analytics Model platform connector contract
Maintainers
Readme
bigquery-analytics-mcp-server
MCP server for Google BigQuery, built for the Analytics Model connector flow. It runs over stdio, authenticates with the user's Google OAuth tokens, and is read-only.
Tools
| Tool | What it does |
|---|---|
| list_projects | Projects the signed-in user can access in BigQuery |
| list_datasets | Datasets in a project |
| list_tables | All tables and views across every dataset in one call (optionally a subset of datasets). include_details adds row count, size, description and column count |
| get_table_schema | Columns (nested fields, descriptions), partitioning, clustering, row count, size, view SQL |
| preview_table | Rows without a full scan. Native tables use the free tabledata.list API; views and external tables fall back to a limited query |
| dry_run_query | Validates SQL and estimates bytes processed and cost |
| run_query | Runs read-only SQL with a dry run first, a bytes-billed cap and a row cap |
| get_job_status / cancel_job | Inspect or cancel a job |
Configuration (environment variables)
| Variable | Purpose |
|---|---|
| GOOGLE_ACCESS_TOKEN | OAuth access token (bigquery.readonly scope; add cloud-platform.read-only for list_projects) |
| GOOGLE_REFRESH_TOKEN | Optional. With the two below, expired access tokens refresh automatically |
| GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET | OAuth client used to refresh tokens |
| BIGQUERY_PROJECT_ID | Default project, used when a tool call omits project_id |
| BIGQUERY_LOCATION | Optional default job location (US, EU, asia-south1...). Normally auto-detected |
| BIGQUERY_MAX_BYTES_BILLED | Hard per-query cap, default 10 GiB. Queries estimated above it are refused |
| BIGQUERY_DEFAULT_ROW_LIMIT / BIGQUERY_MAX_ROW_LIMIT | Default 1000 / ceiling 10000 rows returned per query |
| BQ_ENVELOPE_MODE | double (default, platform contract for list_tables) or single (standard MCP result) |
Safety
- SQL is checked to be a single
SELECT/WITHstatement (comments, strings and quoted identifiers are ignored when scanning for DML/DDL keywords). - Every query is dry-run, and refused unless BigQuery itself classifies it as
SELECT. maximumBytesBilledis set on the job, so BigQuery enforces the cost cap even if the estimate is off.- The recommended OAuth scope is read-only, so writes are impossible regardless.
Run
npm install
npm run build
GOOGLE_ACCESS_TOKEN=... BIGQUERY_PROJECT_ID=my-project node dist/index.jsExample MCP client config:
{
"command": "npx",
"args": ["-y", "bigquery-analytics-mcp-server"],
"env": {
"GOOGLE_ACCESS_TOKEN": "...",
"GOOGLE_REFRESH_TOKEN": "...",
"GOOGLE_CLIENT_ID": "...",
"GOOGLE_CLIENT_SECRET": "...",
"BIGQUERY_PROJECT_ID": "my-project"
}
}Test
npm testUnit tests cover the SQL guard, JSON serialisation of BigQuery types and the response envelopes. They do not call BigQuery.
