mcp-bigquery-dryrun
The mcp-bugquery-dryrun package provides a minimal MCP server for BigQuery SQL validation and dry-run analysis. This server provides exactly two tools for validating and analyzing BigQuery SQL queries without executing them.
** IMPORTANT: This server does NOT execute queries. All operations are dry-run only. Cost estimates are approximations based on bytes processed.**
Features
- SQL Validation: Check BigQuery SQL syntax without running queries
- Dry-Run Analysis: Get cost estimates, referenced tables, and schema preview
- Parameter Support: Validate parameterized queries
- Cost Estimation: Calculate USD estimates based on bytes processed
Quick Start
Prerequisites
- Python 3.10+
- Google Cloud SDK with BigQuery API enabled
- Application Default Credentials configured
Installation
From PyPI (Recommended)
# Install from PyPI
pip install mcp-bigquery-dryrun
# Or with uv
uv pip install mcp-bigquery-dryrun
From Source
# Clone the repository
git clone https://github.com/caron14/mcp-bigquery-dryrun.git
cd mcp-bigquery-dryrun
# Install with uv (recommended)
uv pip install -e .
# Or install with pip
pip install -e .
Authentication
Set up Application Default Credentials:
gcloud auth application-default login
Or use a service account key:
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account-key.json
Configuration
Environment Variables
| Variable | Description | Default |
|---|---|---|
BQ_PROJECT |
GCP project ID | From ADC |
BQ_LOCATION |
BigQuery location (e.g., US, EU, asia-northeast1) | None |
SAFE_PRICE_PER_TIB |
Default price per TiB for cost estimation | 5.0 |
Claude Code Integration
Add to your Claude Code configuration:
{
"mcpServers": {
"bq-dryrun": {
"command": "mcp-bigquery-dryrun",
"env": {
"BQ_PROJECT": "your-gcp-project",
"BQ_LOCATION": "asia-northeast1",
"SAFE_PRICE_PER_TIB": "5.0"
}
}
}
}
Or if installed from source:
{
"mcpServers": {
"bq-dryrun": {
"command": "python",
"args": ["-m", "mcp_bigquery_dryrun"],
"env": {
"BQ_PROJECT": "your-gcp-project",
"BQ_LOCATION": "asia-northeast1",
"SAFE_PRICE_PER_TIB": "5.0"
}
}
}
}
Tools
bq_validate_sql
Validate BigQuery SQL syntax without executing the query.
Input:
{
"sql": "SELECT * FROM dataset.table WHERE id = @id",
"params": {"id": "123"} // Optional
}
Success Response:
{
"isValid": true
}
Error Response:
{
"isValid": false,
"error": {
"code": "INVALID_SQL",
"message": "Syntax error at [3:15]",
"location": {
"line": 3,
"column": 15
},
"details": [...] // Optional
}
}
bq_dry_run_sql
Perform a dry-run to get cost estimates and metadata without executing the query.
Input:
{
"sql": "SELECT * FROM dataset.table",
"params": {"id": "123"}, // Optional
"pricePerTiB": 6.0 // Optional, overrides default
}
Success Response:
{
"totalBytesProcessed": 1073741824,
"usdEstimate": 0.005,
"referencedTables": [
{
"project": "my-project",
"dataset": "my_dataset",
"table": "my_table"
}
],
"schemaPreview": [
{
"name": "id",
"type": "STRING",
"mode": "NULLABLE"
},
{
"name": "created_at",
"type": "TIMESTAMP",
"mode": "REQUIRED"
}
]
}
Error Response:
{
"error": {
"code": "INVALID_SQL",
"message": "Table not found: dataset.table",
"details": [...] // Optional
}
}
Examples
Validate a Simple Query
# Tool: bq_validate_sql
{
"sql": "SELECT 1"
}
# Returns: {"isValid": true}
Validate with Parameters
# Tool: bq_validate_sql
{
"sql": "SELECT * FROM users WHERE name = @name AND age > @age",
"params": {
"name": "Alice",
"age": 25
}
}
Get Cost Estimate
# Tool: bq_dry_run_sql
{
"sql": "SELECT * FROM `bigquery-public-data.samples.shakespeare`",
"pricePerTiB": 5.0
}
# Returns bytes processed, USD estimate, and schema
Analyze Complex Query
# Tool: bq_dry_run_sql
{
"sql": """
WITH user_stats AS (
SELECT user_id, COUNT(*) as order_count
FROM orders
GROUP BY user_id
)
SELECT * FROM user_stats WHERE order_count > 10
"""
}
Testing
Run tests with pytest:
# Run all tests (requires BigQuery credentials)
pytest tests/
# Run only tests that don't require credentials
pytest tests/test_min.py::TestWithoutCredentials
Development
# Install development dependencies
uv pip install -e ".[dev]"
# Run the server locally
python -m mcp_bigquery_dryrun
# Or using the console script
mcp-bigquery-dryrun
Limitations
- No Query Execution: This server only performs dry-runs and validation
- Cost Estimates: USD estimates are approximations based on bytes processed
- Parameter Types: Initial implementation treats all parameters as STRING type
- Cache Disabled: Queries always run with
use_query_cache=Falsefor accurate estimates
License
Apache-2.0
Changelog
0.1.0 (2024-08-12)
- Initial release
Release files for mcp-bigquery-dryrun 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mcp_bigquery_dryrun-0.2.0.tar.gz | 12.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcp_bigquery_dryrun-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 20.2 kB
Release files / mcp_bigquery_dryrun-0.2.0.tar.gz
| Download URL | mcp_bigquery_dryrun-0.2.0.tar.gz |
|---|---|
| Size | 12.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0c7339234ab2c69849ebc6dce6cfeb25b886a5cd17d0c3736f6dc825106b41bb
|
|
BLAKE2b-256 checksum How to use checksums |
7a215e4f8527d3ea758216d88c4b6cf23789d07aabad894d1fa1fc01f40bfef9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.11
|
Release files / mcp_bigquery_dryrun-0.2.0-py3-none-any.whl
| Download URL | mcp_bigquery_dryrun-0.2.0-py3-none-any.whl |
|---|---|
| Size | 8.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0d917b90451beb462ef631630ca38ea9ead3de26697cde655d3bd4c62997ff1d
|
|
BLAKE2b-256 checksum How to use checksums |
6df652a835dde00393912173805d19f79dc5a7a5b6a988ad16d982aec54e0631
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.11
|