View Categories

How to Connect BigQuery to Claude / Cursor via MCP (BigQuery MCP Server Setup)

30 min read

MCP SERVER BIGQUERY

Query BigQuery with Claude or Cursor via MCP.

Connect Google BigQuery — your GCP project, your datasets, your service account — to Claude or Cursor with one MCP key. Schema Intelligence handles GoogleSQL idioms (STRUCT, ARRAY, _PARTITIONTIME, backtick-qualified `project.dataset.table`) so the AI writes valid BigQuery SQL on its first try.

No firewall holes One key, every connector Live data, no cache lag Bring your own AI tool

Query Streams is a secure, real-time data integration platform that brings every database and SaaS API in your account into Claude, Cursor, ChatGPT, and Grok — through a single MCP key with no firewall changes. This guide walks through wiring up the BigQuery MCP connector specifically, so your AI tool can answer plain-English questions about events, users, sessions, attributions, conversion funnels, and any other BigQuery data — partitioned scans, STRUCT / ARRAY traversal, GoogleSQL window functions, ad-hoc reporting — without you copy-pasting CSV exports out of the BigQuery Console, the bq CLI, or Looker Studio. Learn more at QueryStreams.com and sign up for free to start asking your AI tool real BigQuery questions.

What Query Streams MCP gives you for BigQuery

Other “BigQuery MCP” servers on the open-source landscape connect the AI tool directly to a BigQuery service-account key file. That works, but it pushes a long-lived JSON credential into your AI client’s config, scopes the AI tool to only that one GCP project, and gives you no audit trail of what the AI actually asked. The Query Streams MCP server for BigQuery solves a wider problem: one key, every connector, full audit trail, and the AI tool never holds your service-account credentials.

Zero inbound firewall holes

The Network Agent opens a single outbound encrypted cloud link to Query Streams. Your AI client connects to the cloud, never to your GCP project. No long-lived service-account JSON in your AI client config, no IP allowlist on BigQuery, no VPN, no extra IAM bindings on the BigQuery API.

One key, every connector

The same MCP key reaches every database and SaaS API your account has connected. Add a Stripe or PostgreSQL connector tomorrow and the AI tool sees it next to your BigQuery datasets without re-keying.

Schema Intelligence baked in

The AI sees AI-curated descriptions, semantic types, enum value lists, STRUCT / ARRAY annotations, and discovered foreign keys for every BigQuery column — not just bare INFORMATION_SCHEMA output. It writes accurate GoogleSQL on the first try, even on legacy BigQuery datasets with cryptic column names and deeply nested record fields.

Read-only enforced at the agent

Even a hallucinating LLM can’t issue DELETE, UPDATE, or TRUNCATE through Query Streams MCP. The Network Agent rejects anything that isn’t SELECT, WITH, or EXPLAIN before BigQuery ever sees the SQL — even if your service account had write permissions.

Per-key rate limits

Default 60 requests per minute and 10 execute calls per minute, configurable per key. A runaway AI tool-call loop hits a token bucket, not your BigQuery slot reservation or your monthly on-demand bytes-scanned bill.

How it works without opening firewall ports

The Query Streams Network Agent installs once on any machine that can reach the BigQuery API (laptop, on-prem box, or a small GCE VM in your GCP project) and dials one outbound TLS link to the cloud — nothing inbound is ever exposed, and the AI tool never sees your service-account key file or GCP project id. how the outbound-only connection works →

AI Client

Cursor, Claude,
ChatGPT, Grok

QS MCP Server

Streamable HTTP
X-MCP-Key auth

Network Agent

On your network
Cloud link out

BigQuery (GCP project / dataset)

Service account
held by the agent

No inbound port required — the agent dials out, never the other way around

The MCP key you give Cursor or Claude is scoped (read / analyze / execute), revocable at any time, and rate-limited per-key. The AI tool calls these MCP tools to do its work:

querystreams-mcp · tool catalog
qs_list_organizationsread
Returns the org bound to the calling key.
qs_list_agentsread
Lists Network Agents and online state.
qs_list_connectorsread
Lists data connectors (one entry per database server or API).
qs_get_connector_schemaread
Returns the BigQuery datasets, tables, and columns (including STRUCT / ARRAY fields) the AI can query, with Schema Intelligence enrichment when available.
qs_profile_tableanalyze
Sample values, distributions, enum detection, semantic types — on demand.
qs_list_saved_queriesread
Pre-built parameterized SQL templates the team trusts. The AI runs them without ever seeing the SQL.
qs_run_saved_queryexecute
Executes a saved query by pattern_key with optional parameter overrides.
qs_run_queryexecute
Executes a SELECT against a connector. Read-only validator runs at the agent, before BigQuery sees the SQL.

Why Schema Intelligence makes Query Streams MCP different

Most “MCP for BigQuery” servers in the open-source landscape hand your AI tool the same INFORMATION_SCHEMA BigQuery hands a stranger. Column names. GoogleSQL types. Maybe a clustering key. The LLM is left to guess what event_name = 'click_4' means, what up_attr_4 stores, or whether events.event_params is a single STRUCT or a repeated ARRAY<STRUCT> that needs UNNEST() traversal. That’s why the first SQL most LLMs write against a bare BigQuery schema either errors out (forgetting backticks for hyphenated project ids) or scans the entire 5 TB events table because no _PARTITIONTIME filter was applied — not because the LLM is bad, but because it doesn’t have the data it needs to be right.

Query Streams MCP returns that same schema enriched with what we call Schema Intelligence (SI) — AI-curated metadata that’s generated by running profiling queries against your actual BigQuery data before the AI client ever asks. When SI is enabled on a connector and dataset, every schema tool the AI calls (qs_get_connector_schema, qs_get_table_schema, qs_profile_table, qs_get_relationships) returns the bare schema plus six layers of curated knowledge. The LLM stops guessing — and stops scanning terabytes by accident.

To make this concrete, here is what the AI client gets back from a single qs_get_table_schema call against a typical BigQuery web-analytics warehouse (events, users, sessions, attributions, experiments, conversion_events) — first without Schema Intelligence, then with it.

Without Schema Intelligence data_source: captured_schema
// what the LLM sees == TABLE: `analytics.events` == – event_name STRING NOT NULL – user_id STRING – session_id STRING – event_timestamp TIMESTAMP NOT NULL – event_params ARRAY<STRUCT> – user_properties ARRAY<STRUCT> – revenue FLOAT64 Partitioned by: _PARTITIONTIME (DAY) == TABLE: `analytics.users` == – user_pseudo_id STRING – acquisition_source STRING – first_seen TIMESTAMP == TABLE: `analytics.sessions` == – session_id STRING – user_id STRING – duration_sec INT64 == TABLE: `analytics.attributions` == – user_id STRING – channel STRING – touch_ts TIMESTAMP Foreign Keys: (none declared — BQ has no FK constraints) si_recommendation: state: “not_run” what_youre_missing_for_this_call: – STRUCT / ARRAY field schemas (event_params keys) – Cross-table user_id overlap analysis – Per-column sample values + enum detection – Table and column descriptions – Partition / clustering hints note: “types only, no semantic context”
With Schema Intelligence data_source: schema_intelligence
// what the LLM sees == TABLE: `analytics.events` [FACT, domain:product_analytics] == “User event stream; one row per click / view / purchase. Partition by day.” – event_name STRING status_code (enum) page_view (61%) | click (22%) | add_to_cart (9%) | purchase (5%) | sign_up (3%) – user_id STRING identifier (high cardinality) FK -> users.user_pseudo_id (97% overlap, conf 0.96) – _PARTITIONTIME TIMESTAMP date (partition pseudo-col) FILTER ON THIS to bound scan cost – event_params ARRAY<STRUCT> struct_array (UNNEST required) Keys: page_url, value, item_id, source – user_properties ARRAY<STRUCT> struct_array (UNNEST required) Keys: plan_tier, signup_cohort – revenue FLOAT64 currency_usd Range: 0.00 – 4,820.00 · mean 41.30 == TABLE: `analytics.users` [DIM, domain:customers] == – user_pseudo_id STRING identifier (high cardinality) – acquisition_source STRING channel (enum) organic (41%) | cpc (28%) | direct (16%) | referral (10%) | email (5%) == TABLE: `analytics.sessions` [FACT, domain:product_analytics] == – duration_sec INT64 duration_seconds

The six layers Schema Intelligence adds

Each layer addresses a class of question the LLM would otherwise guess at — the opt-in SI profiling pass runs against your BigQuery data without changing your schema, using partition-pruning hints so the scan footprint stays bounded. what Schema Intelligence adds and how it stays current →

AI-curated descriptions

Plain-English purpose for every project, dataset, table, and column — generated once, refreshed when your schema changes. Confidence-scored; user-authored descriptions always win.

events: “User event stream; one row
per click / view / purchase.”

Table classifications

Each table tagged FACT (event streams, sessions), DIM (users, dimensions), or LOOKUP (small code maps), plus a business domain — product_analytics, marketing, finance, support, and more.

events [FACT, domain:product_analytics]
users [DIM, domain:customers]

Semantic types per column

Eighteen types — currency_usd, email, date, status_code, percentage, ranking_position, identifier, url, struct_array, partition_column, and more. The AI generates dialect-correct GoogleSQL appropriate to each type, including partition filters and UNNEST patterns.

revenue: currency_usd
_PARTITIONTIME: partition_column

Sample values from real data

Random rows surfaced to the LLM so it recognises patterns no schema can show — STRUCT key names inside ARRAY columns, encoded values, abbreviation styles, and the actual shape of your nested fields.

event_params keys: page_url, value,
item_id, source, campaign

Enum detection with distributions

Low-cardinality columns (50 or fewer distinct values, at most 5% of rows unique) mapped to their full value list with row counts. The AI never guesses casing or spelling on event types or channels.

acquisition_source: organic (41%)
| cpc (28%) | direct (16%) | …

Implicit foreign-key discovery

Cross-table data overlap analysis finds joins that BigQuery cannot enforce as DDL constraints (BQ has no foreign keys). Stored with confidence scores, returned by qs_get_relationships.

events.user_id -> users.user_pseudo_id
(97% overlap, conf 0.96)

Same prompt, different SQL

The proof is in the SQL the AI tool actually writes. Same Cursor session, same Claude model, same prompt — “What’s our most engaged user cohort by acquisition source, and what’s their conversion rate?” Without Schema Intelligence the LLM has to guess. With it, the LLM writes valid GoogleSQL on the first try and applies the partition filter automatically so the scan stays bounded.

Without Schema Intelligence
— LLM’s first attempt against bare schema: SELECT acquisition_source, COUNT(DISTINCT user_id) AS users FROM analytics-prod.web.events WHERE event_params.value > 0 GROUP BY acquisition_source SYNTAX ERROR: “analytics-prod” has hyphen, must be backtick-qualified `analytics-prod…` acquisition_source is on users, not events event_params is ARRAY<STRUCT> — needs UNNEST no _PARTITIONTIME filter — scans 5 TB ($25) no conversion-rate calculation no engagement filter — counts every visitor
With Schema Intelligence
— LLM’s first attempt with SI enabled: SELECT u.acquisition_source, COUNT(DISTINCT e.user_id) AS engaged_users, SAFE_DIVIDE( COUNTIF(e.event_name = ‘purchase’), COUNT(DISTINCT e.user_id) ) AS conversion_rate FROM `analytics-prod.web.events` e JOIN `analytics-prod.web.users` u ON e.user_id = u.user_pseudo_id WHERE e._PARTITIONTIME >= TIMESTAMP_SUB( CURRENT_TIMESTAMP(), INTERVAL 30 DAY) GROUP BY u.acquisition_source ORDER BY conversion_rate DESC 5 rows. Correct first try, scan = 6 GB. Backticks applied for hyphenated project _PARTITIONTIME bounded scan to last 30 days FK discovery routed user_id -> user_pseudo_id enum on event_name surfaced ‘purchase’ GoogleSQL TIMESTAMP_SUB / SAFE_DIVIDE used
Don’t want to run Schema Intelligence? MCP still works — schema tools return bare metadata (types, primary keys, formal foreign keys, indexes) and every degraded response carries an si_recommendation block telling the AI what it’s missing, including a one-call option to enable SI mid-conversation via qs_request_si_analysis. how Schema Intelligence runs and how long it takes →

Authenticate Query Streams MCP to your GCP project and datasets

BigQuery is itself a cloud platform — there is no “BigQuery on RDS” deployment. The cloud-hosting question for BigQuery is instead how does the Network Agent authenticate to your GCP project, and how do you scope its access to specific datasets only? Three patterns covering 95% of deployments:

Service-account auth RECOMMENDED

Production-grade, least-privilege, dataset-scoped.

Create a scoped service account in your GCP project (for example [email protected]), then grant it roles/bigquery.dataViewer on the specific datasets you want exposed (NOT project-wide) plus roles/bigquery.jobUser on the project so it can submit query jobs. Download the JSON key file, register it with the agent’s secrets store, and the agent uses it to call the BigQuery Query API and Storage Read API.

Why dataset-scoped instead of project-wide: a project-level dataViewer binding exposes every dataset, including ones you might not want the LLM to see (PII vaults, finance ledgers). Per-dataset binding keeps blast radius small. The agent never holds project-owner credentials — only the scoped service account.

OAuth user delegation

For dev and interactive use; agent runs queries as you.

For dev workflows where you want every BigQuery query to run as your Google identity (so it inherits your row-level security, column masking, and per-user audit trails), the agent supports OAuth user delegation: you sign in once with your Google account, the agent stores a refresh token, and every qs_run_query call is attributed to your account in INFORMATION_SCHEMA.JOBS_BY_USER.

OAuth is great for a one-person dev environment or when you want the BigQuery audit log to show your name on every job. For team / production deployments, prefer the service-account pattern — OAuth refresh tokens get revoked when humans leave, and you don’t want your AI client to start failing because someone changed their password.

Multi-project pattern

Each project is its own connector; LLM picks by name.

Most production GCP setups separate prod-analytics, staging-analytics, and data-team-sandbox into distinct projects with distinct service accounts and IAM bindings. Register each project as its own Query Streams connector with its own scoped service account, name the connectors clearly (prod-analytics, staging-analytics, sandbox), and the LLM picks the right one based on the question:

“show me revenue from prod” routes to prod-analytics; “sanity-check my new query against the sandbox first” routes to sandbox. The user never has to know the project id — the agent surfaces clean human-readable connector names in qs_list_connectors.

For multi-region / regional / dual-region datasets, the same pattern works — the BigQuery API handles region routing under the hood. For row-level security and column-level masking (BigQuery’s IAM-based RLS), all enforcement happens at GCP — the agent simply submits queries and gets back what your service account is permitted to see.

The cloud link is one-per-agent, not one-per-connector. The agent dialing OUT to Query Streams is identical regardless of how many GCP projects or datasets you connect — whether you’ve registered 1 BigQuery project or 12, the agent maintains exactly one outbound encrypted cloud link and multiplexes every connector over it. Add a Cloud SQL or Stripe connector tomorrow and the same cloud link carries the new traffic; nothing changes on the firewall side.
Nova AI

MCP not for you? Try Nova AI instead.

Skip the JSON config entirely: Nova AI is built into the Query Streams web portal and asks the same plain-English questions against your BigQuery datasets — same agent, same read-only enforcement, same Schema Intelligence powering the GoogleSQL, no MCP plumbing.

Meet Nova AI

Prerequisites

Before you start, make sure you have:

  1. A free Query Streams account at my.querystreams.com.
  2. The Query Streams Network Agent installed on a machine that can reach the BigQuery API (a small GCE VM in the same GCP project is the most common pattern) — see Download the Query Streams Agent.
  3. A BigQuery connector configured against the agent — see the existing connector setup guides for the service-account auth flow. The agent holds the service-account key file (or OAuth refresh token); the AI tool never touches them.
  4. Any MCP-capable AI client. We’ll show Cursor, Claude Desktop, ChatGPT, and Grok in this guide; if you use Windsurf, Zed, Continue, Cline, VS Code Copilot, Codex, or Goose, the config block is essentially the same.
  5. Five minutes.
You only set up the agent once. The same agent that powers Query Streams’ Excel and Google Sheets add-ons, the web Query Builder, and Nova AI also serves MCP. Adding MCP to an existing Query Streams account is just generating a key — the agent and BigQuery connector are already running.
1

Generate an MCP key

From the /mcp page in Query Streams, mint a key with the scopes you want.

2

Drop it into your AI client

One JSON snippet for Cursor, Claude, ChatGPT, or Grok. Same key everywhere.

3

Ask a question

“What were our top 10 customers by lifetime value?” — the AI calls the right tools, you get the answer.

Step 1: Generate an MCP key in Query Streams

Sign in to Query Streams and open the MCP page (or sign in first at my.querystreams.com and click MCP in the left navigation). Click Generate key, give the key a recognizable name (something like cursor-laptop or claude-desktop), and pick the scopes you want this key to have:

  • read — the AI can browse connectors and read schema. Required for everything else.
  • analyze — the AI can profile tables and discover relationships (sample values, distributions, semantic types). Optional but strongly recommended for BigQuery work, where understanding STRUCT / ARRAY shape and partition pseudo-columns matters when the LLM is generating queries that need to stay inside a partition-pruned scan.
  • execute — the AI can actually run SQL. Without this, the AI is read-only against schema metadata only.

For a typical “let Claude analyse my BigQuery data” workflow, all three scopes are appropriate. For a key you’re handing to a teammate or a less-trusted client, drop execute and let them browse only. You can revoke any key at any time from the same page; the AI client will see MCP_KEY_REVOKED on its next call and stop working immediately. There’s no propagation delay.

Copy the key now — Query Streams shows it once, then stores only a hash. If you lose it, generate a new one. The key looks like qsmcp_ followed by 48 random characters and is what your AI client sends in the X-MCP-Key request header.

Step 2: Add Query Streams MCP to your AI client

The configuration is the same shape across every MCP-capable client — an MCP server entry pointing at https://mcp.querystreams.com with your key in the X-MCP-Key header. Pick your client below.

Cursor
Cursor ~/.cursor/mcp.json
// Edit ~/.cursor/mcp.json
{
  "mcpServers": {
    "querystreams": {
      "url": "https://mcp.querystreams.com",
      "headers": {
        "X-MCP-Key": "qsmcp_PASTE_KEY_HERE"
      }
    }
  }
}
Claude Desktop
Claude Desktop claude_desktop_config.json
// Settings → Developer → Edit Config
{
  "mcpServers": {
    "querystreams": {
      "url": "https://mcp.querystreams.com",
      "headers": {
        "X-MCP-Key": "qsmcp_PASTE_KEY_HERE"
      }
    }
  }
}
ChatGPT
ChatGPT Apps & Connectors
// Settings → Apps & Connectors → Add MCP
Server URL  https://mcp.querystreams.com
Auth header X-MCP-Key
Header value qsmcp_PASTE_KEY_HERE

// Requires a paid ChatGPT plan
// (Plus / Pro / Team / Enterprise).
Grok
Grok Remote MCP Tools
// Grok → Settings → Tools
{
  "mcp_servers": [{
    "name": "querystreams",
    "url": "https://mcp.querystreams.com",
    "auth_header": "X-MCP-Key",
    "auth_value": "qsmcp_..."
  }]
}

Restart your AI client. On its next start it will discover the eight Query Streams MCP tools listed above and surface them in its tool palette. In Cursor and Claude Desktop you can verify by typing “list connectors” — the AI should call qs_list_connectors and return your BigQuery connector along with anything else you have configured.

Step 3: Ask the AI a BigQuery question

You don’t write SQL — the AI does. You ask a question, the AI picks the right MCP tool, the agent runs the query against your BigQuery dataset, and the answer comes back as text plus tables. Three example prompts to try first:

“What’s our most engaged user cohort by acquisition source?”
Engagement
The AI will call qs_get_connector_schema to discover the events, users, and sessions tables (and pick up that events.event_params is an ARRAY<STRUCT> needing UNNEST), then qs_run_query with a SELECT that joins events to users on user_id, applies a _PARTITIONTIME filter to bound the scan, groups by acquisition_source, and computes engaged-user counts and average sessions per user. You’ll see the result table inline, plus a written interpretation — which channels are punching above their weight on engagement, where the long tail sits — that the AI inferred from your BigQuery data.
“Show conversion funnel by traffic source over the last 90 days.”
Conversion
The AI uses GoogleSQL-idiomatic date math to bound the partition (e._PARTITIONTIME >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 90 DAY)), joins events through users, and computes COUNTIF(event_name = 'page_view'), COUNTIF(event_name = 'add_to_cart'), and COUNTIF(event_name = 'purchase') at each funnel step using the enum-detected event names. The result is a step-by-step funnel by traffic source with absolute counts and conversion rates — the AI typically flags the biggest drop-off step and the highest-converting source without you having to ask.
“Which experiment variants have statistically significant lift on signup rate?”
Experiments
The AI uses Schema Intelligence’s STRUCT / ARRAY annotations to UNNEST(event_params) and pull the experiment id and variant out of the nested record, joins to the experiments dim table, and computes a per-variant signup rate with a Wilson-score confidence interval (or chi-square when the user is on a paid stats LLM model). The result is a focused list of variants with absolute signups, baseline-relative lift, and p-values — usually the AI flags the variants that beat the control with 95% confidence as ship candidates and the rest as keep-running rather than calling false positives.

The first time the AI calls a tool, your client may pop up a confirmation prompt asking you to approve the tool call — that’s MCP’s standard consent flow, not anything Query Streams adds. Approve once and the AI proceeds with the rest of the conversation freely. You can revisit the consent at any time in your client’s settings.

Honest billing notice: MCP usage is charged on uncompressed bytes

Query Streams’ Excel add-in, Google Sheets add-on, web Query Builder, and Nova AI all run over our compressed cloud link — we measure and bill compressedBytes against your data realm. The MCP transport (Streamable HTTP per the official MCP spec) does not reliably support compression end-to-end across every client and intermediate proxy, so we measure and bill uncompressedBytes for MCP traffic.

  • What this means: a 5 MB BigQuery aggregate query costs ~5 MB of your data realm when fetched via MCP, vs. ~700 KB – 1.2 MB via Excel / Sheets / Nova / the Query Builder. BigQuery data with STRUCT and repeated-value columns compresses ~5–8x via LZ4 — particularly efficient for analytics output where many rows share the same enum values, dates, or campaign ids.
  • BigQuery scan cost is independent. Query Streams measures bytes returned to your AI client (data realm), not bytes scanned at the warehouse. So if your LLM writes a query that scans 100 GB of data and returns 10 KB of aggregates, you pay 100 GB-scan to Google + 10 KB to Query Streams. Schema Intelligence’s partition-pruning hints help the LLM minimise both numbers — the SQL diff above scans 6 GB instead of 5 TB on the same question.
  • What this isn’t: a markup or a punishment for using MCP. We pass through actual bytes shipped. The other clients are cheaper because compression works reliably on those transports; we don’t punish you for the protocol choice, but we have to be transparent about the cost shape.
  • What you can do: for very large recurring queries (e.g. 100K+ row exports), prefer the Excel / Sheets / Nova path. For interactive AI tool calls (the typical 100–5,000 row BigQuery response that fits in an LLM context), MCP is the right choice and the cost difference is in cents.

Frequently asked questions

Do I need to open ports or run a VPN to use this? +
No inbound rules, port-forwarding, NAT punchthrough, or VPN. The Network Agent makes one outbound TLS connection (port 443) and your AI client reaches https://mcp.querystreams.com from the public internet — if outbound HTTPS works on the agent host, MCP works. See how the outbound-only connection works →
Which AI tools can I use with Query Streams MCP? +
Any client that speaks the open Model Context Protocol — Claude Desktop, Claude Code, Cursor, ChatGPT (paid), Grok, Gemini CLI, Windsurf, Zed, and 500+ more. Bring your own AI tool; you don’t have to switch. Full list of supported AI clients →
Can I revoke an MCP key? +
Yes — three independent kill-switches (per-key from the /mcp page, per-org via plan settings, and platform-level), none of which need a database password rotation or agent restart. More on MCP key security →
How is MCP usage billed against my data realm? +
MCP execute calls deduct from the same data-realm budget your Excel, Google Sheets, web Query Builder, and Nova AI usage already draws on — one consumption budget across every access method. The size measured for MCP differs. The other clients run over our compressed cloud link (we bill compressedBytes); MCP runs over Streamable HTTP, which doesn’t reliably support compression end-to-end through every client and proxy, so we bill uncompressedBytes. A 5 MB BigQuery aggregate result returned to Excel typically costs ~700 KB – 1.2 MB of your data realm; the same 5 MB result returned to Cursor over MCP costs ~5 MB. BigQuery scan cost is independent — that’s Google’s own metric (TB scanned per query) and is tracked separately from data-realm bytes returned. Schema Intelligence’s partition-pruning hints help the LLM minimise both numbers. We’re transparent about it because we’d rather you know up front than be surprised at the end of the billing cycle.
Does Query Streams MCP work with BigQuery slot reservations, on-demand pricing, BigQuery sandbox (free tier), and BigQuery Omni (cross-cloud)? +
Yes — all BigQuery pricing models and editions are supported. The Network Agent uses the standard BigQuery Storage Read API and Query API via your service-account credentials (or OAuth user delegation). Specifically supported: on-demand pricing (you pay Google per TB scanned), slot reservations (Standard / Enterprise / Enterprise Plus editions with committed slots), flat-rate pricing (legacy), BigQuery sandbox (the free tier with 1 TB/mo of query data and 10 GB of storage works exactly the same as paid — great for evaluation), and BigQuery Omni (running queries against AWS S3 or Azure Blob from a BQ frontend, also called BigLake / Omni). For Omni, the cross-cloud routing happens entirely on the GCP side; the agent submits the same SQL and BigQuery routes the scan to the foreign region. Slot-reservation costs and on-demand bytes-scanned costs are tracked at GCP, completely separate from your Query Streams data-realm consumption. Tip for cost-sensitive workloads: attach a slot reservation specifically for your AI / ad-hoc workloads so unbounded LLM-generated queries can’t burst into your production reservation.
How does this differ from running an open-source BigQuery MCP server myself? +
A direct BigQuery MCP server (community projects on GitHub do exist) is one MCP per data source. To get Claude reading from your BigQuery + Google Search Console + your Stripe account + your Snowflake warehouse you’d need four MCP servers configured separately in every AI client, each with its own credentials, each with its own scope model, each with its own audit story. Query Streams MCP is one key reaching every connector your account has paired. You also pick up Schema Intelligence (which is uniquely useful for BigQuery’s STRUCT / ARRAY traversal and partition-pruning), agent-layer read-only enforcement, per-key rate limits, audit trail in event_logs, and the same data-realm billing pipeline you already use — none of which a direct BigQuery MCP gives you.
What happens if the AI tries to write or delete data? +
It’s rejected at the agent before the data source sees the SQL. Every qs_run_query call is parsed by a hardcoded read-only validator that allows only SELECT, WITH, and EXPLAIN statements; anything else returns READONLY_VIOLATION and never reaches BigQuery. The validator runs in the agent process on your network (or your GCE VM), not in the cloud, so a compromised cloud surface couldn’t bypass it. (Belt-and-suspenders option: bind your scoped service account to roles/bigquery.dataViewer + roles/bigquery.jobUser only — never dataEditor or dataOwner. The agent’s validator is independent of whatever IAM grants you’ve configured at GCP.)
Can I see what the AI actually asked? +
Yes. Every MCP tool call writes a row to event_logs with the org, user, key, scope, latency, and result code. The org-admin can answer “who used MCP last week, which connector, and what did they ask?” with a single query. Note that we log the tool name and metadata, not the SQL text or returned rows — those flow through the cloud link and never land in cloud logs. If you want full SQL audit, BigQuery already gives you that for free: query INFORMATION_SCHEMA.JOBS_BY_USER for the SQL text of every job your service account submitted, or stream BigQuery audit logs to Cloud Logging / a separate BigQuery dataset for long-term retention.
Do I have to run Schema Intelligence to use Query Streams MCP? +
No — Schema Intelligence is opt-in per (connector, dataset) pair, and MCP works fine without it. The AI gets bare schema (types, primary keys, formal foreign keys, indexes — or for BigQuery, types, partitioning, and clustering) and writes basic queries. With SI enabled, the AI gets six additional layers of curated metadata: (1) AI-curated descriptions on every project, dataset, table, and column; (2) table classifications (FACT for event streams and sessions, DIM for users and dimensions, LOOKUP for small code maps) plus a business domain tag (product_analytics, marketing, finance, support, and more); (3) a semantic type on every column (currency_usd, email, date, status_code, percentage, identifier, url, struct_array, partition_column, and others) that drives dialect-correct GoogleSQL generation including UNNEST patterns and partition filters; (4) sample values from your real data so the LLM recognises patterns no schema can show, including STRUCT key names inside ARRAY columns; (5) enum detection with full value distributions for low-cardinality columns (event_name, acquisition_source, plan_tier); and (6) AI-discovered foreign keys based on cross-table data overlap (BigQuery has no FK constraints, so this is uniquely valuable), surfaced through qs_get_relationships. Without SI, every schema-tool response also carries an si_recommendation block listing exactly what’s missing for the call — the AI can read this and offer to trigger SI mid-conversation via qs_request_si_analysis. Run time scales with table count: a small database under 100 tables completes in around 10 minutes; a typical mid-size database (a few hundred tables) finishes in 15–25 minutes; a large enterprise database with 1,500+ tables can take 45–60 minutes for a full scan. SI runs through your Network Agent against your BigQuery data (never in the QS cloud), never writes to your datasets, never changes your schema, uses partition-pruning hints to keep the scan footprint bounded, and refreshes incrementally when your schema changes — so subsequent runs after you add or alter tables are much faster than the first one. The end-to-end effect: with SI enabled, your AI client writes correct GoogleSQL on the first try far more often than it does against any “MCP for X” server that just hands the LLM INFORMATION_SCHEMA.
What if I add another connector later, like Stripe or PostgreSQL? +
Nothing changes client-side — the same key reaches the new connector the moment the agent pairs it (qs_list_connectors picks it up automatically). One config block buys your whole account, present and future. Why one key covers every connector →
Do I have to set up MCP just to chat with my data? +
No — Nova AI is built into the Query Streams portal and works against every connector (BigQuery included) with no MCP setup or config files. Use Nova to chat with your data inside Query Streams; use MCP when you want your own AI client (Claude, Cursor, ChatGPT, …) to reach the same data — same agent, same connectors, same Schema Intelligence underneath. Learn more about Nova AI →
How does Query Streams MCP authenticate to my GCP project + datasets, and how do I scope access to specific datasets only? +
Two authentication patterns, both production-grade. Service account (recommended): create a scoped SA in your GCP project (e.g. [email protected]), grant it roles/bigquery.dataViewer on the specific datasets you want exposed (NOT project-wide) plus roles/bigquery.jobUser on the project so it can submit query jobs. Download the JSON key and register it with the agent’s secrets store. The agent never holds project-owner credentials — only the scoped service account. OAuth user delegation: alternative for dev / interactive use where you want every query to run as your Google identity (so it inherits your row-level security and per-user audit trails). Use SA in production. Multi-project pattern: register each project (e.g. prod-analytics, staging-analytics, data-team-sandbox) as its own connector with its own scoped SA — the LLM picks by name, so a Cursor user can ask “show me revenue from prod” without needing to know the project id. For multi-region / regional / dual-region datasets, the agent works the same way; the BigQuery API handles region routing under the hood. For row-level security and column-level masking (BigQuery’s IAM-based RLS), all enforcement happens at GCP — the agent simply submits queries and gets back what your service account is permitted to see. The cloud link from the agent to Query Streams is one-per-agent regardless of how many GCP projects or datasets you connect.

Get started

Connect your AI tool to your BigQuery data in five minutes.

One MCP key reaches BigQuery, every other database, and every API connector in your Query Streams account — with full audit trail, per-key rate limits, and zero firewall changes. Claude, Cursor, ChatGPT, and Grok all work out of the box.

Related guides: Download the Query Streams Agent | Database Connector Setup | All MCP Server guides | Nova AI text-to-SQL

Category: MCP Server

Tags: mcp, claude, cursor, bigquery, google-cloud, gcp, data-warehouse, googlesql, service-account-auth

Meta Description: Connect Google BigQuery to Claude or Cursor via Query Streams MCP. Service-account auth, GoogleSQL-aware, 5-min setup.

Updated on June 16, 2026

Powered by BetterDocs