·

What Is Google Cloud MCP

Learn what Google Cloud MCP is and how it lets your AI agent manage cloud resources and investigate infrastructure.

Core GCP MCP Tools: Cloud Storage, BigQuery, Cloud Run, and Cloud Logging

Google Cloud doesn't ship a single official first-party MCP server the way some vendors do — what you'll actually deploy is one of a handful of community and Google-maintained implementations (the most active being googleapis/genai-toolbox for BigQuery/AlloyDB/Cloud SQL access, and several gcp-mcp community servers that wrap gcloud and the client libraries directly). In practice, most teams standardize on a server that exposes four surfaces: Cloud Storage (GCS), BigQuery, Cloud Run, and Cloud Logging. That's the working set this module covers, because it maps to the daily loop of a backend or data engineer: store artifacts, query data, deploy services, and read logs when something breaks.

Cloud Storage tools typically expose list_buckets, list_objects, read_object (with a size cap — most servers refuse to stream anything over a few MB inline), get_object_metadata, and sometimes generate_signed_url. This is read-heavy by design. Very few teams grant write/delete scopes to an agent's GCS tools, because a hallucinated gsutil rm -r gs://prod-bucket/** prompt is a real risk, not a theoretical one.

BigQuery is the tool surface with the most depth, and rightly so — it's where cost and correctness both bite. A well-built BigQuery MCP tool set gives you list_datasets, list_tables, get_table_schema, execute_query (usually with a mandatory or default dry_run first pass), and get_query_job_stats. Some servers (Google's own genai-toolbox) let you predefine parameterized queries as named tools — e.g., a get_daily_active_users tool backed by a fixed SQL template with a date parameter — which is a materially safer pattern than letting the model free-write SQL against production datasets.

Cloud Run tools cover the deploy-inspection half of the workflow: list_services, get_service, list_revisions, get_revision_traffic, and get_logs (usually delegating to Cloud Logging's logging.googleapis.com API with a resource filter pinned to run.googleapis.com/Revision). Almost no MCP server exposes deploy or update-traffic as a callable tool — that's deliberate. Inspection is safe to automate; mutating production traffic splits generally isn't, unless you've built and reviewed that guardrail yourself.

Cloud Logging, when it's not bundled into Cloud Run's log tool, exposes query_logs with Cloud Logging's filter syntax (not raw SQL — this trips people up the first time) and list_log_entries with severity and time-range bounds.

Typical GCP MCP tool surface (varies by server implementation):
  gcs.list_buckets(project_id)
  gcs.list_objects(bucket, prefix?)
  gcs.read_object(bucket, path, max_bytes?)
  bigquery.list_datasets(project_id)
  bigquery.get_table_schema(dataset, table)
  bigquery.execute_query(sql, dry_run=true, max_bytes_billed?)
  run.list_services(region)
  run.list_revisions(service_name)
  run.get_logs(service_name, since, severity?)
  logging.query_logs(filter, limit, freshness_window)

Tips
- Before adopting any GCP MCP server, read its source to confirm which tools are read-only vs. mutating — READMEs are frequently aspirational and lag the actual tool list.
- Google's genai-toolbox project is the most actively maintained option as of 2026 and supports BigQuery, AlloyDB, Cloud SQL, and Spanner through one config-driven server — start there before rolling a custom one.
- If a server exposes a raw execute_query without a dry_run default, wrap it yourself before giving it to a coding agent unsupervised.


GCP MCP Authentication: Service Accounts, ADC, and Project Scoping

GCP MCP servers authenticate the same way any other GCP client library does — there's no MCP-specific auth mechanism. That means you have three realistic options: Application Default Credentials (ADC) from a logged-in gcloud session, a service account JSON key file, or Workload Identity Federation if the MCP server itself runs inside GCP (a GKE pod or Cloud Run job). For a developer's laptop running Claude Code or Cursor, you'll use one of the first two.

ADC is the fastest path and the one I'd default to for individual developer use:

gcloud auth application-default login

gcloud config set project my-gcp-project-id

The downside: ADC credentials inherit your personal IAM roles. If you're a Project Owner, so is your AI agent, for every action that server exposes tools for. That's fine for a solo side project, dangerous for anything touching a shared production project.

For team or CI use, a dedicated service account with narrowly scoped roles is the correct pattern:

gcloud iam service-accounts create mcp-agent-readonly \
  --display-name="MCP Agent - Read Only Data Access" \
  --project=my-gcp-project-id

gcloud iam service-accounts keys create ./mcp-agent-key.json \
  --iam-account=mcp-agent-readonly@my-gcp-project-id.iam.gserviceaccount.com

gcloud projects add-iam-policy-binding my-gcp-project-id \
  --member="serviceAccount:mcp-agent-readonly@my-gcp-project-id.iam.gserviceaccount.com" \
  --role="roles/bigquery.dataViewer"

Point the MCP server at the key with the standard environment variable — every Google client library respects this without any server-specific config:

export GOOGLE_APPLICATION_CREDENTIALS="/Users/you/.gcp/mcp-agent-key.json"

Project scoping matters more than people expect. Most GCP MCP servers take a project_id either as a startup argument or as a per-call parameter. If your organization has 40 projects and the server defaults to whatever gcloud config get-value project currently returns, you can end up querying the wrong project's BigQuery datasets silently — the query succeeds, it's just against staging-project instead of analytics-project, and nothing errors out. Pin the project explicitly in the MCP server config rather than relying on ambient gcloud state.

{
  "mcpServers": {
    "gcp": {
      "command": "npx",
      "args": ["-y", "@google-cloud/mcp-toolbox"],
      "env": {
        "GOOGLE_APPLICATION_CREDENTIALS": "/Users/you/.gcp/mcp-agent-key.json",
        "GOOGLE_CLOUD_PROJECT": "analytics-project-prod"
      }
    }
  }
}

Rotate service account keys. A JSON key file with no expiration sitting in ~/.gcp/ is a standing liability — set a 90-day rotation reminder or, better, move to Workload Identity Federation once the workflow stabilizes and you're running the MCP server from a machine GCP can attest.

Tips
- Never commit a service account key to a repo — add *.json key file patterns to .gitignore explicitly, and to .git-secrets or gitleaks config if you run pre-commit scanning.
- Run gcloud auth application-default print-access-token to sanity-check which identity a session is actually using before trusting an MCP tool's output.
- If two team members share a machine, ADC credentials are per-OS-user, not per-project — a stale gcloud auth login under a different account is a common source of "wrong project" confusion.


What AI Can Automate on GCP: Data Queries, Deploy Inspection, and Log Analysis

The honest scope of what an AI coding agent does well with GCP MCP is narrower than the marketing suggests, and that's fine — narrow-but-reliable beats broad-but-flaky. Three categories consistently work well.

Data queries. Ask an agent "what's the schema of the orders table in analytics.raw_events, and give me a query for daily order counts by region for the last 30 days" — it fetches the schema via bigquery.get_table_schema, writes correct SQL against the real column names (not guessed ones), dry-runs it, reports the bytes scanned, and only then offers to execute. This eliminates the single most common BigQuery mistake: writing SQL against a schema you're misremembering from three months ago.

Deploy inspection. "Why did the last deploy of checkout-api fail health checks?" is a genuinely strong use case. The agent lists revisions, diffs the failing one against the last healthy one, pulls the relevant log window via Cloud Logging, and — this is the part that saves real time — correlates a specific log line (e.g., a missing env var causing a startup panic) with the revision's config diff. That's a 20-minute manual investigation compressed into two or three tool calls.

Log analysis. Structured log querying is where MCP genuinely beats a human clicking through the Cloud Logging console. Give it a time window and a severity filter, and it will summarize error clusters, count occurrences, and flag the log entries worth reading in full — instead of you scrolling through 4,000 INFO lines to find the 12 ERROR ones.

Prompt example:
"Query Cloud Logging for ERROR-severity entries from the
checkout-api Cloud Run service in the last 2 hours. Group by
error message pattern and tell me which one is new (not present
in the prior 24 hours)."

What doesn't work well, and where I'd keep a human in the loop: multi-step data pipeline orchestration decisions (should this backfill run now or during the maintenance window?), IAM policy changes (the blast radius of a wrong grant is too high for autonomous execution), and any BigQuery query touching more than a few hundred GB without a human confirming the cost estimate first. The agent can propose all of these; it shouldn't execute the destructive or expensive ones unattended.

Tips
- Frame Cloud Run debugging prompts around a specific revision ID, not just the service name — agents sometimes grab the wrong revision when multiple are serving split traffic.
- For log analysis, always specify a bounded time window in the prompt; an unbounded query_logs call against a busy service can return megabytes of entries and blow your context budget.
- Treat AI-generated BigQuery SQL as a draft for review, not an execute-on-sight artifact, until you've built enough trust in a specific agent/prompt combination on your actual schemas.


IAM Role Design and Billing Guardrails for Agent Access

This is the section that actually prevents the bad outcomes, so treat it as load-bearing, not optional. The default temptation — grant the agent's service account roles/editor or roles/owner "to keep things simple" — is the single most common GCP MCP misconfiguration I see, and it's the one that turns a scoped tool integration into an unbounded blast radius.

Build role grants around the four tool surfaces, not around convenience:

PROJECT_ID="my-gcp-project-id"
SA="mcp-agent-readonly@${PROJECT_ID}.iam.gserviceaccount.com"

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

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SA}" --role="roles/storage.objectViewer"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SA}" --role="roles/run.viewer"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SA}" --role="roles/logging.viewer"

Notice what's absent: bigquery.dataEditor, storage.objectAdmin, run.admin, and anything in the roles/iam.* family. If a future workflow genuinely needs write access — say, an agent that provisions a new BigQuery dataset for a project — grant that as a separate, explicitly-scoped service account used only for that workflow, not a blanket upgrade to the general-purpose one.

Billing guardrails are the second half of the story, because bigquery.jobUser still lets someone run a query that scans your entire 40 TB events table. Two mechanisms compound well together:

  1. Per-user/per-project custom quotas on bigquery.googleapis.com/quota/query/usage, capped daily.
  2. maximumBytesBilled enforced at the query level, which the MCP server should set on every execute_query call, not just recommend.
-- Setting a hard cap on bytes billed for a single query.
-- If the query would scan more than 1 GB, it fails before running
-- instead of silently billing for a full table scan.
SELECT region, COUNT(*) AS orders
FROM `analytics-project.raw_events.orders`
WHERE order_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
GROUP BY region;
bq query --use_legacy_sql=false \
  --maximum_bytes_billed=1000000000 \
  'SELECT region, COUNT(*) AS orders
   FROM `analytics-project.raw_events.orders`
   WHERE order_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
   GROUP BY region'

Set an org-level budget alert as the last line of defense — this catches the scenario no per-query cap does: dozens of small, individually-cheap queries adding up over a runaway agentic loop.

gcloud billing budgets create \
  --billing-account=XXXXXX-XXXXXX-XXXXXX \
  --display-name="MCP Agent BigQuery Spend" \
  --budget-amount=200USD \
  --threshold-rule=percent=0.5 \
  --threshold-rule=percent=0.9 \
  --threshold-rule=percent=1.0

Tips
- Grant bigquery.jobUser at the project level but bigquery.dataViewer at the dataset level where possible — bq datasets update supports per-dataset ACLs that are tighter than project-wide viewer access.
- Set maximum_bytes_billed as a default in the MCP server's own config, not something you rely on the LLM to remember to pass on every call.
- Review the Cloud Audit Logs for the service account monthly (protoPayload.authenticationInfo.principalEmail="mcp-agent-readonly@...") — this is the ground truth for what the agent actually did, independent of what it reported doing.


Tips

Tips
- Start every new GCP MCP integration against a sandbox project with synthetic data, not production — the failure modes (wrong project, oversized scan, wrong bucket) are cheap to survive there and expensive everywhere else.
- Pin exact tool versions in your MCP config (npx -y @package@1.4.2 instead of unpinned @latest) — GCP MCP servers are young enough that breaking changes between minor versions are common.
- Document the service account's granted roles next to the MCP config file itself (a comment or a sibling IAM.md) — six months later nobody remembers why mcp-agent-readonly can also read Cloud Storage.