Why connect directly

Most agentic analytics workflows start with the same bottleneck: the agent can reason about data but can't access it. You end up copy-pasting query results into a chat window, which defeats the purpose of autonomy. The agent can't explore, can't follow up on anomalies, and can't verify its own assumptions. Research on tool-augmented LLMs shows that direct tool access is the single largest contributor to task completion rates in multi-step reasoning (Schick et al., "Toolformer," 2023).

Connecting Claude Code or Codex directly to BigQuery removes this bottleneck. The agent gets a tool it can call to run arbitrary SQL against your warehouse. This is what unlocks genuinely agentic behavior: the agent can inspect your schema, sample data, run an initial query, notice something unexpected, and run a follow-up query, all without you intervening.

Scope of this guide

This guide covers the connection setup for Claude Code (Anthropic's CLI-based coding agent) and OpenAI Codex (OpenAI's CLI agent). Both operate in your local terminal and can execute shell commands, which is what makes the direct connection possible.

Prerequisites

Before starting, make sure you have the following in place.

Authentication

There are two ways to authenticate the agent with BigQuery. We recommend OAuth for local development and exploration. Use a service account when you need unattended or headless execution.

Option A: OAuth via gcloud (recommended)

The simplest and most secure approach for local use. Your existing gcloud login is used, no key files to manage, and credentials are automatically scoped to your IAM permissions. The agent inherits whatever BigQuery access your Google account already has.

Terminal
# Authenticate with your Google account (opens a browser)
gcloud auth login

# Set your default project
gcloud config set project YOUR_PROJECT_ID

# Verify BigQuery access
bq ls

That's it. Once gcloud auth login has completed, the bq CLI uses your OAuth credentials automatically. No environment variables, no key files.

Why OAuth is preferred

OAuth credentials are short-lived and tied to your identity. There's no key file to leak, no secret to rotate, and every query is attributed to your Google account in audit logs. For individual use and exploration, this is the right default.

If you want the agent to use Application Default Credentials (for example, when using the BigQuery Python client), run:

Terminal
# Set up Application Default Credentials via OAuth
gcloud auth application-default login

Option B: Service account (for headless/shared use)

Use a service account when you need the agent to run without a browser login, in CI, on a server, or with permissions different from your own account. Create a dedicated service account with only the roles it needs.

Terminal
# Create a service account for agent access
gcloud iam service-accounts create agent-bigquery \
  --display-name="Agent BigQuery Access" \
  --project=YOUR_PROJECT_ID

# Grant read-only data access
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
  --member="serviceAccount:agent-bigquery@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/bigquery.dataViewer"

# Grant ability to run queries
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
  --member="serviceAccount:agent-bigquery@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/bigquery.jobUser"

Then create and download a key file:

Terminal
# Generate a key file
gcloud iam service-accounts keys create agent-bigquery-key.json \
  --iam-account=agent-bigquery@YOUR_PROJECT_ID.iam.gserviceaccount.com

# Set the environment variable
export GOOGLE_APPLICATION_CREDENTIALS="$(pwd)/agent-bigquery-key.json"
Security note

Keep key files out of version control. Add agent-bigquery-key.json to your .gitignore. Service account keys don't expire automatically, so rotate them regularly or use Workload Identity Federation for production setups.

Claude Code + BigQuery

Claude Code runs in your terminal and can execute shell commands. The simplest way to give it BigQuery access is through the bq CLI tool, which it can call directly. If you authenticated via OAuth, just start Claude Code. It will pick up your gcloud credentials automatically.

Terminal
# If using OAuth (recommended), just start Claude Code
claude

# If using a service account, set credentials first
export GOOGLE_APPLICATION_CREDENTIALS="./agent-bigquery-key.json"
claude

Then ask Claude Code to query your data directly:

Claude Code prompt
Explore the schema of the `analytics` dataset in BigQuery project
`my-project`. List all tables, then sample 5 rows from each to
understand the data model. Use the bq command-line tool.

Claude Code will run commands like bq ls my-project:analytics and bq head -n 5 my-project:analytics.events to explore your data.

Option B: Using CLAUDE.md for persistent context

For repeated use, create a CLAUDE.md file in your project root that tells Claude Code about the BigQuery connection and schema context. This file is loaded automatically at the start of every session.

CLAUDE.md
# BigQuery Analytics Access

This project has access to BigQuery via the `bq` CLI.
Credentials are in GOOGLE_APPLICATION_CREDENTIALS env var.

## Available datasets
- `my-project.analytics`, product event data
- `my-project.revenue`, billing and subscription data
- `my-project.support`, support tickets and satisfaction

## Query conventions
- Always use `--format=prettyjson` for readable output
- Use `--max_rows=100` to limit result size
- Prefer `bq query --use_legacy_sql=false` for standard SQL
- Always filter by date to avoid scanning entire tables

## Example query
bq query --use_legacy_sql=false --max_rows=50 \
  'SELECT date, COUNT(*) as events
   FROM `my-project.analytics.events`
   WHERE date >= "2026-03-01"
   GROUP BY date ORDER BY date'

With this file in place, every Claude Code session in this directory will start with context about your BigQuery setup and follow your conventions.

Codex + BigQuery

OpenAI Codex operates similarly to Claude Code. It runs in your terminal and can execute commands. The connection setup is the same: ensure the bq CLI is authenticated and accessible.

Setup

Terminal
# Set credentials
export GOOGLE_APPLICATION_CREDENTIALS="./agent-bigquery-key.json"

# Start Codex
codex

Using instructions.md for persistent context

Codex uses an instructions.md file (or the AGENTS.md convention) for persistent context, similar to Claude Code's CLAUDE.md.

instructions.md
# BigQuery Access

You have access to BigQuery via the `bq` command-line tool.

When querying BigQuery:
- Use standard SQL: `bq query --use_legacy_sql=false`
- Limit results: `--max_rows=100`
- Always include date filters to control scan size
- Use `bq ls PROJECT:DATASET` to list tables
- Use `bq show PROJECT:DATASET.TABLE` to inspect schemas

Available datasets:
- `my-project.analytics`, product events
- `my-project.revenue`, billing data
- `my-project.support`, support tickets

Full auto mode

Codex supports a full-auto mode where it executes commands without asking for approval. This is powerful for agentic analytics but should only be used with read-only credentials.

Terminal
# Run in full auto mode (read-only credentials recommended)
codex --approval-mode full-auto \
  "Investigate why daily active users dropped last week. \
   Query the analytics.events table in BigQuery."

Testing the connection

Before running real investigations, verify that the connection works and the agent understands what it has access to. Here's a good test prompt for either tool.

Test prompt
Run the following three checks against BigQuery and report results:

1. List all datasets in project `my-project`
2. For each dataset, list all tables and their row counts
3. Pick the largest table and show its schema plus 3 sample rows

Use the bq command-line tool. Report any permission errors.

A working setup should produce a complete inventory of your datasets, tables, and a schema sample, all without you running a single command manually.

Good to know

A few practical things we've learned from running agentic workflows against BigQuery that aren't obvious from the documentation.

Tag your queries to identify agent activity

BigQuery supports job labels, key-value pairs attached to every query job. Use these to tag agent-generated queries so you can distinguish them from human activity in logs, cost breakdowns, and audit trails.

Terminal
# Add labels to identify agent queries
bq query --use_legacy_sql=false \
  --label=source:claude-code \
  --label=session:investigation-001 \
  --label=team:analytics \
  'SELECT date, COUNT(*) as events
   FROM `my-project.analytics.events`
   WHERE date >= "2026-03-01"
   GROUP BY date ORDER BY date'

Add the --label flags to your CLAUDE.md or instructions.md query conventions so the agent applies them automatically. You can then filter by these labels in the BigQuery console under Job History, or query them programmatically via the INFORMATION_SCHEMA.JOBS view:

SQL
-- Find all queries run by the agent in the last 7 days
SELECT
  job_id,
  user_email,
  total_bytes_processed,
  creation_time
FROM `region-us`.INFORMATION_SCHEMA.JOBS
WHERE creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
  AND EXISTS (
    SELECT 1 FROM UNNEST(labels) l
    WHERE l.key = 'source' AND l.value = 'claude-code'
  )
ORDER BY creation_time DESC

This is invaluable for cost attribution, debugging wrong answers (you can replay exactly what the agent queried), and understanding usage patterns over time.

Use dry-run to estimate costs before querying

BigQuery charges by bytes scanned. You can have the agent run a dry-run first to estimate the cost before executing a query. This is especially useful for large tables where an unfiltered scan could be expensive.

Terminal
# Dry run: shows bytes that would be scanned, no data returned
bq query --use_legacy_sql=false --dry_run \
  'SELECT * FROM `my-project.analytics.events`
   WHERE date >= "2026-01-01"'

Add a note to your CLAUDE.md telling the agent to dry-run any query expected to scan more than a few hundred MB before executing it.

Prefer LIMIT and date filters aggressively

Agents tend to be thorough, which in BigQuery means expensive. A query like SELECT * FROM events on a multi-terabyte table will scan the entire thing even if the agent only looks at the first few rows of output. Partitioned tables only prune partitions when the partition column appears in a WHERE clause. Instruct the agent to always include a date range filter and use LIMIT for exploratory queries.

CLAUDE.md convention
## BigQuery cost rules
- ALWAYS include a date filter (WHERE date >= ...) on partitioned tables
- Use LIMIT 100 for exploratory queries
- Run --dry_run before any query on tables you haven't queried before
- Use --maximum_bytes_billed=1000000000 (1GB) as a safety net

Column descriptions are your semantic layer

If you don't have a formal semantic layer like Cube or dbt MetricFlow, BigQuery column descriptions are the next best thing. The agent reads these when inspecting schemas with bq show. Adding clear descriptions to ambiguous columns (is revenue gross or net? is active a boolean or a status?) dramatically reduces misinterpretation. Research on text-to-SQL shows that schema annotations significantly improve query accuracy (Rajkumar et al., 2022).

SQL
-- Add descriptions to columns the agent will query
ALTER TABLE `my-project.revenue.invoices`
  ALTER COLUMN revenue SET OPTIONS (
    description = 'Gross revenue in USD cents. Divide by 100 for dollars. Does NOT include refunds. Use net_revenue for post-refund amounts.'
  );

Safety considerations

Giving an AI agent direct database access requires intentional guardrails. Here's what we recommend.

Guardrails
Minimum safety configuration
1
Read-only access
Never grant INSERT, UPDATE, DELETE, or DDL permissions to the agent service account. BigQuery Data Viewer + Job User is sufficient.
2
Dataset-level scoping
Grant access only to specific datasets rather than project-wide. Exclude datasets containing PII, financial records, or credentials.
3
Query cost limits
Set a custom quota on the service account to prevent runaway costs. Use BigQuery's maximum bytes billed setting per query.
4
Audit logging
Enable BigQuery audit logs for the service account. Review what the agent queried, how much data it scanned, and how often.

Setting query cost limits

This is the most commonly overlooked guardrail. An agentic workflow can generate many queries, and without limits, a poorly scoped query can scan terabytes of data.

Terminal
# Set a 1GB scan limit per query (adjust to your needs)
bq query --use_legacy_sql=false --maximum_bytes_billed=1000000000 \
  'SELECT COUNT(*) FROM `my-project.analytics.events`'

Include the --maximum_bytes_billed flag in your CLAUDE.md or instructions.md conventions so the agent applies it to every query automatically.

What not to do

Bottom line

The setup takes about 15 minutes. Once connected, both Claude Code and Codex can run genuine multi-step investigations against your BigQuery data. The key is starting with tight permissions and expanding only as you build confidence in the agent's behavior. Read-only access with cost limits is the right default.

References & further reading