Skip to main content
Glama
YDrogen
by YDrogen

@calendar-mcp/server

npm version

A production-grade Google Calendar MCP (Model Context Protocol) server. Exposes Google Calendar as a set of structured tools that any MCP client can use to list, create, update, delete, search, and subscribe to calendar events.


Overview

This server translates Google Calendar API operations into MCP tool calls. It supports full event CRUD, recurring events, free/busy queries, calendar management, and real-time push notifications via Google Calendar webhooks.

Key features

  • 15 MCP tools covering complete calendar operations

  • Multiple transports: stdio for Claude Desktop, HTTP/SSE for remote clients, or both simultaneously

  • OAuth2 authentication with automatic token refresh

  • AES-256-GCM encrypted token storage with automatic key generation

  • Webhook support for push notifications on calendar changes

  • DNS rebinding protection and channel token validation on HTTP transport

  • TypeScript with strict type safety across all tools


Prerequisites

  • Node.js 20+ (required by the engine constraint)

  • Google OAuth2 credentials:

    1. Go to Google Cloud Console

    2. Create a project (or select an existing one)

    3. Enable the Google Calendar API

    4. Go to Credentials > Create Credentials > OAuth 2.0 Client ID

    5. Set the application type to Web application

    6. Add http://localhost:3500/oauth2callback as an authorized redirect URI (or use your configured OAUTH_PORT)

    7. Copy the Client ID and Client Secret


Installation

Global install

npm install -g @calendar-mcp/server

npx (no install)

npx @calendar-mcp/server --transport stdio

Configuration

All configuration is done via environment variables:

Variable

Required

Default

Description

GOOGLE_CLIENT_ID

Yes

Google OAuth2 client ID

GOOGLE_CLIENT_SECRET

Yes

Google OAuth2 client secret

HTTP_PORT

No

3000

HTTP server port for SSE and webhook endpoints

OAUTH_PORT

No

3500

Port for the OAuth2 callback server

CALENDAR_MCP_ENCRYPTION_KEY

No

auto-generated

64-character hex string for AES-256-GCM token encryption

Generating an encryption key

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Store the output in CALENDAR_MCP_ENCRYPTION_KEY. If omitted, a key is generated automatically and stored at ~/.config/calendar-mcp/encryption-key.txt.


Authentication

On first run, the server opens a browser window for Google OAuth2 authorization.

  1. Start the server with your credentials

  2. Visit http://localhost:3500 (or your configured OAUTH_PORT)

  3. Sign in with your Google account and grant calendar access

  4. Tokens are saved locally and refreshed automatically

Tokens are encrypted at rest using AES-256-GCM. The token file is stored at ~/.config/calendar-mcp/tokens.json with 0o600 file permissions.


Available Tools

Tool

Description

Annotations

list_events

List events with optional filtering by time range and max results

Read-only

get_event

Get single event details

Read-only

create_event

Create a new event (supports all-day and timed)

update_event

Partial update of an existing event

delete_event

Delete an event

Destructive

list_event_instances

Expand a recurring event into individual instances

Read-only

create_recurring_event

Create a recurring event with RRULE

query_free_busy

Query availability across up to 50 calendars

Read-only

list_calendars

List all calendars in the user account

Read-only

get_calendar

Get single calendar details

Read-only

subscribe_calendar

Subscribe to push notifications (7-day expiry)

unsubscribe_calendar

Unsubscribe from push notifications

Destructive

list_subscriptions

List active webhook subscriptions

Read-only

search_events

Full-text search events in a calendar

Read-only

get_current_time

Get current server time with timezone context

Read-only


Transport Modes

The server supports three transport modes via the --transport flag.

Stdio (for Claude Desktop, Cursor, and other MCP clients)

calendar-mcp --transport stdio

Add to your MCP client configuration (e.g., Claude Desktop claude_desktop_config.json):

{
  "mcpServers": {
    "calendar": {
      "command": "calendar-mcp",
      "args": ["--transport", "stdio"],
      "env": {
        "GOOGLE_CLIENT_ID": "your-client-id",
        "GOOGLE_CLIENT_SECRET": "your-client-secret"
      }
    }
  }
}

HTTP/SSE (for remote clients and webhook reception)

GOOGLE_CLIENT_ID=xxx GOOGLE_CLIENT_SECRET=yyy calendar-mcp --transport http

Both (default)

calendar-mcp --transport both

CLI options

calendar-mcp --help

Output:

Google Calendar MCP Server

Usage: calendar-mcp [options]

Options:
  --transport <mode>  Transport mode: stdio, http, or both (default: both)
  --help              Show this help message
  --version           Show version number

Environment Variables:
  GOOGLE_CLIENT_ID            Google OAuth2 client ID (required)
  GOOGLE_CLIENT_SECRET        Google OAuth2 client secret (required)
  HTTP_PORT                   HTTP server port (default: 3000)
  OAUTH_PORT                  OAuth callback port (default: 3500)
  CALENDAR_MCP_ENCRYPTION_KEY Encryption key for token storage (optional)

HTTP Endpoints (HTTP mode)

Endpoint

Method

Description

/mcp

GET

SSE stream for MCP connection

/messages

POST

MCP message handler

/webhooks/google-calendar

POST

Google Calendar push notifications

/health

GET

Health check


Docker Deployment

Build and run

docker build -t calendar-mcp .
docker run \
  -e GOOGLE_CLIENT_ID=xxx \
  -e GOOGLE_CLIENT_SECRET=yyy \
  -p 3000:3000 \
  -p 3500:3500 \
  calendar-mcp

Docker Compose

# Set env vars in .env file or export them
export GOOGLE_CLIENT_ID=xxx
export GOOGLE_CLIENT_SECRET=yyy

# Ports are configurable via HTTP_PORT and OAUTH_PORT env vars
docker compose up -d

The compose file mounts ~/.config/calendar-mcp as a volume so tokens persist across container restarts.


Webhook Setup

Google Calendar push notifications let you receive real-time updates when events change.

  1. Ensure the server runs in HTTP or both mode

  2. Use the subscribe_calendar tool to register a webhook

  3. Google sends a sync notification first, then change notifications to /webhooks/google-calendar

  4. Subscriptions expire after 7 days; re-subscribe before expiry

  5. Use list_subscriptions to see active channels and unsubscribe_calendar to remove them

Requirements for public webhooks:

The server must be reachable from the internet. Set the webhook address in your Google Cloud Console OAuth2 credentials to your public URL (e.g., https://your-domain.com/webhooks/google-calendar).


Security

  • AES-256-GCM encrypted token storage with authenticated encryption

  • Token store at ~/.config/calendar-mcp/tokens.json with 0o600 permissions

  • OAuth2 refresh token rotation supported by the Google Auth Library

  • DNS rebinding protection on HTTP transport (only localhost, 127.0.0.1, ::1 allowed as Host header)

  • X-Goog-Channel-Token validation for webhook requests

  • No plaintext token logging anywhere in the application


Development

# Clone the repository
git clone https://github.com/your-org/calendar-mcp.git
cd calendar-mcp

# Install dependencies
npm install

# Run tests (20 test suites)
npm test

# Build the project
npm run build

# Run the dev server with hot reload
npm run dev

# Lint
npm run lint

License

ISC

F
license - not found
-
quality - not tested
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/YDrogen/calendar-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server