google-advanced-protectionsecurityservice-accountstutorial

Google Advanced Protection and AI Agents: The Calendar Integration Guide

Google Advanced Protection blocks most OAuth apps cold. This guide explains what GAP is, why it breaks calendar integrations, and how to solve it with service accounts.

Sarah Chen
Developer Relations, CalendarMCP ·

If you use Google Advanced Protection and have tried to connect an AI agent to your calendar, you have probably seen this error:

Error 400: policy_enforced Access blocked: This app's request is not allowed for your account. If you think this should work, contact the app developer.

This is not a misconfiguration. It is Google Advanced Protection doing exactly what it is designed to do: blocking OAuth apps that have not been explicitly approved for high-security accounts.

This post explains what GAP is, why it blocks calendar integrations, and how CalendarMCP solves it with service accounts — and how you can connect a GAP-protected calendar alongside other Google accounts under a single CalendarMCP API key, so your agent can read and write across all of them from one connection.

What is Google Advanced Protection?

Google Advanced Protection (GAP) is a high-security mode for Google accounts. It is designed for people who face elevated risk: journalists, activists, executives, politicians, and anyone who is a likely target for targeted account attacks.

When GAP is enabled on your account, Google enforces several restrictions beyond what normal accounts have:

  • Hardware security keys are required for sign-in (like YubiKey or Titan)
  • Only Google-approved apps can access your data via OAuth
  • Third-party email and Drive access is restricted
  • Account recovery options are limited to reduce social engineering risk

The OAuth restriction is the one that matters for calendar integrations.

Why GAP Blocks Calendar MCP Servers

Most calendar MCP tools, including the popular self-hosted options, use standard OAuth 2.0. Your browser redirects to Google, you approve the app, Google issues a refresh token, and the app uses that token to call the Calendar API on your behalf.

With GAP enabled, Google will reject that OAuth flow if the app is not on an approved list. Being "published" on Google's consent screen verification is not enough. GAP requires apps to go through a more restrictive process, and most third-party calendar tools have not done that, and cannot realistically do it.

This means every self-hosted solution (nspady/google-calendar-mcp and similar) is blocked at step one. You cannot get past the authorization screen.

The Solution: Service Accounts

Service accounts are a different authentication mechanism. Instead of asking you to authorize an OAuth app, a service account is a separate Google identity (with its own email address like calendar-agent@your-project.iam.gserviceaccount.com) that you grant calendar access to directly.

This sidesteps GAP entirely. You are not authorizing an app to access your account. You are sharing your calendar with another Google identity, the same way you would share a calendar with a coworker.

GAP has no mechanism to block calendar sharing. It can only block OAuth app authorization.

How CalendarMCP Handles This

CalendarMCP has a service account setup flow specifically for Advanced Protection users. You can use it as your primary account, or — if you also have non-GAP Google accounts you want your agent to reach — as an additional connection under an existing CalendarMCP account. One API key multiplexes all of them. Here is how it works:

  1. You visit the setup page. From a new browser session, go to the CalendarMCP setup flow for service accounts. Or, if you already have a CalendarMCP account, click + Add account on the dashboard and pick Share a calendar with our service account.
  2. You get the service account email. CalendarMCP shows you the service account email address. It looks something like calendarmcp@chromosome-474619.iam.gserviceaccount.com.
  3. You share your calendar. In Google Calendar settings, you share your calendar with that service account email address. Give it "Make changes to events" permission.
  4. You verify and complete setup. Back on the CalendarMCP setup page, enter your calendar ID (your Google email or the calendar ID from Google Calendar settings) and verify the connection. CalendarMCP tests that it can read your calendar.
  5. You get your API key (or attach to an existing one). First-time users get a new cmcp_... API key. If you’re already signed in, the new connection is added to your existing key — nothing to change in your MCP client configuration. Both cases show up on the dashboard under Connected Google accounts with per-calendar Read/Write controls.

Step-by-Step: Sharing Your Calendar

Here is the calendar sharing step in more detail:

  1. Open Google Calendar at calendar.google.com
  2. In the left sidebar, find the calendar you want to share and click the three dots next to it
  3. Click "Settings and sharing"
  4. Scroll to "Share with specific people or groups"
  5. Click "Add people and groups"
  6. Enter the CalendarMCP service account email address
  7. Set the permission to "Make changes to events" (required for create, update, delete tools)
  8. Click Send

Important

Do not share using "Make changes and manage sharing". That grants more access than needed. "Make changes to events" is sufficient.

Limitations of the Service Account Approach

Service accounts work well for most calendar operations, but there are a few things worth knowing:

  • Attendee management is blocked. Creating or updating events with attendees on a service-account-connected calendar is rejected with a clear error. Google does not allow service accounts to dispatch invites on personal calendars, full stop. If you need attendee invites, connect the same Google account via OAuth (if GAP permits it) or leave attendee orchestration to a non-GAP account under the same API key.
  • You must share each calendar explicitly. If you have multiple calendars you want the agent to access, share each one with the service account email, then add each from the dashboard.
  • The calendar ID matters. Use your actual Google email address as the calendar ID, not "primary". Service accounts do not have a "primary" calendar concept tied to your account.

Mixing a GAP Calendar with Your Normal Accounts

If you have a work account that supports OAuth and a personal GAP account, the ideal setup is: sign up for CalendarMCP with OAuth on the work account, then add the GAP calendar as a service-account connection from your dashboard. Both calendars now live under one API key. Your agent can list_events across both in one call, and the per-calendar Read/Write matrix lets you lock the GAP calendar to read-only while keeping the work calendar read+write — all without minting a second key.

Adding to Your Agent

Once you have completed setup and have your API key, the connection is identical to the OAuth flow:

# Claude Code
claude mcp add calendar https://calendarmcp.ai/api/mcp \
  --header "Authorization: Bearer cmcp_your_api_key"

# Test it
claude "What's on my calendar tomorrow?"

The service account approach is the only way to give AI agents reliable Google Calendar access when Advanced Protection is enabled. If you have GAP on and have been stuck on this, the service account setup flow is the path forward.

Ready to get started?

Connect your Google Calendar to Claude and any MCP client in about two minutes.

Connect Google Calendar