> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polycore.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Google Cloud

> Read and act on Cloud Run and Cloud Logging through Google's own MCP servers, without handing Polycore a Google credential.

Google Cloud is a **direct integration**: Polycore hosts the connection to
Google's own remote MCP servers, so there is no runner to deploy. An owner or
admin connects it once per project, and everyone in the connection's audience
can ask about services and logs from Slack, the dashboard, an MCP client, or a
page.

Google ships **one MCP server per product**, so each product is its own
connection with its own tools and its own policy. Polycore governs two today:

| Connection | Server | What it reaches |
| - | - | - |
| Cloud Run | `run.googleapis.com/mcp` | Services, revisions, deploys |
| Cloud Logging | `logging.googleapis.com/mcp` | Log entries, buckets, views |

## Polycore holds no Google credential

Every other integration hands Polycore a secret. This one does not.

Instead you create a service account in your own project, grant it the roles
the connection needs, and let Polycore's executor **impersonate** it. Polycore
asks Google for a token that lives ten minutes, uses it for one call, and
stores nothing. The authority is a binding in your IAM policy, not a credential
in Polycore's database.

That has three consequences worth knowing:

* **Nothing expires on you.** There is no token to rotate and no connection
  that dies in an hour, or when an employee leaves.
* **You revoke it, not us.** Removing the token creator binding stops every
  call immediately, without waiting for Polycore to delete anything.
* **Least privilege is yours to set.** The connection reaches exactly what you
  granted that service account, and you can see that in your own IAM.

```mermaid theme={"system"}
flowchart LR
  Caller["Agent, Slack, dashboard, page"]
  CP["Polycore control plane"]
  Executor["Private integration executor"]
  IAM["iamcredentials.googleapis.com"]
  MCP["run.googleapis.com/mcp"]

  Caller --> CP --> Executor
  Executor -- "mint a 10 minute token" --> IAM
  Executor -- "one call, as your account" --> MCP
```

## What it can do

Polycore classifies every tool Google advertises:

**Cloud Run.** `list_services` and `get_service` are reads and run when they
are called. `deploy_service_from_image`, `deploy_service_from_archive`, and
`deploy_service_from_file_contents` are writes, so each one waits for a human
approval before anything reaches production.

**Cloud Logging.** `list_log_entries`, `list_log_names`, `list_buckets`,
`get_bucket`, `list_views`, and `get_view` are all reads.

Anything Google adds that Polycore has not classified is treated as unknown. It
is gated like a write, and it arrives **disabled** so an admin reviews it
before anyone can call it.

<Warning>
  This is shared authority. Everyone in the connection's audience acts through
  the one service account, reaching projects their own Google account may not be
  able to open. Every Google tool takes its target project as an argument, so
  the service account's IAM grants are the resource boundary. Grant them on the
  projects this connection should reach, and no others.
</Warning>

## Connect it

First, enable the products you want to reach through MCP in your Google Cloud
project. See Google's
[enable MCP servers](https://docs.cloud.google.com/mcp/enable-disable-mcp-servers)
guide.

Then, in Polycore, open **Project settings → Integrations**, pick **Google
Cloud Run** or **Google Cloud Logging**, and choose **Connect**. The connect
screen generates the setup for that connection's roles, including Polycore's
executor identity, as either `gcloud` commands or Terraform. Both make the same
grant, so pick whichever matches how you manage the project. The commands look
like this:

```bash theme={"system"}
PROJECT="acme-prod"
SA="polycore@$PROJECT.iam.gserviceaccount.com"

gcloud iam service-accounts create polycore \
  --project="$PROJECT" --display-name="Polycore"

gcloud projects add-iam-policy-binding "$PROJECT" \
  --member="serviceAccount:$SA" --role="roles/mcp.toolUser"

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

# Let Polycore act as this account, and only this account.
gcloud iam service-accounts add-iam-policy-binding "$SA" \
  --project="$PROJECT" \
  --member="serviceAccount:POLYCORE_EXECUTOR" \
  --role="roles/iam.serviceAccountTokenCreator"
```

The Terraform tab is the same grant as resources you paste into whatever
already manages the project, ending in a `polycore_service_account` output.
Optional roles arrive commented out in both tabs, so applying or pasting can
never widen the connection by accident.

`roles/mcp.toolUser` is required for any Google MCP call at all. The product
role decides what the connection can reach: `roles/run.viewer` for reads, or
`roles/run.developer` plus `roles/iam.serviceAccountUser` if you also want the
deploy tools to work. For Cloud Logging, `roles/logging.viewer`.

Paste the service account's email back into Polycore, pick the environment it
belongs to, name its GCP project, and choose a namespace and audience.

Repeat for your other environments from the connection's **Environments**
panel. Each one takes its own service account and project; the tools, their
hazards and their enable flags stay on the connection, so you classify Google's
surface once rather than once per environment.

## Using it

Ask in Slack, or from any front door:

```text theme={"system"}
Which Cloud Run services have failing revisions?
```

Capabilities appear in the catalog under the connection's namespace:

```ts theme={"system"}
await polycore.run("run/list_services", {});
```

The connection supplies the project, so it is not asked for. That matters
beyond convenience: Google marks it required, and a model told an argument is
required will invent a value rather than leave it out.

A Cloud Run region is not part of the connection, because a region belongs to
a service rather than to an environment. Cloud Run's tools take `region: "-"`
to mean every region, which is what the tool description tells a caller, so
listing services finds them wherever they run and each result carries the
region to use for anything more specific.

Where a connection covers more than one environment, its tools take a
`project` argument listing exactly those projects, and it is required. There is
no honest default across dev and prod, and Slack has no environment switcher,
so anything else means guessing: "get me the GCP logs" would answer about one
project while you were asking about another. Say which project you mean and you
get the credential bound to it. Because the list is closed, a project cannot be
invented, and naming one this connection has no credential for is refused
rather than answered from somewhere else.

A connection covering one environment asks for nothing, since there is only one
target the call can mean.

Agent and MCP tool names are `direct__<namespace>__<tool>`. The audit row
records the caller, the connection, the tool, and the service account the call
acted as.

## Limits

* **Two products.** Google publishes MCP servers for around sixty. More arrive
  as they are classified.
* **One credential per environment.** A connection covers every environment of
  a project under one namespace, but each environment needs its own service
  account and GCP project added to it. An environment with none has no tools
  there rather than falling back to another environment's credential.
* **Impersonation, not OAuth.** Connecting as your own Google account is not
  supported, and would inherit your full cloud access if it were.

## Removing it

**Remove connection** stops calls at once and drops the tools from the catalog.
Because Polycore stores no Google credential, there is nothing to rotate
afterwards, but removing the `roles/iam.serviceAccountTokenCreator` binding in
your own project is what makes it permanent. The audit history stays.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.