BigQuery-Read-Only-MCP-Server

Un servidor seguro y autohospedado del Protocolo de Contexto de Modelo (MCP) para Google BigQuery. Listas blancas de tablas estrictas, límites de escaneo por consulta, limitación de velocidad integrada y costos predecibles en Cloud Run. Funciona con Claude, ChatGPT, Cursor, Gemini y cualquier agente de IA compatible con MCP.

Documentación

Servidor MCP de BigQuery de Solo Lectura

Un servidor de Protocolo de Contexto de Modelo (MCP) para Google BigQuery seguro y autoalojado. Listas blancas estrictas de tablas, límites de escaneo por consulta, limitación de velocidad integrada y costos predecibles en Cloud Run. Funciona con Claude, ChatGPT, Cursor, Gemini y cualquier agente de IA compatible con MCP.

License: MIT Python 3.11+ Cloud Run MCP Claude Desktop


📚 Artículos relacionados

Publicaciones extensas sobre este proyecto en hugonissar.github.io:

O lee la descripción general del proyecto.

📖 Qué es esto

Un servidor MCP de BigQuery listo para producción que despliegas en tu propio proyecto de GCP. Los agentes de IA se conectan a través de HTTPS y pueden hacer exactamente dos cosas: leer los esquemas de las tablas que permites explícitamente en la lista blanca y ejecutar consultas SELECT contra ellas, sujeto a un presupuesto de escaneo configurable, un límite de filas de resultados y una limitación de velocidad de depósito de tokens. Nada más. Sin DROP, sin INSERT, sin descubrimiento de esquemas más allá de lo que permites, sin facturas sorpresa.

Existe porque las alternativas — incluido el servidor MCP oficial de BigQuery de Google — exponen todas las tablas a las que la cuenta de servicio subyacente puede acceder. Ese es el valor predeterminado correcto para analistas internos de confianza. Es el valor predeterminado incorrecto para un agente autónomo que podría ser invocado por un chatbot orientado al cliente, una herramienta de terceros o un documento con inyección de prompts.

💬 Caso de uso

Tú: Dame la campaña con mayor conversión en los últimos 30 días
LLM: consulta tus datos y devuelve el resultado

Conéctate una vez, consulta todo. Apúntalo a tu exportación de Google Analytics 4, o importa Google Ads, Meta y TikTok a BigQuery para analizar cada campaña en cada canal desde un solo agente.

🏆 Por qué elegir esto en lugar del servidor MCP oficial de BigQuery de Google

  1. Lista blanca estricta de tablas aplicada en código, no solo en IAM. Listas pares de (dataset, table) en variables de entorno. Cualquier cosa fuera de la lista blanca se rechaza en el analizador SQL antes de que se envíe un trabajo, incluidas referencias calificadas como wrong_dataset.allowed_table. El servidor de Google permite que el agente vea todas las tablas que el IAM de la SA permite.

  2. Límite estricto de escaneo por consulta (MAX_SCAN_MB). Cada consulta se prueba primero en seco. Si el escaneo estimado excede el límite, la consulta se rechaza — no se crea ningún trabajo de BigQuery, no se facturan bytes. Esto detiene de raíz el conocido problema de "la IA acaba de ejecutar una consulta de $2000". El servidor de Google no tiene límite de escaneo integrado — tienes que aplicarlo mediante roles de IAM personalizados o cuotas a nivel de BQ.

  3. Limitación de velocidad integrada con depósito de tokens + ráfaga. Los documentos de Google son explícitos: "El servidor MCP de BigQuery no tiene sus propias cuotas. No hay límite en el número de llamadas que se pueden hacer al servidor MCP." Este servidor incluye RATE_LIMIT_QPM y RATE_LIMIT_BURST configurables de serie, además de semáforos de concurrencia separados para consultas frente a llamadas de metadatos.

  4. Solo lectura aplicada por el analizador SQL, no solo por IAM. DDL, DML, scripting, cuerpos de múltiples declaraciones y construcciones procedurales se rechazan en la capa de aplicación además de lo que IAM te dé. Defensa en profundidad — una concesión de IAM mal configurada no puede habilitar escrituras accidentalmente.

  5. Límite de filas de resultados (MAX_RESULT_ROWS). Una consulta que devuelve un millón de filas se trunca en el servidor antes de que toque la ventana de contexto de un LLM. Ahorra tokens, ahorra dinero y previene la exfiltración accidental de PII a través de escaneos amplios.

  6. Caché de prueba en seco. Las pruebas en seco repetidas del mismo SQL usan una caché LRU + TTL, por lo que un agente que reintenta o itera no genera llamadas redundantes a la API de BigQuery. Las búsquedas de esquemas también se almacenan en caché con TTL.

  7. Costo predecible, casi cero en inactividad. Cloud Run se reduce a cero. Pagas casi nada en inactividad y unos pocos dólares al mes bajo carga moderada. Compáralo con un endpoint administrado donde estás sujeto al modelo de precios que el proveedor decida después del GA.

  8. Multiinquilino mediante variables de entorno, sin archivo de configuración. Listas separadas por comas de BQ_DATASET_ID y BQ_ALLOWED_TABLE emparejadas posicionalmente — analytics.events, reporting.daily, etc. Añade o elimina tablas con una sola gcloud run deploy --update-env-vars. Sin archivo de configuración que hornear en la imagen, sin redespliegues de un servicio de configuración separado.

  9. Superficie de herramientas mínima. Solo se exponen dos herramientas: get_table_schema y query_assessments. Menor superficie de ataque, más fácil de auditar, menos para que el agente haga mal uso. El servidor de Google expone una execute_sql genérica además de herramientas de descubrimiento de metadatos que recorren todo el grafo del proyecto.

  10. Un solo archivo, licencia MIT, ~1400 líneas. Lee el código fuente. Haz un fork. Añade un validador personalizado. Cambia el esquema de autenticación. No puedes hacer nada de eso con un servidor administrado de código cerrado.

⚖️ Tabla comparativa

Este servidorServidor MCP oficial de BigQuery de Google
Modelo de despliegueAutoalojado en Cloud RunEndpoint remoto administrado
AutenticaciónClave API + clave de administradorIAM de Google / OAuth
Control de acceso a tablasLista blanca estricta de pares (dataset, table), aplicada en códigoSolo IAM — cualquier tabla accesible
Límite de escaneo por consultaSí (MAX_SCAN_MB, aplicado mediante prueba en seco)No (depende de IAM / cuotas de BQ)
Limitación de velocidadDepósito de tokens integrado + ráfagaNinguna (según los documentos de Google)
Límite de filas de resultadosSí (MAX_RESULT_ROWS)No
Caché de prueba en seco / esquemaSí (LRU + TTL)No
Aplicación de solo lecturaAnalizador SQL + IAMSolo IAM
Herramientas expuestas2 (esquema, consulta)5+ incluyendo execute_sql, pronósticos, listado de conjuntos de datos/tablas
Pronósticos / ayudas de MLNo (escribe tu propio SQL)Sí (forecast integrado)
Escaneo de inyección de promptsNoSí (mediante Model Armor, complemento de pago)
Registro de auditoríaCloud Logging + registros de auditoría de BQCloud Audit Logs
Código fuenteAbierto (MIT)Cerrado
Costo en inactividad~$0 (se reduce a cero)N/D (administrado)
Hacer fork y modificarNo
Bloqueo de regiónElige cualquier región de Cloud RunSolo las regiones de Google

Cuándo elegir el servidor de Google en su lugar: si quieres pronósticos y ARIMA de serie, si necesitas Model Armor para el escaneo de inyección de prompts, o si te sientes cómodo dejando que el agente vea todo lo que el IAM de la SA alcanza y no necesitas un límite estricto de escaneo.

Cuándo elegir este servidor: cualquier otra cosa — especialmente agentes de producción, despliegues orientados al cliente, entornos regulados, escenarios multiinquilino y en cualquier lugar donde las palabras "presupuesto de escaneo" o "límite de velocidad" importen.

🏗️ Arquitectura de un vistazo

┌─────────────┐       HTTPS + X-API-KEY       ┌──────────────────────┐         IAM        ┌───────────┐
│ MCP client  │ ────────────────────────────▶ │  Cloud Run service   │ ─────────────────▶ │ BigQuery  │
│ (Claude /   │            API KEY            │  bigquery-readonly-  │   service account  │  datasets │
│  Cursor /   │                               │       mcp-server     │                    │  + tables │
│  ChatGPT)   │                               │                      │                    │           │
└─────────────┘                               │  • SQL allowlist     │                    └───────────┘
                                              │  • Dry-run scan cap  │
                                              │  • Rate limiter      │                    ┌───────────┐
                                              │  • Schema cache      │ ◀───── secrets ──  │  Secret   │
                                              └──────────────────────┘                    │  Manager  │
                                                                                          └───────────┘

☁️ Servicios de GCP requeridos

Habilita estas APIs en tu proyecto:

ServicioPropósitoRequerido
Cloud Run (run.googleapis.com)Aloja el servidor MCP
BigQuery (bigquery.googleapis.com)El almacén de datos que estás consultando
Secret Manager (secretmanager.googleapis.com)Almacena MCP_API_KEY y MCP_ADMIN_KEY
Artifact Registry (artifactregistry.googleapis.com)Aloja la imagen del contenedor
IAM (iam.googleapis.com)Cuenta de servicio + vinculaciones de roles
Cloud Build (cloudbuild.googleapis.com)Si construyes la imagen en GCPOpcional
Cloud LoggingCaptura registros estructurados del servicioAutomático
Cloud MonitoringCaptura métricas + alertasAutomático

Habilitación rápida:

gcloud services enable \
  run.googleapis.com \
  bigquery.googleapis.com \
  secretmanager.googleapis.com \
  artifactregistry.googleapis.com \
  iam.googleapis.com \
  cloudbuild.googleapis.com

🔐 Permisos de la cuenta de servicio (privilegio mínimo)

Crea una cuenta de servicio dedicada — no reutilices una. El servicio necesita el mínimo absoluto: acceso de lectura a tablas específicas de BigQuery, la capacidad de ejecutar trabajos de consulta y acceso de lectura a dos secretos.

PROJECT_ID="your-project"
SA_NAME="bigquery-readonly-mcp"
SA_EMAIL="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"

gcloud iam service-accounts create $SA_NAME \
  --display-name="BigQuery Read-Only MCP Server"

🔑 Roles de IAM requeridos

RolAlcancePor qué
roles/bigquery.jobUserProyectoPermite que la SA envíe trabajos de consulta (no otorga acceso a datos)
roles/bigquery.dataViewerConjunto de datos (por conjunto de datos en lista blanca)Leer esquemas + filas de tablas
roles/bigquery.metadataViewerConjunto de datos (por conjunto de datos en lista blanca)Leer esquemas sin acceso de lectura — opcional, solo si tienes conjuntos de datos donde quieres visibilidad de esquemas sin acceso a filas
roles/secretmanager.secretAccessorSecreto (por secreto)Leer clave API + clave de administrador

Otorgar bigquery.jobUser en el proyecto

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SA_EMAIL}" \
  --role="roles/bigquery.jobUser"

Otorgar bigquery.dataViewer en el conjunto de datos específico (preferido sobre todo el proyecto)

# For each dataset in BQ_DATASET_ID:
DATASET="your_dataset"
bq add-iam-policy-binding \
  --member="serviceAccount:${SA_EMAIL}" \
  --role="roles/bigquery.dataViewer" \
  "${PROJECT_ID}:${DATASET}"

Para un control más estricto, otorga acceso a nivel de tabla en lugar del conjunto de datos:

DATASET="your_dataset"
TABLE="your_table"
bq add-iam-policy-binding \
  --member="serviceAccount:${SA_EMAIL}" \
  --role="roles/bigquery.dataViewer" \
  "${PROJECT_ID}:${DATASET}.${TABLE}"

Otorgar secretAccessor en los dos secretos

gcloud secrets add-iam-policy-binding mcp-api-key \
  --member="serviceAccount:${SA_EMAIL}" \
  --role="roles/secretmanager.secretAccessor"

gcloud secrets add-iam-policy-binding mcp-admin-key \
  --member="serviceAccount:${SA_EMAIL}" \
  --role="roles/secretmanager.secretAccessor"

Esa es toda la superficie de IAM. No otorgues bigquery.user, bigquery.admin, editor o owner — ninguno de esos es necesario y todos otorgan estrictamente más de lo necesario.

🚀 Inicio rápido

1. Genera y almacena claves API

# MCP API key (clients use this in X-API-KEY)
openssl rand -hex 32 | gcloud secrets create mcp-api-key --data-file=-

# Admin key (for the /admin endpoint — schema cache invalidation)
openssl rand -hex 32 | gcloud secrets create mcp-admin-key --data-file=-

2. Construye y sube la imagen

REGION="europe-north2"
PROJECT_ID="your-project"
REPO="bigquery-readonly-mcp"
IMAGE="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPO}/server:latest"

gcloud artifacts repositories create $REPO \
  --repository-format=docker \
  --location=$REGION

gcloud builds submit --tag $IMAGE

3. Despliega en Cloud Run

gcloud run deploy bigquery-readonly-mcp \
  --image="$IMAGE" \
  --region="$REGION" \
  --service-account="bigquery-readonly-mcp@${PROJECT_ID}.iam.gserviceaccount.com" \
  --set-secrets="MCP_API_KEY=mcp-api-key:latest,MCP_ADMIN_KEY=mcp-admin-key:latest" \
  --set-env-vars="\
GCP_PROJECT_ID=${PROJECT_ID},\
BQ_DATASET_ID=your_dataset,\
BQ_ALLOWED_TABLE=your_table,\
MAX_SCAN_MB=100,\
MAX_RESULT_ROWS=2000,\
BQ_JOB_TIMEOUT_SECS=60,\
MAX_SQL_LENGTH=2000,\
SCHEMA_TTL_SECS=300,\
DRY_RUN_CACHE_TTL_SECS=60,\
DRY_RUN_CACHE_MAX_ENTRIES=1000,\
RATE_LIMIT_QPM=20,\
RATE_LIMIT_BURST=5,\
QUERY_CONCURRENCY=10,\
META_CONCURRENCY=3,\
ADMIN_RATE_LIMIT_QPM=10,\
MAX_REQUEST_BODY_BYTES=65536" \
  --allow-unauthenticated \
  --port 8080

Para múltiples conjuntos de datos/tablas, gcloud necesita un delimitador alternativo para que las comas dentro de los valores no se dividan como variables separadas:

gcloud run deploy bigquery-readonly-mcp \
  --image="$IMAGE" \
  ...
  --set-env-vars="^@^\
GCP_PROJECT_ID=${PROJECT_ID}@\
BQ_DATASET_ID=analytics,reporting,raw@\
BQ_ALLOWED_TABLE=events,daily_summary,events@\
MAX_SCAN_MB=100"

Los conjuntos de datos y las tablas se emparejan posicionalmente: el índice 0 se empareja con el índice 0. El ejemplo anterior permite analytics.events, reporting.daily_summary y raw.events. Las longitudes de las listas deben coincidir.

4. Conéctate desde un cliente MCP

// claude_desktop_config.json or equivalent
{
  "mcpServers": {
    "bigquery": {
      "command": "/home/yourusername/.local/bin/uvx",
      "args": [
        "mcp-proxy",
        "--transport", "streamablehttp",
        "-H", "x-api-key", "YOUR_MCP_API_KEY",
        "https://bigquery-readonly-mcp-XXXX.a.run.app/mcp"
      ]
    }
  }
}

⚙️ Referencia de configuración

Toda la configuración es mediante variables de entorno. Las variables requeridas abortan el inicio si faltan; todo lo demás tiene un valor predeterminado.

VariableRequeridaPredeterminadoDescripción
GCP_PROJECT_IDEl proyecto donde se ejecutan los trabajos de BigQuery
BQ_DATASET_IDLista de conjuntos de datos separados por comas
BQ_ALLOWED_TABLELista de tablas separadas por comas; emparejadas posicionalmente con BQ_DATASET_ID
MCP_API_KEYClave API que los clientes deben presentar
MCP_ADMIN_KEYNoClave API para el endpoint /admin; si está vacía, usa MCP_API_KEY por defecto
MAX_SCAN_MBNo100Límite estricto de bytes escaneados por consulta (MB)
MAX_RESULT_ROWSNo2000Las filas de resultados se truncan por encima de esto
BQ_JOB_TIMEOUT_SECSNo30Tiempo de espera de BigQuery por consulta
MAX_SQL_LENGTHNo2000Rechazar SQL más largo que esto
MAX_REQUEST_BODY_BYTESNo65536Rechazar cuerpos HTTP más grandes que esto
SCHEMA_TTL_SECSNo300TTL de caché de esquemas
DRY_RUN_CACHE_TTL_SECSNo60TTL de caché de prueba en seco
DRY_RUN_CACHE_MAX_ENTRIESNo1000Tamaño LRU para caché de prueba en seco
RATE_LIMIT_QPMNo20Tasa de recarga del depósito de tokens (consultas por minuto)
RATE_LIMIT_BURSTNo5Capacidad de ráfaga del depósito de tokens
QUERY_CONCURRENCYNo10Máximo de trabajos de consulta BQ concurrentes
META_CONCURRENCYNo3Máximo de llamadas de metadatos concurrentes
ADMIN_RATE_LIMIT_QPMNo10Límite de velocidad separado para el endpoint de administrador

🛡️ Modelo de seguridad

El modelo de amenazas es: un agente de IA es parcial o totalmente no confiable y puede ser invocado con entrada adversarial. Los controles están en capas.

  1. Capa de red. Cloud Run te ofrece terminación HTTPS y Cloud Armor opcional delante para listas de permitidos por IP o reglas WAF.
  2. Capa de autenticación. Cada solicitud requiere un encabezado x-api-key: <key> comparado con MCP_API_KEY en tiempo constante. El endpoint de administración requiere un encabezado x-admin-key separado.
  3. Límite de tamaño del cuerpo. Las solicitudes por encima de MAX_REQUEST_BODY_BYTES se rechazan antes del análisis.
  4. Límite de tasa. Token-bucket, por instancia. Los clientes con mal comportamiento reciben 429s.
  5. Capa de análisis SQL. sqlparse descompone cada consulta. Las sentencias que no son SELECT, los cuerpos de múltiples sentencias, DDL, DML, scripting y construcciones procedurales se rechazan.
  6. Aplicación de la lista de permitidos. Cada tabla referenciada en FROM / JOIN / unión por comas se valida contra la lista de permitidos (dataset, table) en sus dos últimos segmentos. Las referencias entre conjuntos de datos como wrong_ds.allowed_table se rechazan. Los nombres de tabla simples que existen en múltiples conjuntos de datos permitidos se rechazan por ambiguos (el agente debe calificarlos).
  7. Conocimiento de CTE. Los nombres de Common Table Expression están exentos: no son tablas.
  8. Techo de escaneo en dry-run. El dry-run de BigQuery estima los bytes escaneados. Las consultas que superan MAX_SCAN_MB se rechazan antes de que se ejecute el trabajo real.
  9. Capa de IAM. Incluso si se omitieran todas las comprobaciones anteriores, la cuenta de servicio solo tiene dataViewer en conjuntos de datos / tablas específicos.
  10. Truncamiento de resultados. La salida está limitada a MAX_RESULT_ROWS para que una sola respuesta no pueda exfiltrar una tabla completa.

Lo que el servidor no hace (y deberías saber):

  • Sin escaneo de inyección de prompts. Si lo necesitas, despliega detrás de una puerta de enlace de seguridad de modelos (p. ej. Model Armor de Google, Lakera Guard, NeMo Guardrails) o usa el servidor MCP oficial de Google, que tiene integración con Model Armor.
  • Sin enmascaramiento a nivel de columna. La lista de permitidos está a nivel de tabla. Si tus tablas contienen columnas con PII que no quieres exponer, crea una vista autorizada de BigQuery que proyecte solo columnas seguras y añade la vista a la lista de permitidos.
  • Sin atribución por usuario. La clave de API se comparte entre clientes. Para registros de auditoría por usuario, coloca un proxy consciente de identidad delante, o haz un fork y añade OAuth.
  • Sin soporte de escritura, nunca. Es intencional. Si necesitas escrituras, usa un servidor diferente.

💻 Desarrollo local

git clone https://github.com/hugonissar/bigquery-readonly-mcp-server.git
cd bigquery-readonly-mcp-server

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

# Authenticate to GCP
gcloud auth application-default login

# Set required env vars
export GCP_PROJECT_ID=your-project
export BQ_DATASET_ID=your_dataset
export BQ_ALLOWED_TABLE=your_table
export MCP_API_KEY=$(openssl rand -hex 32)

# Run
uvicorn main:app --host 0.0.0.0 --port 8080 --reload

El endpoint MCP estará en http://localhost:8080/mcp y /health devuelve el estado del servicio.

🛠️ Operaciones

🔄 Invalidar la caché de esquema tras un cambio de esquema

curl -X POST "https://your-service.run.app/admin/invalidate-cache" \
  -H "x-admin-key: $MCP_ADMIN_KEY"

📜 Ver registros (tail logs)

gcloud run services logs tail bigquery-readonly-mcp --region=$REGION

🔍 Consultar el registro de auditoría

Cada trabajo de BigQuery se registra en Cloud Audit Logs. Para ver qué consultas ha ejecutado el servidor MCP:

SELECT
  protopayload_auditlog.authenticationInfo.principalEmail AS sa,
  protopayload_auditlog.servicedata_v1_bigquery.jobCompletedEvent.job.jobConfiguration.query.query AS sql,
  protopayload_auditlog.servicedata_v1_bigquery.jobCompletedEvent.job.jobStatistics.totalBilledBytes AS bytes,
  timestamp
FROM `your-project.cloudaudit_logs.cloudaudit_googleapis_com_data_access`
WHERE protopayload_auditlog.authenticationInfo.principalEmail = 'bigquery-readonly-mcp@your-project.iam.gserviceaccount.com'
ORDER BY timestamp DESC
LIMIT 100;

⚠️ Limitaciones

  • Una región por despliegue. Cloud Run es regional. Para conmutación por error multi-región, despliega múltiples instancias detrás de un balanceador de carga global.
  • Arranques en frío. Scale-to-zero significa que la primera solicitud tras inactividad tarda unos segundos. Configura --min-instances=1 para eliminarlo a costa de unos pocos dólares al mes.
  • Esquema de autenticación único. Solo clave de API en el encabezado x-api-key. Sin OAuth, sin mTLS de serie (ambos son alcanzables mediante la autenticación basada en IAM de Cloud Run + un proxy consciente de identidad; consulta Operaciones).
  • La caché de esquema es por instancia. Cada instancia de Cloud Run mantiene la suya propia. El endpoint de administración invalida la caché en la instancia que recibe la llamada; bajo carga con múltiples instancias, puede que prefieras lanzar una nueva revisión.
  • Sin resultados en streaming. Las consultas se materializan completamente en el servidor antes del truncamiento. No aumentes MAX_RESULT_ROWS más allá de unos pocos miles sin considerar la memoria.

❓Preguntas frecuentes

¿Funciona con Claude Desktop? Sí, mediante la configuración url + headers anterior. También funciona con Cursor, Windsurf, Claude Code, OpenAI Responses API y cualquier otra cosa que hable streamable-HTTP MCP.

¿Puedo usarlo con una VPC privada / conector VPC serverless? Sí. Añade --vpc-connector y --ingress=internal al comando de despliegue de Cloud Run. Luego adjunta un balanceador de carga interno para el acceso de los clientes.

¿Cómo se compara con MCP Toolbox for Databases? MCP Toolbox es genérico para muchas bases de datos y se configura mediante YAML. Este servidor es específico de BigQuery y se configura mediante variables de entorno. Elige Toolbox si necesitas múltiples bases de datos; elige este si quieres protecciones específicas de BigQuery (límites de escaneo, listas de permitidos) integradas.

¿Puedo añadir herramientas personalizadas? Sí: es un único archivo Python. Añade un nuevo @mcp.tool y aplica el mismo patrón de validación.

¿Es estable el formato de respuesta del esquema? get_table_schema devuelve {"tables": [{dataset, table, partition_field, clustering_fields, schema}, ...]}. La forma es estable en configuraciones de una sola tabla y de múltiples tablas.

¿Soporta SQL heredado bq? No. Solo SQL estándar (GoogleSQL).

🤝 Contribuciones

Se aceptan PRs. Los issues con reproducciones tienen prioridad.

📄 Licencia

MIT. Consulta LICENSE.


Palabras clave: servidor MCP de BigQuery, Model Context Protocol BigQuery, integración de Claude con BigQuery, MCP seguro de BigQuery, MCP de BigQuery autoalojado, servidor MCP en Cloud Run, agente de IA de BigQuery, BigQuery de solo lectura, BigQuery LLM, servidor MCP en Cloud Run, límite de tasa de BigQuery, control de costos de IA de BigQuery.