diff --git a/docs.json b/docs.json index da2e8807..8e7a3b3f 100644 --- a/docs.json +++ b/docs.json @@ -120,6 +120,7 @@ "product/admin/mcp-server/freshdesk", "product/admin/mcp-server/github", "product/admin/mcp-server/gong", + "product/admin/mcp-server/google-cloud-project-setup", "product/admin/mcp-server/google-analytics-admin", "product/admin/mcp-server/google-analytics", "product/admin/mcp-server/google-drive", diff --git a/product/admin/mcp-server/google-analytics-admin.mdx b/product/admin/mcp-server/google-analytics-admin.mdx index 548c3000..54c49e76 100644 --- a/product/admin/mcp-server/google-analytics-admin.mdx +++ b/product/admin/mcp-server/google-analytics-admin.mdx @@ -30,7 +30,7 @@ The credentials you set up below are what C1 uses to call Google Analytics Admin ## Before you begin - AI access management must be enabled for your tenant. See [Enable AI access management](/product/admin/enable-ai-access-management). -- A Google Cloud project where you can enable the Google Analytics Admin API and create credentials. +- A Google Cloud project, set up as described in [Set up a Google Cloud project for MCP servers](/product/admin/mcp-server/google-cloud-project-setup) (enable the Google Analytics Admin API, create OAuth credentials, and grant users the **Service Usage Consumer** role on the quota project). - The right GA4 role for the operations you need. Reads need at least **Viewer**, edits and creates need **Editor** at the property level or **Administrator** at the account level, and managing GA4 user permissions needs **Administrator** at the account level. diff --git a/product/admin/mcp-server/google-analytics.mdx b/product/admin/mcp-server/google-analytics.mdx index b1411a33..a2021f6f 100644 --- a/product/admin/mcp-server/google-analytics.mdx +++ b/product/admin/mcp-server/google-analytics.mdx @@ -30,7 +30,7 @@ The credentials you set up below are what C1 uses to call Google Analytics on yo ## Before you begin - AI access management must be enabled for your tenant. See [Enable AI access management](/product/admin/enable-ai-access-management). -- A Google Cloud project where you can enable the Google Analytics Data API and create credentials. +- A Google Cloud project, set up as described in [Set up a Google Cloud project for MCP servers](/product/admin/mcp-server/google-cloud-project-setup) (enable the Google Analytics Data API, create OAuth credentials, and grant users the **Service Usage Consumer** role on the quota project). - Access to the GA4 properties you want to query. The user or service account must already have at least **Viewer** access on those properties. diff --git a/product/admin/mcp-server/google-cloud-project-setup.mdx b/product/admin/mcp-server/google-cloud-project-setup.mdx new file mode 100644 index 00000000..90bbaa38 --- /dev/null +++ b/product/admin/mcp-server/google-cloud-project-setup.mdx @@ -0,0 +1,426 @@ +--- +title: Set up a Google Cloud project for MCP servers +description: Create and configure the Google Cloud project that every Google MCP server shares — enable APIs, grant users permission to use the project, and create OAuth credentials. +og:title: Set up a Google Cloud project for MCP servers +og:description: Create and configure the Google Cloud project that every Google MCP server shares — enable APIs, grant users permission to use the project, and create OAuth credentials. +sidebarTitle: Google Cloud project setup +--- + +{/* Editor Refresh: 2026-07-16 */} + +Set up one Google Cloud project and reuse it for every Google MCP server — Google Drive, Docs, Sheets, Slides, Gmail, Calendar, and the rest. Each Google server connects through a **Google Cloud project** that you own, and a single project can back all of them. + +## Before you begin + +- AI access management must be enabled for your tenant. See [Enable AI access management](/product/admin/enable-ai-access-management). +- Access to the [Google Cloud console](https://console.cloud.google.com/) with permission to create or select a project, enable APIs, and edit IAM — a project **Owner**, or **Editor** plus a role that grants IAM admin. +- A **Google Workspace administrator** for the steps that allow the OAuth client or configure domain-wide delegation. + +## What the project provides + +When a user's AI client calls a Google tool, C1 makes the matching request to the Google API. Your Google Cloud project supplies three things that request depends on: + +| What | Why it matters | +| :--- | :--- | +| **Enabled APIs** | Each connector calls a specific Google API (for example, the Gmail API). That API must be enabled in your project. | +| **OAuth client** | The client ID and secret C1 uses to let each user authorize with their own Google account. | +| **Quota project** | The project that Google attributes each request's quota and billing to. You enter this as the **Google Cloud Quota Project ID** when you register the server, and every caller must be allowed to use it. | + +The third item is the one most often missed — see [Grant users permission to use the project](#grant-users-permission-to-use-the-project). Skipping it is the most common cause of a failed Google connection. + +## Create or select a project + +Pick the project that will own your OAuth credentials and receive API quota. It can be a new project or an existing one. + + + +Sign in to the [Google Cloud console](https://console.cloud.google.com/). + + +Create a new project for C1, or select an existing one. Note its **Project ID** (for example, `acme-c1-mcp`) — you'll enter this exact value when you register each Google server. + + +The Workspace APIs in this guide don't require a billing account. If you plan to use a billing-gated Google API or need higher quota limits, link a billing account to the project. + + + +## Enable the APIs for your connectors + +Enable one API per Google connector you plan to use. In the console, go to **APIs & Services** > **Library**, search for the API by name, and select **Enable**. The service ID is the identifier you use with the `gcloud` CLI. + +| Connector | API to enable | Service ID | +| :--- | :--- | :--- | +| Google Drive | Google Drive API | `drive.googleapis.com` | +| Google Docs | Google Docs API | `docs.googleapis.com` | +| Google Sheets | Google Sheets API | `sheets.googleapis.com` | +| Google Slides | Google Slides API | `slides.googleapis.com` | +| Gmail | Gmail API | `gmail.googleapis.com` | +| Google Calendar | Google Calendar API | `calendar-json.googleapis.com` | +| Google Contacts | People API | `people.googleapis.com` | +| Google Tasks | Google Tasks API | `tasks.googleapis.com` | +| Google Chat | Google Chat API | `chat.googleapis.com` | +| Google Meet | Google Meet API | `meet.googleapis.com` | +| Google Forms | Google Forms API | `forms.googleapis.com` | +| Drive Activity | Drive Activity API | `driveactivity.googleapis.com` | +| Google Analytics | Google Analytics Data API | `analyticsdata.googleapis.com` | +| Google Analytics Admin | Google Analytics Admin API | `analyticsadmin.googleapis.com` | + + +Enable only the APIs for the connectors you actually register. If a connector's API isn't enabled, its tool calls fail with a `SERVICE_DISABLED` error telling you to enable that API in the project. + + +To enable the APIs from the command line instead, pass the service IDs to `gcloud`. This example enables the full set — drop any you don't need: + +```bash +gcloud services enable \ + drive.googleapis.com \ + docs.googleapis.com \ + sheets.googleapis.com \ + slides.googleapis.com \ + gmail.googleapis.com \ + calendar-json.googleapis.com \ + people.googleapis.com \ + tasks.googleapis.com \ + chat.googleapis.com \ + meet.googleapis.com \ + forms.googleapis.com \ + driveactivity.googleapis.com \ + analyticsdata.googleapis.com \ + analyticsadmin.googleapis.com \ + --project=YOUR_PROJECT_ID +``` + +To confirm which APIs are enabled on the project: + +```bash +gcloud services list --enabled --project=YOUR_PROJECT_ID +``` + +## Grant users permission to use the project + +When you register a Google server with **per-user OAuth**, each person authenticates as themselves — so *each user* is the caller Google checks. Because you set a **Quota Project ID**, every request carries that project as its quota project, and Google requires the caller to hold the `serviceusage.services.use` permission on it. + +If a user doesn't have it, their tool calls fail with: + +```text +PERMISSION_DENIED: Caller does not have required permission to use project +. Grant the caller the roles/serviceusage.serviceUsageConsumer +role, or a custom role with the serviceusage.services.use permission ... +``` + +The `serviceusage.services.use` permission comes with the **Service Usage Consumer** role (`roles/serviceusage.serviceUsageConsumer`). It only allows using APIs already enabled in the project and attributing quota to it — it grants **no access to any data** in the project. + +Because every user needs this, grant it to a **Google group** that contains all of your MCP users rather than to individuals. New users then inherit access automatically when they join the group. + + + +Create (or choose) a Google group that contains everyone who will use your Google MCP servers — for example, an all-employees group. + + +In the Google Cloud console, go to **IAM & Admin** > **IAM**, select **Grant access**, enter the group's email as the principal, and assign the **Service Usage Consumer** role. See Google's [Grant a role](https://cloud.google.com/iam/docs/grant-role-console) documentation. + + + +If you prefer the command line: + +```bash +gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \ + --member="group:your-mcp-users-group@yourdomain.com" \ + --role="roles/serviceusage.serviceUsageConsumer" +``` + + +IAM changes usually take effect within a minute but can take a few. If a user still sees `PERMISSION_DENIED` right after you grant access, have them retry shortly and reconnect their Google account so C1 mints a fresh token. + + +For the service-account option (see [Use a service account instead](#optional-use-a-service-account-instead)), the caller is the service account rather than each user — grant the Service Usage Consumer role to the service account instead of a user group. + +## Create an OAuth client + +Per-user OAuth needs one OAuth client in your project. Its client ID and secret let each user authorize C1 with their own Google account. + +### Configure the OAuth consent screen + +The consent screen defines who can authorize the app and which scopes they grant. + + + +Go to **APIs & Services** > **OAuth consent screen** (labeled **Google Auth Platform** on newer projects). + + +Choose the audience: +- **Internal** — only accounts in your Google Workspace organization. Recommended when all your users are in one Workspace, because it avoids Google's app-verification review. +- **External** — any Google account. Broad Google Workspace scopes are **restricted** and require Google verification before an External app can be used outside your organization. + + +Add the scopes your connectors need — see [OAuth scopes by connector](#oauth-scopes-by-connector) for the full list per connector. Request only the scopes you need; for read-only use, prefer the narrower `.readonly` scopes. See Google's [Configure the OAuth consent screen](https://developers.google.com/workspace/guides/configure-oauth-consent) documentation. + + + + +For an **External** app that hasn't completed Google verification, add each person as a **test user** on the consent screen. Otherwise they hit a "Google hasn't verified this app" screen and can't authorize. Publishing and verifying the app removes that limit. + + +### Create the client credentials + +Create the OAuth client, then capture its ID and secret. + + + +Go to **APIs & Services** > **Credentials** > **Create Client** > **Web application**. For details, see Google's [Manage OAuth Clients](https://support.google.com/cloud/answer/15549257) documentation. + + +Under **Authorized redirect URIs**, add exactly: + +```text +https://accounts.conductor.one/auth/callback +``` + +The value must match exactly — even a trailing-slash difference fails the authorization flow. + + +Select **Create**, then copy the **Client ID** and **Client secret**. Google shows the client secret only once. + + + +If your users are on Google Workspace, an administrator may also need to allow the OAuth client under **Admin Console** > **Security** > **Access and data control** > **API controls** > **App access control**. + +## OAuth scopes by connector + +Add the scopes for each connector you use — to the consent screen for per-user OAuth, or to domain-wide delegation for a service account. Each list below is the full set that connector's tools can use. Grant only what your deployment needs, and prefer the `.readonly` scopes for read-only use. + + + +```text expandable +https://www.googleapis.com/auth/drive +https://www.googleapis.com/auth/drive.appdata +https://www.googleapis.com/auth/drive.apps.readonly +https://www.googleapis.com/auth/drive.file +https://www.googleapis.com/auth/drive.meet.readonly +https://www.googleapis.com/auth/drive.metadata +https://www.googleapis.com/auth/drive.metadata.readonly +https://www.googleapis.com/auth/drive.readonly +https://www.googleapis.com/auth/drive.scripts +``` + + +```text +https://www.googleapis.com/auth/documents +https://www.googleapis.com/auth/documents.readonly +https://www.googleapis.com/auth/drive +https://www.googleapis.com/auth/drive.file +https://www.googleapis.com/auth/drive.readonly +``` + + +```text +https://www.googleapis.com/auth/drive +https://www.googleapis.com/auth/drive.file +https://www.googleapis.com/auth/drive.readonly +https://www.googleapis.com/auth/spreadsheets +https://www.googleapis.com/auth/spreadsheets.readonly +``` + + +```text +https://www.googleapis.com/auth/drive +https://www.googleapis.com/auth/drive.file +https://www.googleapis.com/auth/drive.readonly +https://www.googleapis.com/auth/presentations +https://www.googleapis.com/auth/presentations.readonly +https://www.googleapis.com/auth/spreadsheets +https://www.googleapis.com/auth/spreadsheets.readonly +``` + + +```text expandable +https://mail.google.com/ +https://www.googleapis.com/auth/gmail.addons.current.action.compose +https://www.googleapis.com/auth/gmail.addons.current.message.action +https://www.googleapis.com/auth/gmail.addons.current.message.metadata +https://www.googleapis.com/auth/gmail.addons.current.message.readonly +https://www.googleapis.com/auth/gmail.compose +https://www.googleapis.com/auth/gmail.insert +https://www.googleapis.com/auth/gmail.labels +https://www.googleapis.com/auth/gmail.metadata +https://www.googleapis.com/auth/gmail.modify +https://www.googleapis.com/auth/gmail.readonly +https://www.googleapis.com/auth/gmail.send +https://www.googleapis.com/auth/gmail.settings.basic +https://www.googleapis.com/auth/gmail.settings.sharing +``` + + +```text expandable +https://www.googleapis.com/auth/calendar +https://www.googleapis.com/auth/calendar.acls +https://www.googleapis.com/auth/calendar.acls.readonly +https://www.googleapis.com/auth/calendar.app.created +https://www.googleapis.com/auth/calendar.calendarlist +https://www.googleapis.com/auth/calendar.calendarlist.readonly +https://www.googleapis.com/auth/calendar.calendars +https://www.googleapis.com/auth/calendar.calendars.readonly +https://www.googleapis.com/auth/calendar.events +https://www.googleapis.com/auth/calendar.events.freebusy +https://www.googleapis.com/auth/calendar.events.owned +https://www.googleapis.com/auth/calendar.events.owned.readonly +https://www.googleapis.com/auth/calendar.events.public.readonly +https://www.googleapis.com/auth/calendar.events.readonly +https://www.googleapis.com/auth/calendar.freebusy +https://www.googleapis.com/auth/calendar.readonly +https://www.googleapis.com/auth/calendar.settings.readonly +``` + + +```text expandable +https://www.googleapis.com/auth/contacts +https://www.googleapis.com/auth/contacts.other.readonly +https://www.googleapis.com/auth/contacts.readonly +https://www.googleapis.com/auth/directory.readonly +https://www.googleapis.com/auth/user.addresses.read +https://www.googleapis.com/auth/user.birthday.read +https://www.googleapis.com/auth/user.emails.read +https://www.googleapis.com/auth/user.gender.read +https://www.googleapis.com/auth/user.organization.read +https://www.googleapis.com/auth/user.phonenumbers.read +https://www.googleapis.com/auth/userinfo.email +https://www.googleapis.com/auth/userinfo.profile +``` + + +```text +https://www.googleapis.com/auth/tasks +https://www.googleapis.com/auth/tasks.readonly +``` + + +```text +https://www.googleapis.com/auth/drive +https://www.googleapis.com/auth/drive.file +https://www.googleapis.com/auth/drive.readonly +https://www.googleapis.com/auth/forms.body +https://www.googleapis.com/auth/forms.body.readonly +https://www.googleapis.com/auth/forms.responses.readonly +``` + + +```text +https://www.googleapis.com/auth/drive.activity +https://www.googleapis.com/auth/drive.activity.readonly +``` + + +```text +https://www.googleapis.com/auth/meetings.space.created +https://www.googleapis.com/auth/meetings.space.readonly +https://www.googleapis.com/auth/meetings.space.settings +``` + + +```text expandable +https://www.googleapis.com/auth/chat.admin.delete +https://www.googleapis.com/auth/chat.admin.memberships +https://www.googleapis.com/auth/chat.admin.memberships.readonly +https://www.googleapis.com/auth/chat.admin.spaces +https://www.googleapis.com/auth/chat.admin.spaces.readonly +https://www.googleapis.com/auth/chat.app.delete +https://www.googleapis.com/auth/chat.app.memberships +https://www.googleapis.com/auth/chat.app.memberships.readonly +https://www.googleapis.com/auth/chat.app.messages.readonly +https://www.googleapis.com/auth/chat.app.spaces +https://www.googleapis.com/auth/chat.app.spaces.create +https://www.googleapis.com/auth/chat.app.spaces.readonly +https://www.googleapis.com/auth/chat.bot +https://www.googleapis.com/auth/chat.customemojis +https://www.googleapis.com/auth/chat.customemojis.readonly +https://www.googleapis.com/auth/chat.delete +https://www.googleapis.com/auth/chat.import +https://www.googleapis.com/auth/chat.memberships +https://www.googleapis.com/auth/chat.memberships.app +https://www.googleapis.com/auth/chat.memberships.readonly +https://www.googleapis.com/auth/chat.messages +https://www.googleapis.com/auth/chat.messages.create +https://www.googleapis.com/auth/chat.messages.reactions +https://www.googleapis.com/auth/chat.messages.reactions.create +https://www.googleapis.com/auth/chat.messages.reactions.readonly +https://www.googleapis.com/auth/chat.messages.readonly +https://www.googleapis.com/auth/chat.spaces +https://www.googleapis.com/auth/chat.spaces.create +https://www.googleapis.com/auth/chat.spaces.readonly +https://www.googleapis.com/auth/chat.users.availability +https://www.googleapis.com/auth/chat.users.availability.readonly +https://www.googleapis.com/auth/chat.users.readstate +https://www.googleapis.com/auth/chat.users.readstate.readonly +https://www.googleapis.com/auth/chat.users.sections +https://www.googleapis.com/auth/chat.users.sections.readonly +https://www.googleapis.com/auth/chat.users.spacesettings +``` + + +```text +https://www.googleapis.com/auth/analytics +https://www.googleapis.com/auth/analytics.readonly +``` + + +```text +https://www.googleapis.com/auth/analytics.edit +https://www.googleapis.com/auth/analytics.readonly +``` + + + + +Broad Google Workspace scopes are **restricted** or **sensitive** and require Google verification before an **External** app can use them outside your organization. **Internal** (Workspace-only) apps skip that review. See Google's [OAuth API verification FAQs](https://support.google.com/cloud/answer/9110914). If you add scopes after users have connected, they must reconnect their Google account to grant the new scopes. + + +## Optional: Use a service account instead + +Instead of per-user OAuth, a Google Workspace tenant can authenticate everyone through a single **service account** with domain-wide delegation. All tool calls then reach Google as one shared identity. + + + +In the Google Cloud console, go to **APIs & Services** > **Credentials** > **Create credentials** > **Service account**, create the account, and generate a JSON key. See Google's [Create service accounts](https://docs.cloud.google.com/iam/docs/service-accounts-create) documentation. + + +Note the service account's numeric **Unique ID**. + + +As a Workspace administrator, go to **Admin Console** > **Security** > **Access and data control** > **API controls** > **Domain-wide delegation**, select **Add new**, and enter the Unique ID along with the scopes your connectors need. + + +Grant the service account the **Service Usage Consumer** role on your project (see [Grant users permission to use the project](#grant-users-permission-to-use-the-project)) so its requests can use the quota project. + + + +## Register your Google servers + +With the project ready, register each Google MCP server. During [authentication setup](/product/admin/mcp-servers#configure-authentication), you provide: + +- The **Google Cloud Quota Project ID** — the Project ID from [Create or select a project](#create-or-select-a-project). +- For per-user OAuth: the **client ID**, **client secret**, and the **scopes** you configured. +- For a service account: the **JSON key** and the scopes you delegated. + +Then follow the connector-specific page for anything unique to that server: + +- [Google Drive](/product/admin/mcp-server/google-drive) +- [Google Analytics](/product/admin/mcp-server/google-analytics) +- [Google Analytics Admin](/product/admin/mcp-server/google-analytics-admin) + + +Connectors without a dedicated page above use the same [Register an MCP server](/product/admin/mcp-servers#register-an-mcp-server) flow. If a Google connector you want isn't in your catalog yet, [contact the C1 support team](mailto:support@c1.ai). + + +## Troubleshoot Google Cloud project errors + +| Symptom | Cause | Fix | +| :--- | :--- | :--- | +| `PERMISSION_DENIED: Caller does not have required permission to use project ...` | The caller lacks `serviceusage.services.use` on the quota project. | Grant the **Service Usage Consumer** role — see [Grant users permission to use the project](#grant-users-permission-to-use-the-project). | +| `SERVICE_DISABLED` / "API has not been used in project ... before or it is disabled" | The connector's API isn't enabled in the quota project. | Enable it — see [Enable the APIs for your connectors](#enable-the-apis-for-your-connectors). | +| Authorization flow fails after the user consents | The redirect URI doesn't match. | Set it to exactly `https://accounts.conductor.one/auth/callback` — see [Create the client credentials](#create-the-client-credentials). | +| A restricted-scope warning blocks External users | The app needs Google verification for restricted scopes. | Use an **Internal** consent screen for Workspace-only use, or complete Google's verification for External use. | +| "Google hasn't verified this app" blocks sign-in | The External app isn't verified and the user isn't a test user. | Add the user as a **test user** on the consent screen, or complete Google's verification. | + + +Tool discovery runs even before authentication works, so seeing discovered tools doesn't confirm your credentials are correct. You confirm the setup only when an approved user successfully calls a Google tool from their AI client. + diff --git a/product/admin/mcp-server/google-drive.mdx b/product/admin/mcp-server/google-drive.mdx index 6baad64f..58e79d4b 100644 --- a/product/admin/mcp-server/google-drive.mdx +++ b/product/admin/mcp-server/google-drive.mdx @@ -30,7 +30,7 @@ The credentials you set up below are what C1 uses to call Google Drive on your u ## Before you begin - AI access management must be enabled for your tenant. See [Enable AI access management](/product/admin/enable-ai-access-management). -- A Google Cloud project where you can enable the Google Drive API and create credentials. +- A Google Cloud project, set up as described in [Set up a Google Cloud project for MCP servers](/product/admin/mcp-server/google-cloud-project-setup). That guide covers enabling the Google Drive API, creating OAuth credentials, and granting your users the **Service Usage Consumer** role on the quota project so their tool calls aren't rejected with `PERMISSION_DENIED`. - For the service-account option, a Google Workspace administrator to set up [domain-wide delegation](https://knowledge.workspace.google.com/admin/apps/control-api-access-with-domain-wide-delegation). @@ -77,7 +77,7 @@ With your OAuth client ready, register the server and provide its credentials. Follow [Register an MCP server](/product/admin/mcp-servers#register-an-mcp-server) and select **Google Drive** from the catalog. -When you [configure authentication](/product/admin/mcp-servers#configure-authentication), choose per-user OAuth and enter your OAuth client's **client ID** and **client secret**, plus the scopes you configured. +When you [configure authentication](/product/admin/mcp-servers#configure-authentication), choose per-user OAuth and enter your OAuth client's **client ID** and **client secret**, plus the scopes you configured. Also enter the **Google Cloud Quota Project ID** — the ID of the project where you enabled the Google Drive API and granted users the Service Usage Consumer role. Save your changes. The first time a user calls a Google Drive tool from their AI client, they're prompted to connect their Google account.