Platform integration

Agents in production

Google Workspace AI assistant: a practical setup guide for agent access

Build a Google Workspace AI assistant: OAuth setup, scopes, per-user tool access, and the limits of Gemini's native workspace integration explained.

8 minute read
Decorative imagery showcasing Pontil's brand

Google Workspace is one of the most common targets for an AI agent. Email, Calendar, Drive, Docs — most knowledge workers live there, so most agent projects end up wanting to reach it. By the end of this guide you'll have a Google Workspace AI assistant wired up through Google's official APIs, with OAuth running as the authenticated user, scoped access, and a working tool surface your agent can actually call. You'll also see where Gemini's built-in workspace integration stops short, and what that means for anything beyond a chat sidebar.

Prerequisites: a Google Cloud project, a Workspace account with admin rights (or a co-operative admin), and a working agent runtime — Claude, OpenAI, or any framework that can call HTTP tools. Time required: about 90 minutes for a clean setup, longer if your admin's slow on the consent screen.

Step 1 — Decide what "workspace agent access" actually means for you

Before you touch a console, get specific about scope. "Google Workspace AI assistant" covers two very different builds. One is a chat assistant that reads and summarises — Gmail threads, Calendar events, a Drive folder. The other is an agent that acts: drafts replies, schedules meetings, updates Sheets, moves files. The first needs read scopes and a small tool set. The second needs write scopes, careful permissioning, and a much harder conversation about what the agent is allowed to do as the user.

Write down the four or five concrete actions your agent must perform. "Summarise yesterday's unread emails." "Schedule a 30-minute meeting with the next available slot." "Find the latest pricing doc and extract the enterprise tier." Each action maps to one or two API calls. If you can't list the actions, you're not ready to build the assistant — you're still scoping the problem.

This matters because Gemini's native Workspace integration handles the chat-sidebar version well. If that's all you need, you may not need to build anything. The rest of this guide assumes you need an agent that acts, on behalf of a specific user, against APIs you control.

Step 2 — Set up the Google Cloud project and OAuth client

Open the Google Cloud Console and create a new project. Name it something you'll recognise — workspace-agent-dev works.

Enable the APIs your actions need. For most assistants that's:

  • Gmail API
  • Google Calendar API
  • Google Drive API
  • Google Docs API
  • Google Sheets API

Enable only what you'll use. Every extra API expands the consent screen and the audit surface.

Next, configure the OAuth consent screen. For an internal Workspace assistant, set the user type to Internal — this restricts access to your Workspace domain and generally skips Google's verification process. For anything that touches users outside your domain, you'll need External, which means verification and a privacy policy URL. For sensitive scopes, Google's official guidance is 3–5 business days to review, though in practice it often runs longer; restricted scopes (full Gmail or Drive access) additionally require an annual independent security assessment that can take weeks to months.

Create an OAuth 2.0 client ID under Credentials → Create Credentials → OAuth client ID. Pick Web application. Add your redirect URI — http://localhost:8080/oauth/callback for local development, your production callback URL later. Save the client ID and client secret somewhere your agent runtime can read them.

Expected result: a client ID ending in .apps.googleusercontent.com and a client secret. You'll use both in Step 4.

Step 3 — Choose your scopes carefully

Scopes are where most workspace agent projects quietly break. Request too few and your agent can't do its job. Request too many and your consent screen scares users off, or your admin blocks the app entirely.

Map each action from Step 1 to the narrowest scope that works:

Action
Scope

Read Gmail messages

`https://www.googleapis.com/auth/gmail.readonly`

Send Gmail messages

`https://www.googleapis.com/auth/gmail.send`

Read and modify Calendar

`https://www.googleapis.com/auth/calendar`

Read Drive files

`https://www.googleapis.com/auth/drive.readonly`

Read/write specific Drive files the app created

`https://www.googleapis.com/auth/drive.file`

Read and edit Docs

`https://www.googleapis.com/auth/documents`


Prefer drive.file over drive whenever you can — it only grants access to files your app explicitly creates or the user explicitly picks, which keeps the audit story clean.

Add each scope to the OAuth consent screen configuration. Sensitive and restricted scopes (full Gmail or Drive access) require app verification and, for restricted scopes on External apps, an independent security assessment. Internal Workspace apps generally skip both — another reason to start there if you can.

Step 4 — Implement the OAuth flow as the authenticated user

This is the step that separates a Workspace assistant from a Workspace integration. Your agent must execute as the user who authenticated, not as a service account that impersonates everyone. Shared service accounts break audit trails, violate least-privilege, and turn one compromised agent into a domain-wide incident.

Use the standard authorisation-code flow. In Python with the official client:

from google_auth_oauthlib.flow import Flow

flow = Flow.from_client_config(
   client_config=CLIENT_CONFIG,
   scopes=[
       "https://www.googleapis.com/auth/calendar",
       "https://www.googleapis.com/auth/gmail.send",
   ],
   redirect_uri="http://localhost:8080/oauth/callback",
)

auth_url, state = flow.authorization_url(
   access_type="offline",
   prompt="consent",
   include_granted_scopes="true",
)

Send the user to auth_url. When they consent, Google redirects to your callback with a code. Exchange it for tokens, then store the refresh token against the user record — not in a shared cache, not in an env var. The refresh token is per-user and lets you mint access tokens for that user only.

When your agent later makes API calls, it uses that user's access token. Every read, every write, every action sits in Google's audit log under the real user's email. That's the model you want.

Step 5 — Define your tools for the agent runtime

Your agent doesn't call Google's APIs directly. It calls tools you define, which then call the APIs. Each tool needs a name, a description, a JSON schema for arguments, and a handler.

Keep tools narrow. One tool per intent:

{
 "name": "calendar_find_free_slot",
 "description": "Find the next available 30-minute slot in the user's primary calendar within the next 7 days, during working hours.",
 "input_schema": {
   "type": "object",
   "properties": {
     "duration_minutes": {"type": "integer", "default": 30},
     "working_hours_start": {"type": "string", "default": "09:00"},
     "working_hours_end": {"type": "string", "default": "17:00"}
   }
 }
}

A broad tool like calendar_do_anything will be misused by the model. A specific tool with a clear description will not. Write descriptions for the model's benefit — they're the only thing it has to reason about when to invoke.

Register the tools with your agent runtime. For Claude, that's the tools parameter on the messages API. For OpenAI, the tools array on the Responses API. The runtime will call your handler with arguments; your handler hits the Google API with the user's token and returns the result.

For a deeper look at how the tools layer sits relative to the rest of the agent stack, see the agent stack: a map for platform teams.

Step 6 — Test against real Workspace data

Spin up the agent. Authenticate as a test user in your Workspace. Run each action from Step 1 end-to-end.

Things to check:

  • The agent calls the right tool for each intent. If it calls the wrong one, your tool descriptions need work.
  • Each API call appears in Google's Admin audit log under the test user, not under a service account.
  • Tokens refresh correctly when the access token expires (usually after one hour).
  • Errors from the API surface back to the agent as readable strings, not silent failures.

Deliberately break things. Revoke the user's consent and watch the agent fail gracefully. Hit the API rate limit and check your retry logic. Pass malformed input and confirm the handler validates before calling Google.

Common pitfalls

Gemini's native Workspace integration limits. Gemini for Workspace can read and act inside Gmail, Docs, and Drive — for the user, inside Google's UI. Outside that surface, your agent can't reuse it. If you need an agent that lives in your own product and reaches into a customer's Workspace, you're building what this guide describes, not extending Gemini.

Service account shortcuts. Domain-wide delegation lets a service account impersonate any user. It feels like a faster path. It also gives one credential the keys to the whole domain, breaks per-user audit trails, and gets flagged in every serious security review. Use the OAuth flow.

Scope creep on the consent screen. Every scope you add raises the chance the user bails or the admin blocks the app. Start with the minimum and add scopes only when an action genuinely needs them.

Rate limits in production. Gmail allows 250 quota units per user per second. Calendar enforces quotas per minute per project and per minute per user — check the exact default in your Cloud Console Quotas page, since these vary by project. A chatty agent will hit limits fast. Cache aggressively where data isn't time-sensitive, and back off cleanly when you hit a 429.

The 2% problem. Google's APIs are excellent — but they're not the same as Workspace itself. Plenty of UI features (specific admin settings, some Meet controls, parts of Sites) have no API. If your assistant needs those, no amount of OAuth wiring will help. That's the broader pattern this guide sits inside: your APIs expose 2% of what your product can do.

How Pontil fits

This guide assumes Google's APIs cover what you need. For an agent built against Workspace itself, that's usually true — Google has invested heavily in the API surface.

The pattern doesn't hold for most enterprise SaaS. If you're an established SaaS company building an AI assistant on your own platform, your APIs probably don't reach what your UI does. The agent project stalls at access, not at the model. Pontil is a Tools-as-a-Service platform — we generate, run, and maintain the tools agents need against the systems you already own, so your agent can reach the rest of your product without a multi-year API rewrite. If that's the problem you're hitting, book a walk-through.

What to do next

Move the working setup off localhost. Swap the redirect URI for production, store refresh tokens in your real user database, and put the tool handlers behind your own observability. If the assistant is for external users, start the OAuth verification process now — it takes weeks. Then add the next action from Step 1 and repeat.

POSTS

Related content

Agent infrastructure

Platform integration

MCP servers: a practical setup and architecture guide

8 minute read

Platform integration

Agent infrastructure

Claude MCP vs custom tool APIs: which fits your agent project

6 minute read

Agents in production

Platform integration

Platform readiness for AI agents: a checklist

5 minute read