Skip to content

dleen/google-calendar-mcp-cloudflare

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Google Calendar MCP Server on Cloudflare Workers

A tutorial/proof-of-concept demonstrating how to build an MCP (Model Context Protocol) server that integrates with Google Calendar, featuring enterprise-grade authentication patterns.

What This Demonstrates

This project showcases several advanced integration patterns that are individually documented but rarely shown working together:

1. MCP Server on Cloudflare Workers

Deploy an MCP server as a Cloudflare Worker - lightweight, globally distributed, and serverless.

2. Auth0 Token Vault for Third-Party API Access

Exchange user access tokens for Google Calendar tokens without storing sensitive credentials yourself. Auth0's Token Vault securely manages the Google OAuth tokens.

┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ Claude Code │────▶│   Worker    │────▶│ Auth0 Token │────▶│   Google    │
│ (MCP Client)│     │ (MCP Server)│     │   Vault     │     │  Calendar   │
└─────────────┘     └─────────────┘     └─────────────┘     └─────────────┘
       │                   │                   │
       │   Auth0 JWT       │  Token Exchange   │  Google Token
       └───────────────────┴───────────────────┘

3. CIBA for Sensitive Operations

Client-Initiated Backchannel Authentication (CIBA) for operations that require explicit user approval. When the agent tries to create or delete a calendar event, the user receives a push notification on their phone to approve or deny.

Agent: "Create meeting with Bob tomorrow at 2pm"
         │
         ▼
┌─────────────────────────────────────────────────────┐
│  🔔 Push Notification to User's Phone               │
│                                                     │
│  "Claude wants to create an event:                  │
│   Meeting with Bob - Tomorrow 2:00 PM"              │
│                                                     │
│  [Approve]  [Deny]                                  │
└─────────────────────────────────────────────────────┘
         │
         ▼ (after approval)
    Event Created

4. Dynamic Client Registration (DCR) for Claude Code

Claude Code can automatically register itself as an OAuth client with Auth0, enabling seamless authentication without pre-configuring client credentials.

5. Connect SPA for User Consent

Before the MCP server can access a user's Google Calendar, the user must explicitly consent to linking their Google account. The Connect SPA (Single Page Application, hosted on Cloudflare Pages) is a simple web application that handles this one-time consent flow:

┌─────────────────────────────────────────────────────────────────────────────┐
│                           Connect SPA Flow                                   │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  1. User visits Connect SPA                                                 │
│                    │                                                        │
│                    ▼                                                        │
│  2. User signs in with Auth0 (google-oauth2)                                │
│                    │                                                        │
│                    ▼                                                        │
│  3. User selects permissions:                                               │
│     ┌─────────────────────────────────────────┐                             │
│     │ ☑ Read-only access                      │                             │
│     │   View calendar events and settings     │                             │
│     │                                         │                             │
│     │ ☑ Full access                           │                             │
│     │   Create, edit, and delete events       │                             │
│     └─────────────────────────────────────────┘                             │
│                    │                                                        │
│                    ▼                                                        │
│  4. User clicks "Connect Google Calendar"                                   │
│                    │                                                        │
│                    ▼                                                        │
│  5. Google OAuth consent screen appears                                     │
│                    │                                                        │
│                    ▼                                                        │
│  6. Auth0 stores Google tokens in Token Vault                               │
│     (linked to user's Auth0 identity)                                       │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

This separation is important: the MCP server never sees the Google OAuth flow directly. It only exchanges Auth0 tokens for Google tokens via the Token Vault, which already has the user's consent stored.

Architecture

┌────────────────────────────────────────────────────────────────────────────┐
│                              Auth0 Tenant                                   │
├────────────────────────────────────────────────────────────────────────────┤
│                                                                            │
│  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────────────┐ │
│  │  google-oauth2   │  │    GoogleCal     │  │   Claude Code (DCR)      │ │
│  │  (User Login)    │  │  (Token Vault)   │  │   (Dynamic Client)       │ │
│  └──────────────────┘  └──────────────────┘  └──────────────────────────┘ │
│           │                     │                        │                 │
│           │ authenticates       │ stores Google          │ registers       │
│           │ users               │ tokens                 │ automatically   │
│           ▼                     ▼                        ▼                 │
└────────────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌────────────────────────────────────────────────────────────────────────────┐
│                        Cloudflare Worker (MCP Server)                       │
│                                                                            │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────────────────┐│
│  │  JWT Validation │  │ Token Exchange  │  │    Calendar Tools          ││
│  │  (Auth0 JWKS)   │  │ (Token Vault)   │  │  list/create/update/delete ││
│  └─────────────────┘  └─────────────────┘  └─────────────────────────────┘│
│           │                    │                         │                 │
│           │                    │                         │                 │
│           ▼                    ▼                         ▼                 │
│  ┌─────────────────────────────────────────────────────────────────────┐  │
│  │                    CIBA (for sensitive operations)                   │  │
│  │         create_event, update_event, delete_event require            │  │
│  │                    user approval via push notification              │  │
│  └─────────────────────────────────────────────────────────────────────┘  │
└────────────────────────────────────────────────────────────────────────────┘

Prerequisites

Quick Start

1. Clone and Configure

git clone https://github.com/dleen/google-calendar-mcp-cloudflare.git
cd google-calendar-mcp-cloudflare
cp .env.example .env

Edit .env with your credentials (see comments in file for guidance).

2. Deploy Auth0 Configuration

./auth0/deploy import

This creates:

  • Resource server (API) for the MCP endpoint
  • SPA application for Google account linking
  • Token Vault client for token exchange
  • CIBA client for push notifications
  • Google Calendar OAuth connection

3. Complete Manual Auth0 Setup

See MANUAL_STEPS.md for steps that can't be automated:

  • Enable My Account API for the SPA
  • Configure Guardian for CIBA push notifications

4. Get Auth0 Client Credentials

After the first deploy, copy the generated client IDs and secrets from the Auth0 Dashboard:

  • Google Calendar MCP Token VaultMCP_TOKEN_VAULT_CLIENT_ID/SECRET
  • Google Calendar MCP CIBAMCP_CIBA_CLIENT_ID/SECRET

Add these to your .env file.

5. Deploy the Worker

./worker/deploy all  # Sets secrets and deploys

6. Deploy the Connect SPA

./connect-spa/deploy

7. Link Your Google Account

Visit the Connect SPA URL and:

  1. Sign in with Auth0
  2. Click "Connect Google Calendar"
  3. Authorize the requested permissions

Usage with Claude Code

Once deployed, add the MCP server to Claude Code:

claude mcp add google-calendar https://your-worker.workers.dev/mcp

Claude Code will:

  1. Discover Auth0 via /.well-known/oauth-protected-resource
  2. Register itself via DCR
  3. Authenticate you via Auth0
  4. Make authenticated MCP requests

Example Prompts

"What's on my calendar today?"
"Schedule a meeting with alice@example.com tomorrow at 2pm"
"Delete my 3pm meeting"  # Triggers CIBA approval

Project Structure

.
├── auth0/                    # Auth0 configuration (IaC)
│   ├── clients/              # Application definitions
│   ├── connections/          # Identity providers
│   ├── grants/               # Client grants
│   ├── resource-servers/     # API definitions
│   └── deploy                # Deploy script
├── connect-spa/              # Google account linking web app
│   ├── index.html            # SPA with scope toggles
│   └── deploy                # Deploy script
├── worker/                   # Cloudflare Worker (MCP server)
│   ├── src/
│   │   ├── index.ts          # Entry point, routing
│   │   ├── mcp.ts            # MCP protocol handlers
│   │   ├── calendar.ts       # Google Calendar API client
│   │   └── auth.ts           # Auth0 JWT validation, CIBA, token exchange
│   ├── wrangler.toml         # Worker configuration
│   └── deploy                # Deploy script
├── .env.example              # Environment template
└── MANUAL_STEPS.md           # Non-automatable Auth0 setup

Key Concepts Explained

Token Exchange Flow

When the MCP server needs to call Google Calendar:

  1. Claude Code sends request with Auth0 JWT
  2. Worker validates JWT against Auth0 JWKS
  3. Worker calls Auth0 Token Vault with the JWT
  4. Token Vault returns the user's Google access token
  5. Worker calls Google Calendar API
  6. Results returned to Claude Code

CIBA Flow

For sensitive operations (create/update/delete events):

  1. Agent requests operation
  2. Worker initiates CIBA request to Auth0
  3. Auth0 sends push notification via Guardian
  4. User approves/denies on their phone
  5. Worker polls Auth0 for result
  6. On approval, operation proceeds

Why These Patterns Matter

Pattern Problem Solved
Token Vault Securely access third-party APIs without storing tokens
CIBA Get user approval for sensitive agent actions
DCR Zero-config client setup for MCP clients
Cloudflare Workers Global, serverless, low-latency MCP hosting

References

License

MIT

About

Google Calendar MCP Server for Cloudflare Workers with Auth0 integration

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors