BigQuery MCP: connect Claude to BigQuery and keep it read-only
AI for data and analytics · Facts checked 22 October 2026
BigQuery's official MCP server is hosted by Google at bigquery.googleapis.com/mcp and turns on with the BigQuery API. It offers six tools: four for metadata, `execute_sql_readonly` and `execute_sql`, the only one that can write, which you can block with an IAM deny policy. Claude connects as a custom connector over Google OAuth. Results cap at 3,000 rows.
Google runs the BigQuery MCP server; you control who can call it
There's nothing to install. Google hosts an official remote MCP server for BigQuery at https://bigquery.googleapis.com/mcp, and it switches on when you enable the BigQuery API in a project (Google Cloud docs, checked 22 October 2026). It speaks Streamable HTTP, signs in with Google OAuth, and every call is checked against IAM.
It exposes six tools, and only one of them can change anything:
| Tool | What it does | Reads or writes |
|---|---|---|
list_dataset_ids |
Lists datasets in a project | Reads |
list_table_ids |
Lists tables in a dataset | Reads |
get_dataset_info |
Dataset metadata | Reads |
get_table_info |
Table schema and metadata | Reads |
execute_sql_readonly |
Runs a query; rejects DML, DDL and Python UDFs | Reads |
execute_sql |
Runs any SQL the identity is allowed to run | Reads and writes: "the only MCP tool that isn't read-only" |
Two limits shape every answer you'll get. Queries are cancelled after three minutes by default, and results are capped at 3,000 rows. Neither is a problem if Claude aggregates in SQL. Both are a problem if it pulls raw rows and summarises them itself, which it will happily do unless you ask otherwise.
Every query runs as an ordinary BigQuery job under the identity that signed in. The MCP server has no quotas of its own; BigQuery's usual API quotas and billing apply.
Connect it to Claude in five steps
You need a Google Cloud project with BigQuery enabled and permission to create an OAuth client. The steps follow Google's BigQuery MCP guide, its client set-up page and Anthropic's custom connector help article.
- Enable the BigQuery API in the project. That also enables the MCP server.
- Grant IAM roles to the people (or the dedicated identity) who will connect: MCP Tool User (
roles/mcp.toolUser), BigQuery Job User (roles/bigquery.jobUser) and BigQuery Data Viewer (roles/bigquery.dataViewer). - Create an OAuth client. In the Google Cloud console, go to Google Auth Platform > Clients > Create client. Choose Web application, add
https://claude.aias an authorised JavaScript origin andhttps://claude.ai/api/mcp/auth_callbackas the redirect URI, then create it. Copy the client secret straight away: Google shows it once. - Add the connector in Claude. On Pro or Max, Customize > Connectors > Add custom connector. Name it, enter
https://bigquery.googleapis.com/mcp, choose "Use your own OAuth client" and paste the client ID and secret. On Team or Enterprise an Owner adds it under Organization settings > Connectors, and each member then connects with their own Google account. - Sign in and test with a question you can answer yourself, such as the row count of a table you know.
The OAuth scope is https://www.googleapis.com/auth/bigquery, which Google describes as "View and manage your data in BigQuery". The scope is broad. IAM is what narrows it, so step 2 is where the safety lives.
- Warehouse
- BigQuery · reporting datasets
read with a least-privilege role - MCP serverquery through approved tools
- audit before it ships
- share
- Where it goes
- Dashboard
- Board pack
- Slack thread
BigQuery answers, with the working shown
BigQuery's MCP server gives Claude your data. Count shows which claims in the answer trace to a query, and which rest on a definition nobody checked.
Make it read-only with an IAM deny policy, not a polite request
Telling Claude "only run SELECT statements" is a preference. An IAM deny policy is a rule. Google's docs say you can "restrict access to the execute_sql tool by creating a deny policy that restricts read-write MCP tool use", which leaves execute_sql_readonly and the metadata tools working. Its IAM policies can also filter by tool name, by the read-only attribute and by OAuth client ID, so you can allow the Claude client and nothing else.
The set-up we'd use for anyone outside the data team:
- Deny read-write MCP tools for the group that uses Claude. With
execute_sqlblocked, a mistakenDELETEfails at Google's end, whatever the prompt said. - Narrow Data Viewer. Google's guide grants the roles on the project. BigQuery also supports access at dataset level, so if the project holds raw or sensitive data, grant Data Viewer only on the reporting datasets Claude should see.
- Use a separate identity for agents. Google recommends it so access "can be controlled and monitored". Shared credentials make every query look like the same person.
- Consider Model Armor for prompt and response screening. Google's caveats are worth reading first: its logs capture the whole payload, which "might expose sensitive information in your logs", and its routing may not respect data residency everywhere.
In Claude, approve tool calls one at a time rather than "Allow always", and remember Anthropic's warning that in Research mode Claude "can invoke tools from your connectors automatically without further approval".
Prompts that keep BigQuery answers inside the row cap
Each of these asks Claude to aggregate in SQL, name its definitions and show the query (examples illustrative; use your own datasets).
Map the data before asking anything:
Using the BigQuery connector, list the datasets in project acme-analytics and the
tables in the reporting dataset. For the subscriptions table, give the grain (what
one row represents), the date columns and any obvious status fields. Don't run
any analysis yet.
Ask for a metric with the definition pinned:
Calculate monthly active users for September 2026 from reporting.events. Before
running anything, state whether you'll use a calendar month or a rolling 30 days,
and which event counts as "active". Aggregate in SQL; don't pull raw rows. Show
the query, the bytes it scanned if you can see them, and the row count returned.
Explain a change, without guessing:
Return on ad spend fell from August to September. Using reporting.ad_spend and
reporting.orders, break the change down by channel. Show each query. Compute
ROAS as total conversion value divided by total spend, never as an average of
daily ROAS. If the data can't explain part of the change, say so.
Spot truncation:
Before you answer, check: did any query return exactly 3,000 rows? If so, the
result was capped. Rewrite the query to aggregate and run it again.
The last prompt is cheap insurance. On BigQuery's MCP server, 3,000 is the number that means "there was more".
Read-only stops changes, not leaks
BigQuery's server is Google's own, so the risk is rarely the server. It is the session around it. The dated incidents that shaped MCP security all follow one pattern: untrusted text, a connection with valuable data, and a way out.
- 1 April 2025: tool poisoning. Invariant Labs showed that hidden instructions in another server's tool description could make a model read files and pass them on, and that a tool's description can change after you approve it.
- 26 May 2025: GitHub MCP. A malicious public issue led an agent in Claude Desktop, with "Always Allow" on, to copy private-repository data into a public pull request (Invariant Labs).
- 8 July 2025: Supabase MCP. Hidden instructions in a support ticket led a coding agent, connected with a key that bypassed row-level security, to read an integration-tokens table and post it into the ticket (General Analysis). Their advice applies directly to a warehouse: a read-only role still reads everything it can see, so keep secrets out of reach.
What that means for BigQuery: don't connect it in the same Claude session as a connector that reads inbound email, tickets or public issues and can also post somewhere. Keep credential tables, PII and raw logs in datasets the Claude group can't see. And read the query before approving it: a request for revenue by month has no reason to touch a users table's email column.
The query is valid, and the metric is still somebody's guess
Most wrong answers from a connected warehouse aren't syntax errors. They're definitions.
"Monthly active users" in Google Analytics means a rolling 30 days, not a calendar month (GA4 Help), and your events table may mean something else again. "Churn" can be logo or revenue churn, and on ChartMogul's three-customer example those come out at 33% and 50%. ROAS is revenue over spend, but an average of daily ROAS values isn't the same number as total value over total spend. Claude will pick one reading, write correct SQL for it and present the result with the same confidence either way. See return on ad spend for one metric's competing definitions.
Benchmarks agree that real schemas are where models slip. In the original Spider 2.0 paper, the best agent solved 21.3% of enterprise text-to-SQL problems against 91.2% on the older Spider 1.0 (Lei et al., November 2024). Agents have improved a great deal since, but an expert audit found that more than half of the answer keys on two major benchmarks had errors, often because the question itself was ambiguous (Jin et al., January 2026). We cover that in text-to-SQL.
The fix that scales is to write definitions down where the model can read them: a modelled reporting dataset, a dbt semantic layer (see dbt MCP), or at minimum a project instruction listing your metric definitions. More in semantic layers for AI.
Two minutes with the tool calls before you share the number
Claude shows each BigQuery call it makes. Expand them.
- Which tool ran?
execute_sql_readonlyis what you want. Ifexecute_sqlappears and you didn't expect it, find out why. - Read the query. Check the joins (is the grain still one row per customer?), the date filter (column, time zone, end date) and any
WHEREthat quietly drops rows. - Check the row count. Exactly 3,000 means truncated. Zero means a filter is wrong.
- Re-run one query in the BigQuery console and compare.
- Ask: "Which numbers came from a query result, and which did you calculate or assume afterwards?" Arithmetic done outside SQL is where small errors creep in.
For an answer that's going into a deck, Count makes this systematic. Connect Count's MCP server to Claude alongside BigQuery and ask it to audit the answer. It returns a link to a canvas with every claim labelled (Citation, Assumption, Model knowledge, Hallucination) and a reasoning chain under each, showing the queries and calculations it rests on. A ROAS figure averaged from daily ratios shows up in the chain, not in a footnote. The canvas connects to BigQuery too, so you can fix the query there and re-run it.
Questions people ask
Is there an official BigQuery MCP server?
Yes. Google hosts a remote MCP server for BigQuery at https://bigquery.googleapis.com/mcp. It is enabled when you enable the BigQuery API, and access is controlled by IAM roles and OAuth.
How do I connect Claude to BigQuery?
Grant the MCP Tool User, BigQuery Job User and Data Viewer roles, create a Web application OAuth client with Claude's redirect URI, then add the server URL, client ID and secret as a custom connector in Claude.
Can the BigQuery MCP server modify data?
One tool can: execute_sql. Every other tool is read-only, and execute_sql_readonly rejects DML and DDL. Google's docs describe blocking execute_sql with an IAM deny policy, which we'd do for everyone outside the data team.
What are the BigQuery MCP server's limits?
Queries are cancelled after three minutes by default and results are capped at 3,000 rows. The SQL tools don't support Google Drive external tables, and normal BigQuery API quotas apply.
Sources
- Google Cloud: Use the BigQuery MCP server (checked 22 October 2026)
- Google Cloud: Configure MCP in an AI application (checked 22 October 2026)
- Google Cloud: Supported products for remote MCP
- Anthropic Help Centre: Getting started with custom connectors using remote MCP (checked 22 October 2026)
- Invariant Labs: MCP security notification, tool poisoning attacks (1 April 2025)
- Invariant Labs: GitHub MCP exploited (26 May 2025)
- General Analysis: Supabase MCP can leak your entire SQL database (8 July 2025)
- Lei et al.: Spider 2.0 (arXiv, v1 12 November 2024, v2 17 March 2025)
- Jin, Choi, Zhu, Kang: Pervasive Annotation Errors Break Text-to-SQL Benchmarks and Leaderboards (arXiv, January 2026)
- Google Analytics Help: DAU, WAU and MAU (rolling windows)
- ChartMogul: Customer churn rate
