Package: @prmichaelsen/google-calendar-mcp
Version: 2.0.0
A TypeScript-based Model Context Protocol (MCP) server for Google Calendar and Gmail integration using service account authentication with domain-wide delegation.
New in v2.0: Factory pattern support for multi-tenant deployments. Can be used as a standalone server or imported as a library for wrapper projects.
Note: This is a minimal implementation covering the most common use cases. The Google Calendar API has many more features (recurring events, calendar management, ACLs, etc.) that are not implemented here. This server focuses on basic event CRUD operations with reminders and attendee management.
- ✅ Create calendar events with title, description, start/end times, location, and attendees
- ✅ Update existing calendar events
- ✅ List upcoming calendar events
- ✅ Custom event reminders (popup/email at any interval)
- ✅ Service account authentication with domain-wide delegation
- ✅ Automatic email notifications to attendees
- ✅ TypeScript implementation with full type safety
- Node.js v18 or later
- Google Workspace account with admin access (for domain-wide delegation)
- Google Cloud Console project with Calendar API enabled
- Service account with Calendar API access and domain-wide delegation
- Service account JSON key file
- Go to Google Cloud Console
- Create a new project or select existing one
- Enable the Google Calendar API:
- Navigate to "APIs & Services" > "Library"
- Search for "Google Calendar API"
- Click "Enable"
- Go to "APIs & Services" > "Credentials"
- Click "Create Credentials" > "Service Account"
- Fill in service account details:
- Name:
calendar-mcp(or your choice) - ID:
calendar-mcp@your-project.iam.gserviceaccount.com
- Name:
- Click "Create and Continue"
- Grant appropriate roles (optional)
- Click "Done"
- Click on the newly created service account
- Go to the "Keys" tab
- Click "Add Key" > "Create new key"
- Select "JSON" and click "Create"
- Save the downloaded JSON file as
~/calendar-mcp-server/service-account-key.json - Note the
client_idfrom the JSON file - you'll need this for domain-wide delegation
This step is critical for sending calendar invitations to attendees.
-
In Google Admin Console:
- Go to Google Admin Console
- Navigate to: Security → Access and data control → API Controls
- Click Manage Domain Wide Delegation
- Click Add new
-
Configure delegation:
- Client ID: Paste the
client_idfrom your service account JSON key - OAuth Scopes:
https://www.googleapis.com/auth/calendar - Click Authorize
- Client ID: Paste the
-
Verify setup:
- The service account should now appear in the Domain-Wide Delegation list
- Status should show "Authorized"
Without domain-wide delegation: Events can be created but attendee invitations will fail with error:
Service accounts cannot invite attendees without Domain-Wide Delegation of Authority
cd ~/calendar-mcp-server
npm installnpx tscThe server requires three environment variables:
GOOGLE_APPLICATION_CREDENTIALS: Path to your service account JSON key fileGOOGLE_CALENDAR_ID: Calendar ID to use (e.g., email address or "primary")GOOGLE_CALENDAR_SUBJECT: Email address to impersonate for domain-wide delegation
Add to your MCP settings file (.vscode-server/data/User/globalStorage/kilocode.kilo-code/settings/mcp_settings.json):
{
"mcpServers": {
"@prmichaelsen/google-calendar-mcp": {
"command": "node",
"args": ["/path/to/calendar-mcp-server/build/index.js"],
"env": {
"GOOGLE_APPLICATION_CREDENTIALS": "/path/to/calendar-mcp-server/service-account-key.json",
"GOOGLE_CALENDAR_ID": "your-email@your-domain.com",
"GOOGLE_CALENDAR_SUBJECT": "your-email@your-domain.com"
},
"alwaysAllow": [
"create_calendar_event",
"list_calendar_events",
"update_calendar_event",
"send_email",
"list_emails",
"read_email"
]
}
}
}Note: Replace paths and email addresses with your actual values.
Create a new calendar event with optional reminders and attendees.
Parameters:
summary(required): Event titlestart_time(required): Start time in ISO 8601 formatend_time(required): End time in ISO 8601 formatdescription(optional): Event descriptionlocation(optional): Event locationattendees(optional): Array of attendee email addressessend_notifications(optional): Send email notifications (default: true)reminders(optional): Array of reminder objects withmethod("email" or "popup") andminutes
Example:
{
"summary": "Team Meeting",
"description": "Weekly team sync",
"start_time": "2024-12-25T10:00:00-08:00",
"end_time": "2024-12-25T11:00:00-08:00",
"location": "Conference Room A",
"attendees": ["alice@example.com", "bob@example.com"],
"reminders": [
{
"method": "popup",
"minutes": 10
},
{
"method": "email",
"minutes": 1440
}
]
}Common Reminder Times:
- 10 minutes before:
{method: "popup", minutes: 10} - 1 hour before:
{method: "popup", minutes: 60} - 1 day before:
{method: "email", minutes: 1440} - 2 days before:
{method: "email", minutes: 2880} - 1 week before:
{method: "email", minutes: 10080}
List upcoming calendar events with their IDs.
Parameters:
max_results(optional): Maximum number of events to return (default: 10)time_min(optional): Lower bound for event start time in ISO 8601 format (default: now)time_max(optional): Upper bound for event start time in ISO 8601 format
Example:
{
"max_results": 20,
"time_min": "2024-12-01T00:00:00Z",
"time_max": "2024-12-31T23:59:59Z"
}Update an existing calendar event by its ID.
Parameters:
event_id(required): Event ID to updatesummary(optional): New event titledescription(optional): New event descriptionstart_time(optional): New start time in ISO 8601 formatend_time(optional): New end time in ISO 8601 formatlocation(optional): New event locationattendees(optional): New array of attendee email addressessend_notifications(optional): Send update notifications (default: true)reminders(optional): New reminder configuration
Example:
{
"event_id": "abc123xyz",
"summary": "Updated Team Meeting",
"attendees": ["alice@example.com", "charlie@example.com"],
"reminders": [
{
"method": "popup",
"minutes": 30
}
]
}This package can be used as a base for multi-tenant MCP servers:
import { createGoogleCalendarServer } from '@prmichaelsen/google-calendar-mcp/factory';
const server = createGoogleCalendarServer(
'user@workspace.com', // User to impersonate
'user-123', // User ID for tracking
{
serviceAccountKeyPath: '/path/to/key.json',
calendarId: 'primary'
}
);
// Connect to transport (stdio, SSE, etc.)
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const transport = new StdioServerTransport();
await server.connect(transport);interface GoogleCalendarServerOptions {
serviceAccountKeyPath: string; // Required: Path to service account JSON key
calendarId?: string; // Optional: Calendar ID (defaults to "primary")
}For multi-tenant deployments with Platform JWT authentication, see:
The factory pattern enables wrapping this server with @prmichaelsen/mcp-auth for per-user authentication and authorization.
v2.0 Breaking Change: All tools now have a google_ prefix for multi-tenant compatibility:
google_create_calendar_event(wascreate_calendar_event)google_list_calendar_events(waslist_calendar_events)google_update_calendar_event(wasupdate_calendar_event)google_send_email(wassend_email)google_list_emails(waslist_emails)google_read_email(wasread_email)
Note: If you're using the standalone server (not as a library), update your MCP settings to use the new tool names.
# Build
cd ~/calendar-mcp-server
npx tsc
# The compiled server will be at build/index.js- Ensure
GOOGLE_CALENDAR_SUBJECTis set in your MCP settings - This should be the email address you want to impersonate (e.g., your Google Workspace email)
- Follow step 4 above to enable domain-wide delegation in Google Admin Console
- Ensure the OAuth scope
https://www.googleapis.com/auth/calendaris authorized - Verify the service account's
client_idis correctly entered in Admin Console
- The email specified in
GOOGLE_CALENDAR_SUBJECTneeds to visit calendar.google.com once to activate Google Calendar - This is a one-time setup requirement
- Verify domain-wide delegation is properly configured
- Ensure Calendar API is enabled in Google Cloud Console
- Check that the service account has the calendar scope authorized
Domain-Wide Delegation Flow:
- Service account (
calendar-mcp@your-project.iam.gserviceaccount.com) impersonates user - User email specified in
GOOGLE_CALENDAR_SUBJECTenvironment variable - Calendar operations performed as that user
- Attendee invitations sent from that user's calendar
Benefits:
- No OAuth2 browser flow required
- Automated calendar management
- Ability to send attendee invitations
- Suitable for server-side/bot applications
MIT